Merge pull request #2722 from ceph/wip-9598

msgr: make mark_down not block on fast dispatch

sage-2014-11-11_08:26:01-rados-wip-sage-testing-distro-basic-multi

Reviewed-by: Greg Farnum <greg@inktank.com>
This commit is contained in:
Sage Weil 2014-11-12 10:01:50 -08:00
commit 1eed56bf5d
3 changed files with 8 additions and 18 deletions

View File

@ -251,8 +251,7 @@ void *Pipe::DelayedDelivery::entry()
void Pipe::DelayedDelivery::stop_fast_dispatching() {
Mutex::Locker l(delay_lock);
stop_fast_dispatching_flag = true;
// we can't block if we're the delay thread; see Pipe::stop_and_wait()
while (delay_dispatching && !am_self())
while (delay_dispatching)
delay_cond.Wait(delay_lock);
}
@ -1431,18 +1430,11 @@ void Pipe::stop_and_wait()
if (state != STATE_CLOSED)
stop();
// HACK: we work around an annoying deadlock here. If the fast
// dispatch method calls mark_down() on itself, it can block here
// waiting for the reader_dispatching flag to clear... which will
// clearly never happen. Avoid the situation by skipping the wait
// if we are marking our *own* connect down. Do the same for the
// delayed dispatch thread.
if (delay_thread) {
delay_thread->stop_fast_dispatching();
}
while (reader_running &&
reader_dispatching &&
!reader_thread.am_self())
reader_dispatching)
cond.Wait(pipe_lock);
}

View File

@ -581,7 +581,7 @@ void SimpleMessenger::mark_down_all()
Pipe *p = *q;
ldout(cct,5) << "mark_down_all accepting_pipe " << p << dendl;
p->pipe_lock.Lock();
p->stop_and_wait();
p->stop();
PipeConnectionRef con = p->connection_state;
if (con && con->clear_pipe(p))
dispatch_queue.queue_reset(con.get());
@ -596,7 +596,7 @@ void SimpleMessenger::mark_down_all()
rank_pipe.erase(it);
p->unregister_pipe();
p->pipe_lock.Lock();
p->stop_and_wait();
p->stop();
PipeConnectionRef con = p->connection_state;
if (con && con->clear_pipe(p))
dispatch_queue.queue_reset(con.get());
@ -613,7 +613,7 @@ void SimpleMessenger::mark_down(const entity_addr_t& addr)
ldout(cct,1) << "mark_down " << addr << " -- " << p << dendl;
p->unregister_pipe();
p->pipe_lock.Lock();
p->stop_and_wait();
p->stop();
if (p->connection_state) {
// generate a reset event for the caller in this case, even
// though they asked for it, since this is the addr-based (and
@ -640,7 +640,7 @@ void SimpleMessenger::mark_down(Connection *con)
assert(p->msgr == this);
p->unregister_pipe();
p->pipe_lock.Lock();
p->stop_and_wait();
p->stop();
if (p->connection_state) {
// do not generate a reset event for the caller in this case,
// since they asked for it.

View File

@ -1762,14 +1762,12 @@ public:
public:
bool ms_dispatch(Message *m);
bool ms_can_fast_dispatch_any() const {
return false;
return true;
}
bool ms_can_fast_dispatch(Message *m) const {
switch (m->get_type()) {
case CEPH_MSG_OSD_OPREPLY:
/* sadly, we need to solve a deadlock before reenabling.
* See tracker issue #9462 */
return false;
return true;
default:
return false;
}