summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-02-17 22:35:50 -0800
committerSage Weil <sage@inktank.com>2013-02-25 15:29:31 -0800
commit79d68ae8581141c3fb4cfafd76d5111ff009b762 (patch)
tree71f69cd46d614a23843052a6f4b4807e529798ec
parent79c4e7e91becc497843d96251776bdc176706aa0 (diff)
downloadceph-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.h9
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();
}