]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: don't schedule a cr if already scheduled
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 19 Oct 2017 21:04:03 +0000 (14:04 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Tue, 10 Apr 2018 15:05:39 +0000 (08:05 -0700)
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 <yehuda@redhat.com>
src/rgw/rgw_coroutine.cc

index f4e1e0ab1dd07a02876bffe3d953e3ca40ae0f68..852fee41f38359cfec1d270856d3ac4987f63337 100644 (file)
@@ -513,8 +513,10 @@ void RGWCoroutinesManager::handle_unblocked_stack(set<RGWCoroutinesStack *>& 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<RGWCoroutinesStack *>& context_stacks = run_contexts[env->run_context];
   context_stacks.insert(stack);
 }
@@ -573,6 +577,8 @@ int RGWCoroutinesManager::run(list<RGWCoroutinesStack *>& stacks)
 
   for (list<RGWCoroutinesStack *>::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<RGWCoroutinesStack *>& stacks)
     }
 
 next:
-    ++iter;
-    scheduled_stacks.pop_front();
-
-
     while (scheduled_stacks.empty() && blocked_count > 0) {
       lock.unlock();
       ret = completion_mgr->get_next(&io);