From: Sage Weil Date: Mon, 18 Feb 2013 06:35:50 +0000 (-0800) Subject: osd: requeue pg waiters at the front of the finished queue X-Git-Tag: v0.56.4~56 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=79d68ae8581141c3fb4cfafd76d5111ff009b762;p=ceph.git osd: requeue pg waiters at the front of the finished queue We could have a sequence like: - op1 - notify - op2 in the finished queue. Op1 gets put on waiting_for_pg, the notify creates the pg and requeues op1 (and the end), op2 is handled, and finally op1 is handled. That breaks ordering; see #2947. Instead, when we wake up a pg, queue the waiting messages at the front of the dispatch queue. Signed-off-by: Sage Weil Reviewed-by: Samuel Just (cherry picked from commit 56c5a07708d52de1699585c9560cff8b4e993d0a) --- diff --git a/src/osd/OSD.h b/src/osd/OSD.h index c3bc0b96839e..3a4e5117af55 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -617,6 +617,11 @@ private: finished.splice(finished.end(), ls); finished_lock.Unlock(); } + void take_waiters_front(list& ls) { + finished_lock.Lock(); + finished.splice(finished.begin(), ls); + finished_lock.Unlock(); + } void take_waiter(OpRequestRef op) { finished_lock.Lock(); finished.push_back(op); @@ -880,7 +885,7 @@ protected: void wake_pg_waiters(pg_t pgid) { if (waiting_for_pg.count(pgid)) { - take_waiters(waiting_for_pg[pgid]); + take_waiters_front(waiting_for_pg[pgid]); waiting_for_pg.erase(pgid); } } @@ -888,7 +893,7 @@ protected: for (map >::iterator p = waiting_for_pg.begin(); p != waiting_for_pg.end(); p++) - take_waiters(p->second); + take_waiters_front(p->second); waiting_for_pg.clear(); }