From: Sage Weil Date: Mon, 30 Apr 2018 14:52:38 +0000 (-0500) Subject: osdc/Objecter: fix recursive locking in _finish_command X-Git-Tag: v12.2.6~110^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f356ee748a37e1357dc2ab5caa0c2f9a940a118e;p=ceph.git osdc/Objecter: fix recursive locking in _finish_command The path #9 Objecter::_finish_command (this=this@entry=0x7f76c00aeb30, c=c@entry=0x7f76b0000b10, r=, rs="osd down") at /build/ceph-13.0.2-1932-g458b4fb/src/osdc/Objecter.cc:4950 #10 0x00007f76d26de106 in Objecter::_check_command_map_dne (this=this@entry=0x7f76c00aeb30, c=c@entry=0x7f76b0000b10) at /build/ceph-13.0.2-1932-g458b4fb/src/osdc/Objecter.cc:1726 #11 0x00007f76d26e52e4 in Objecter::_scan_requests (this=this@entry=0x7f76c00aeb30, s=0x7f76c00af8a0, skipped_map=skipped_map@entry=false, cluster_full=cluster_full@entry=false, pool_full_map=0x7f76be7fb330, need_resend=..., need_resend_linger=..., need_resend_command=std::map with 0 elements, sul=..., gap_removed_snaps=0x7f76ac0016f8) at /build/ceph-13.0.2-1932-g458b4fb/src/osdc/Objecter.cc:1120 #12 0x00007f76d26eded5 in Objecter::handle_osd_map (this=this@entry=0x7f76c00aeb30, m=m@entry=0x7f76ac0014a0) at /build/ceph-13.0.2-1932-g458b4fb/src/osdc/Objecter.cc:1228 led to recursive lock of the session mutex (locked in _scan_requests, and again in _finish_command). Fix by making the callers for _finish_command (and _check_command_map_dne) take the session lock. Fixes: http://tracker.ceph.com/issues/23940 Signed-off-by: Sage Weil (cherry picked from commit 891f5192427a4a783d5d7194fc2556dfdc1a0ed2) --- diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 0393be268ae3..39cd1f7a656c 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -1697,7 +1697,9 @@ void Objecter::C_Command_Map_Latest::finish(int r) if (c->map_dne_bound == 0) c->map_dne_bound = latest; + OSDSession::unique_lock sul(c->session->lock); objecter->_check_command_map_dne(c); + sul.unlock(); c->put(); } @@ -1705,6 +1707,7 @@ void Objecter::C_Command_Map_Latest::finish(int r) void Objecter::_check_command_map_dne(CommandOp *c) { // rwlock is locked unique + // session is locked unique ldout(cct, 10) << "_check_command_map_dne tid " << c->tid << " current " << osdmap->get_epoch() @@ -1722,6 +1725,7 @@ void Objecter::_check_command_map_dne(CommandOp *c) void Objecter::_send_command_map_check(CommandOp *c) { // rwlock is locked unique + // session is locked unique // ask the monitor if (check_latest_map_commands.count(c->tid) == 0) { @@ -4771,8 +4775,10 @@ void Objecter::handle_command_reply(MCommandReply *m) sl.unlock(); - + OSDSession::unique_lock sul(s->lock); _finish_command(c, m->r, m->rs); + sul.unlock(); + m->put(); if (s) s->put(); @@ -4919,13 +4925,16 @@ int Objecter::command_op_cancel(OSDSession *s, ceph_tid_t tid, int r) CommandOp *op = it->second; _command_cancel_map_check(op); + OSDSession::unique_lock sl(op->session->lock); _finish_command(op, r, ""); + sl.unlock(); return 0; } void Objecter::_finish_command(CommandOp *c, int r, string rs) { // rwlock is locked unique + // session lock is locked ldout(cct, 10) << "_finish_command " << c->tid << " = " << r << " " << rs << dendl; @@ -4938,9 +4947,7 @@ void Objecter::_finish_command(CommandOp *c, int r, string rs) timer.cancel_event(c->ontimeout); OSDSession *s = c->session; - OSDSession::unique_lock sl(s->lock); _session_command_op_remove(c->session, c); - sl.unlock(); c->put();