diff --git a/arch/lib/nuse.c b/arch/lib/nuse.c index e0bb4180dc9b..5a347302cf0e 100644 --- a/arch/lib/nuse.c +++ b/arch/lib/nuse.c @@ -232,6 +232,8 @@ void nuse_event_cancel(struct SimKernel *kernel, void *event) nuse_fiber_stop(task->private); /* nuse_fiber_free (task->private); */ + if (task->head.prev == LIST_POISON2) + return; list_del_rcu(&task->head); } diff --git a/arch/lib/sched.c b/arch/lib/sched.c index b3d558fe34af..9849f398fab7 100644 --- a/arch/lib/sched.c +++ b/arch/lib/sched.c @@ -135,7 +135,8 @@ void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait) } void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { - list_del(&wait->task_list); + if (wait->task_list.prev != LIST_POISON2) + list_del(&wait->task_list); } void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state) @@ -167,8 +168,9 @@ int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, { int ret = default_wake_function(wait, mode, sync, key); - if (ret) + if (ret && (wait->task_list.prev != LIST_POISON2)) { list_del_init(&wait->task_list); + } return ret; } @@ -208,7 +210,9 @@ unsigned long wait_for_completion_timeout(struct completion *x, do timeout = schedule_timeout(timeout); while (!x->done && timeout); - list_del(&wait.task_list); + if (wait.task_list.prev != LIST_POISON2) { + list_del(&wait.task_list); + } if (!x->done) return timeout; } diff --git a/arch/lib/timer.c b/arch/lib/timer.c index ce07c9c53b41..ef557abfe974 100644 --- a/arch/lib/timer.c +++ b/arch/lib/timer.c @@ -56,9 +56,11 @@ static void run_timer_softirq(struct softirq_action *h) fn = timer->function; data = timer->data; lib_assert(timer->base == 0); - list_del(&timer->entry); - timer->entry.next = NULL; - fn(data); + if (timer->entry.prev != LIST_POISON2) { + list_del(&timer->entry); + timer->entry.next = NULL; + fn(data); + } } } @@ -78,7 +80,9 @@ static void timer_trampoline(void *context) ensure_softirq_opened(); timer = context; timer->base = 0; - list_del(&timer->entry); + if (timer->entry.prev != LIST_POISON2) { + list_del(&timer->entry); + } list_add_tail(&timer->entry, &g_expired_events); raise_softirq(TIMER_SOFTIRQ); } @@ -136,8 +140,10 @@ int del_timer(struct timer_list *timer) retval = 1; } else retval = 0; - list_del(&timer->entry); - timer->entry.next = NULL; + if (timer->entry.prev != LIST_POISON2) { + list_del(&timer->entry); + timer->entry.next = NULL; + } return retval; } diff --git a/arch/lib/workqueue.c b/arch/lib/workqueue.c index 6f57db9b356e..7e3e2ea4848f 100644 --- a/arch/lib/workqueue.c +++ b/arch/lib/workqueue.c @@ -59,10 +59,12 @@ workqueue_function(void *context) entry); work_func_t f = work->func; - list_del_init(&work->entry); - clear_bit(WORK_STRUCT_PENDING_BIT, - work_data_bits(work)); - f(work); + if (work->entry.prev != LIST_POISON2) { + list_del_init(&work->entry); + clear_bit(WORK_STRUCT_PENDING_BIT, + work_data_bits(work)); + f(work); + } } } } @@ -134,9 +136,11 @@ bool cancel_work_sync(struct work_struct *work) return 0; if (!list_empty(&work->entry)) { /* work was queued. now unqueued. */ - list_del_init(&work->entry); - clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)); - retval = 1; + if (work->entry.prev != LIST_POISON2) { + list_del_init(&work->entry); + clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)); + retval = 1; + } } return retval; }