diff options
author | Sage Weil <sage@inktank.com> | 2013-02-17 22:35:50 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-25 15:29:31 -0800 |
commit | 79d68ae8581141c3fb4cfafd76d5111ff009b762 (patch) | |
tree | 71f69cd46d614a23843052a6f4b4807e529798ec | |
parent | 79c4e7e91becc497843d96251776bdc176706aa0 (diff) | |
download | ceph-79d68ae8581141c3fb4cfafd76d5111ff009b762.tar.gz |
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 <sage@inktank.com>
Reviewed-by: Samuel Just <sam.just@inktank.com>
(cherry picked from commit 56c5a07708d52de1699585c9560cff8b4e993d0a)
-rw-r--r-- | src/osd/OSD.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/osd/OSD.h b/src/osd/OSD.h index c3bc0b96839..3a4e5117af5 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<OpRequestRef>& 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<pg_t, list<OpRequestRef> >::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(); } |