]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: requeue PG when we skip handling a peering event
authorSage Weil <sage@redhat.com>
Thu, 8 Jan 2015 21:34:52 +0000 (13:34 -0800)
committerSage Weil <sage@redhat.com>
Fri, 9 Jan 2015 00:14:56 +0000 (16:14 -0800)
If we don't handle the event, we need to put the PG back into the peering
queue or else the event won't get processed until the next event is
queued, at which point we'll be processing events with a delay.

The queue_null is not necessary (and is a waste of effort) because the
event is still in pg->peering_queue and the PG is queued.

Note that this only triggers when we exceeed osd_map_max_advance, usually
when there is a lot of peering and recovery activity going on.  A
workaround is to increase that value, but if you exceed osd_map_cache_size
you expose yourself to crache thrashing by the peering work queue, which
can cause serious problems with heavily degraded clusters and bit lots of
people on dumpling.

Backport: giant, firefly
Fixes: #10431
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/OSD.cc

index bda3622e8c56099162256fb7ca9ba92d079060f5..7c45ae80d0e56e34757dd65068fbe9c5179822f3 100644 (file)
@@ -8372,7 +8372,9 @@ void OSD::process_peering_events(
       continue;
     }
     if (!advance_pg(curmap->get_epoch(), pg, handle, &rctx, &split_pgs)) {
-      pg->queue_null(curmap->get_epoch(), curmap->get_epoch());
+      // we need to requeue the PG explicitly since we didn't actually
+      // handle an event
+      peering_wq.queue(pg);
     } else if (!pg->peering_queue.empty()) {
       PG::CephPeeringEvtRef evt = pg->peering_queue.front();
       pg->peering_queue.pop_front();