summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-11-10 18:03:37 +0100
committerSage Weil <sage@newdream.net>2010-11-10 18:03:37 +0100
commit586c9e7a80b425802ca77d8c09bb00da5c25d616 (patch)
treea8449075369d6fae32885e435325945ca3d47bbb
parentmon: drop unnecessary state checks (diff)
downloadceph-586c9e7a80b425802ca77d8c09bb00da5c25d616.tar.xz
ceph-586c9e7a80b425802ca77d8c09bb00da5c25d616.zip
objecter: throttle before looking at lock protected state
The take_op_budget() may drop our lock if we are in keep_balanced_budget mode, so we need to do that _before_ we take references to internal state that may change out from under us during that time. This fixes a crash like ./osd/OSDMap.h: In function 'entity_inst_t OSDMap::get_inst(int)': ./osd/OSDMap.h:460: FAILED assert(exists(osd) && is_up(osd)) ceph version 0.22.1 (commit:c6f403a6f441184956e00659ce713eaee7014279) 1: (Objecter::op_submit(Objecter::Op*)+0x6c2) [0x38658854c2] 2: /usr/lib64/librados.so.1() [0x3865855dc9] 3: (RadosClient::aio_write(RadosClient::PoolCtx&, object_t, long, ceph::buffer::list const&, unsigned long, RadosClient::AioCompletion*)+0x24b) [0x386585724b] 4: (rados_aio_write()+0x9a) [0x386585741a] 5: /usr/bin/qemu-kvm() [0x45a305] 6: /usr/bin/qemu-kvm() [0x45a430] 7: /usr/bin/qemu-kvm() [0x43bb73] NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this. ./osd/OSDMap.h: In function 'entity_inst_t OSDMap::get_inst(int)': ./osd/OSDMap.h:460: FAILED assert(exists(osd) && is_up(osd)) ceph version 0.22.1 (commit:c6f403a6f441184956e00659ce713eaee7014279) 1: (Objecter::op_submit(Objecter::Op*)+0x6c2) [0x38658854c2] 2: /usr/lib64/librados.so.1() [0x3865855dc9] 3: (RadosClient::aio_write(RadosClient::PoolCtx&, object_t, long, ceph::buffer::list const&, unsigned long, RadosClient::AioCompletion*)+0x24b) [0x386585724b] 4: (rados_aio_write()+0x9a) [0x386585741a] 5: /usr/bin/qemu-kvm() [0x45a305] 6: /usr/bin/qemu-kvm() [0x45a430] 7: /usr/bin/qemu-kvm() [0x43bb73] NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this. terminate called after throwing an instance of 'ceph::FailedAssertion' *** Caught signal (ABRT) *** ceph version 0.22.1 (commit:c6f403a6f441184956e00659ce713eaee7014279) 1: (sigabrt_handler(int)+0x91) [0x3865922b91] 2: /lib64/libc.so.6() [0x3c0c032a30] 3: (gsignal()+0x35) [0x3c0c0329b5] 4: (abort()+0x175) [0x3c0c034195] 5: (__gnu_cxx::__verbose_terminate_handler()+0x12d) [0x3c110beaad] Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--src/osdc/Objecter.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index 0fe4d65019b..4c17812bf38 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -411,6 +411,10 @@ void Objecter::resend_mon_ops()
tid_t Objecter::op_submit(Op *op)
{
+ // throttle. before we look at any state, because
+ // take_op_budget() may drop our lock while it blocks.
+ take_op_budget(op);
+
if (op->oid.name.length())
op->pgid = osdmap->object_locator_to_pg(op->oid, op->oloc);
@@ -436,7 +440,6 @@ tid_t Objecter::op_submit(Op *op)
} else {
dout(20) << " note: not requesting commit" << dendl;
}
- take_op_budget(op);
op_osd[op->tid] = op;
pg.active_tids.insert(op->tid);
pg.last = g_clock.now();