From: Yehuda Sadeh Date: Thu, 19 Oct 2017 21:04:03 +0000 (-0700) Subject: rgw: don't schedule a cr if already scheduled X-Git-Tag: v13.1.0~270^2~73 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=2760375f874e856fb1f6898e858af8a094596541;p=ceph.git rgw: don't schedule a cr if already scheduled This can be triggered when multiple IOs return for the same cr. We don't want to allow it to be scheduled multiple times, as this might wake up blocking IOs that shouldn't be woken up. If we try to block on an IO that we already complete, we won't block anyway. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_coroutine.cc b/src/rgw/rgw_coroutine.cc index f4e1e0ab1dd07..852fee41f3835 100644 --- a/src/rgw/rgw_coroutine.cc +++ b/src/rgw/rgw_coroutine.cc @@ -513,8 +513,10 @@ void RGWCoroutinesManager::handle_unblocked_stack(set& con } stack->set_interval_wait(false); if (!stack->is_done()) { - scheduled_stacks.push_back(stack); - stack->set_is_scheduled(true); + if (!stack->is_scheduled) { + scheduled_stacks.push_back(stack); + stack->set_is_scheduled(true); + } } else { context_stacks.erase(stack); stack->put(); @@ -530,8 +532,10 @@ void RGWCoroutinesManager::schedule(RGWCoroutinesEnv *env, RGWCoroutinesStack *s void RGWCoroutinesManager::_schedule(RGWCoroutinesEnv *env, RGWCoroutinesStack *stack) { assert(lock.is_wlocked()); - env->scheduled_stacks->push_back(stack); - stack->set_is_scheduled(true); + if (!stack->is_scheduled) { + env->scheduled_stacks->push_back(stack); + stack->set_is_scheduled(true); + } set& context_stacks = run_contexts[env->run_context]; context_stacks.insert(stack); } @@ -573,6 +577,8 @@ int RGWCoroutinesManager::run(list& stacks) for (list::iterator iter = scheduled_stacks.begin(); iter != scheduled_stacks.end() && !going_down;) { RGWCoroutinesStack *stack = *iter; + ++iter; + scheduled_stacks.pop_front(); if (context_stacks.find(stack) == context_stacks.end()) { /* stack was probably schedule more than once due to IO, but was since complete */ @@ -662,10 +668,6 @@ int RGWCoroutinesManager::run(list& stacks) } next: - ++iter; - scheduled_stacks.pop_front(); - - while (scheduled_stacks.empty() && blocked_count > 0) { lock.unlock(); ret = completion_mgr->get_next(&io);