[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 5/5] lib/ukschedcoop: Fix race condition when trying to wake up current thread


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Wed, 29 May 2019 07:56:32 +0300
  • Cc: Florian.Schmidt@xxxxxxxxx
  • Delivery-date: Wed, 29 May 2019 04:56:51 +0000
  • Ironport-phdr: 9a23:QgYM0xT3VV+LXrezXErXFWZS59psv+yvbD5Q0YIujvd0So/mwa6yZhaN2/xhgRfzUJnB7Loc0qyK6vmmADZeqsbe+Fk5M7V0HycfjssXmwFySOWkMmbcaMDQUiohAc5ZX0Vk9XzoeWJcGcL5ekGA6ibqtW1aFRrwLxd6KfroEYDOkcu3y/qy+5rOaAlUmTaxe7x/IAiroQnLq8Uan4pvJqkyxxbLv3BFZ/lYyWR0KFyJgh3y/N2w/Jlt8yRRv/Iu6ctNWrjkcqo7ULJVEi0oP3g668P3uxbDSxCP5mYHXWUNjhVIGQnF4wrkUZr3ryD3q/By2CiePc3xULA0RTGv5LplRRP0lCsKMSMy/WfKgcJyka1bugqsqRxhzYDJbo+bN/1wcaHTfd4BWWZNQtxcWzBbD4+gc4cCCfcKM+ZCr4n6olsDtQWzBQ63BOPzyz9IgGL906sn0+Q5DAHNwQstEM4JsHTPsNX1NaESXfqxzKnV1TXDcuhb1ivm6ITSahAhvOqDUahqccrW0EQiER7OgFaIqYH9Ij+Y2fkBv3KY4udgT+6jlXArpgNrrjWh3ssgl4bEip8Pxl3H9Sh12pg5KNO2RUJhfNKpH4VcuieHPIVsWMwiWXtnuCMix70Dvp60YTYFxYw8xx7ad/yHa4+I4g//VOqJITd3mnZleLWnihas9Eiv0Oz8Vs2u3FlWtSpJiMHMtm0W2BDJ8MiHTeNx/kan2TmRywDe8vxILE8pmabBKJMswqQ8moQNvUnBBCP7ll36jKqMeUUl/uio5f7nYrLjppKEK4B0jRr+Mrgvmsy5G+g4NhUOX3CG+emnyLLj5lf1QK1XjvItiKXZqpfaKdwBpqGlGw9Vzpoj6xGnAjej0dQYm3gHLFVeeB6ekofmJU/OL+78Dfqkh1SskSxrx+zdPrH7DZTCMH7DnK3mfbZn5E5W0BAzwsxH55JIFrEBJ+r+VE/1tNzfFB85Mha7w+D9BNtgyoweWWePAq6EP6POqlKI4PwgLPWIZIAPoznxMeYq5+O9xUM+zFoce6iuxt4bZW61GtxiIl6Fejz8j9FHFn0F7SQkS+m/o1qZTT9VL1KvR790sjo8E56nC8HHW5iwqLeamj+mFNtMYTYVWRi3DX70etDcCL83YyWIL5o5nw==
  • Ironport-sdr: 8HlwabhGmXqdIwNjIp5pBTCJZtWBxbwqTCGr0s6OVjgC9e7mfL+paLeEeB0P4I3+ZVOsncEnlP SCmPUFj83CxA==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

The previous patch introduced a race condition: if the current thread
blocks and yields, and an interrupt is triggered whose handle tries to
wake up the current thread then the thread will remain blocked until the
next interrupt (potentially forever) because the current thread cannot
be added to the ready threads list.

The solution is to set a flag on the current thread as soon as the next
thread is scheduled. The interrupt will queue the current thread if and
only if this flag is set.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
 lib/uksched/include/uk/thread.h | 5 +++++
 lib/ukschedcoop/schedcoop.c     | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/uksched/include/uk/thread.h b/lib/uksched/include/uk/thread.h
index 71e39225..10fd4a33 100644
--- a/lib/uksched/include/uk/thread.h
+++ b/lib/uksched/include/uk/thread.h
@@ -96,6 +96,7 @@ struct uk_thread *uk_thread_current(void)
 
 #define RUNNABLE_FLAG   0x00000001
 #define EXITED_FLAG     0x00000002
+#define QUEUEABLE_FLAG  0x00000004
 
 #define is_runnable(_thread)    ((_thread)->flags &   RUNNABLE_FLAG)
 #define set_runnable(_thread)   ((_thread)->flags |=  RUNNABLE_FLAG)
@@ -104,6 +105,10 @@ struct uk_thread *uk_thread_current(void)
 #define is_exited(_thread)      ((_thread)->flags &   EXITED_FLAG)
 #define set_exited(_thread)     ((_thread)->flags |=  EXITED_FLAG)
 
+#define is_queueable(_thread)    ((_thread)->flags &   QUEUEABLE_FLAG)
+#define set_queueable(_thread)   ((_thread)->flags |=  QUEUEABLE_FLAG)
+#define clear_queueable(_thread) ((_thread)->flags &= ~QUEUEABLE_FLAG)
+
 int uk_thread_init(struct uk_thread *thread,
                struct ukplat_ctx_callbacks *cbs, struct uk_alloc *allocator,
                const char *name, void *stack,
diff --git a/lib/ukschedcoop/schedcoop.c b/lib/ukschedcoop/schedcoop.c
index 28667bf1..5e7dbe89 100644
--- a/lib/ukschedcoop/schedcoop.c
+++ b/lib/ukschedcoop/schedcoop.c
@@ -101,6 +101,9 @@ static void schedcoop_schedule(struct uk_sched *s)
                        if (is_runnable(prev))
                                UK_TAILQ_INSERT_TAIL(&prv->thread_list, prev,
                                                thread_list);
+                       else
+                               set_queueable(prev);
+                       clear_queueable(next);
                        ukplat_stack_set_current_thread(next);
                        break;
                } else if (is_runnable(prev)) {
@@ -196,8 +199,10 @@ static void schedcoop_thread_woken(struct uk_sched *s, 
struct uk_thread *t)
 
        if (t->wakeup_time > 0)
                UK_TAILQ_REMOVE(&prv->sleeping_threads, t, thread_list);
-       if (t != uk_thread_current())
+       if (t != uk_thread_current() || is_queueable(t)) {
                UK_TAILQ_INSERT_TAIL(&prv->thread_list, t, thread_list);
+               clear_queueable(t);
+       }
 }
 
 static void idle_thread_fn(void *unused __unused)
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.