linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] Fix bug about invalid wake up problem
@ 2013-08-29 13:57 Libin
  2013-08-29 13:57 ` [PATCH 01/14] kthread: Fix invalid wakeup in kthreadd Libin
                   ` (17 more replies)
  0 siblings, 18 replies; 25+ messages in thread
From: Libin @ 2013-08-29 13:57 UTC (permalink / raw)
  To: akpm, tj, viro, eparis, tglx, rusty, ebiederm, paulmck,
	john.stultz, mingo, peterz, gregkh
  Cc: linux-kernel, lizefan, jovi.zhangwei, guohanjun, zhangdianfang,
	wangyijing, huawei.libin

1)Problem Description:
The prototype of invalid wakeup problem is as follows:
========================================================================
----------------------------
Consumer Thread
----------------------------
...
if (list_empty(&list)){
	//location a 
	set_current_state(TASK_INTERRUPTIBLE);
	schedule();
}
...
----------------------------
Producer Thread
----------------------------
...
list_add_tail(&item, &list);
wake_up_process(A);
...
========================================================================

Invalid wakeup problem occurs in preemptable kernel environment. The list
is empty initially, if consumer is preempted after condition validated at
location a, and at this time producer is woken up, adding a node to the
list and calling wake_up_process to wake up consumer. After that when
consumer being scheduled by scheduler, it calls set_current_state to set
itself as state TASK_INTERRUPTIBLE, and calling schedule() to request
scheduled. After consumer being scheduled out, it has no condition to be
woken up, and causing invalid wakeup problem.

In most cases, the kernel codes use a form similar to the following:
--------------------------------------------
 ...
 //location a
 ...
 set_current_state(TASK_INTERRUPTIBLE);
 //location b
 while (list_empty(&product_list)){
	schedule();	//location c
	set_current_state(TASK_INTERRUPTIBLE);
	//location d
}
__set_current_state(TASK_RUNNING);
...
--------------------------------------------
At location a, consumer is preempted, and producer is scheduled,
adding item to product_list and waking up consumer. After consumer is
re-scheduled, calling set_current_state to set itself as state
TASK_INTERRUPTIBLE, if it is preempted again before __set_current_state(TASK_RUNNING),
also trigger the invalid wakeup problem that the consumer will not be scheduled
and the item be added by producer can't be consumed.

The following circumstance will also trigger this issue:
At location c, consumer is scheduled out, and be preempted after calling
set_current_state(TASK_INTERRUPTIBLE) when it be re-schdeuled.

2)Test:
I have written a test module to trigger the problem by adding some
synchronization condition. I will post it in the form of an attachment soon.

Test result as follows:
[103135.332683] wakeup_test: create two kernel threads - producer & consumer
[103135.332686] wakeup_test: module loaded successfully
[103135.332692] wakeup_test: kthread producer try to wake up the kthread consumer
[103165.299865] wakeup_test: kthread consumer have waited for 30s, indicating
trigger an invalid wakeup problem!

3)Solution:
Using preempt_disable() to bound the operaion that setting the task state
and the conditions(set by the wake thread) validation.

----------------------------------------------
...
preempt_disable();
set_current_state(TASK_INTERRUPTIBLE);
while (list_empty(&product_list)){
	preempt_enable();
	schedule();
	preempt_disable();
	set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
preempt_enable();
...
----------------------------------------------
And it also can be solved as follows:
----------------------------------------------
...
preempt_disable();
while (list_empty(&product_list)){
	set_current_state(TASK_INTERRUPTIBLE);
	preempt_enable();
	schedule();
	preempt_disable();	
}
preempt_enable();
...
----------------------------------------------

Libin (14):
  kthread: Fix invalid wakeup in kthreadd
  audit: Fix invalid wakeup in kauditd_thread
  audit: Fix invalid wakeup in wait_for_auditd
  exit: Fix invalid wakeup in do_wait
  hrtimer: Fix invalid wakeup in do_nanosleep
  irq: Fix invalid wakeup in irq_wait_for_interrupt
  module: Fix invalid wakeup in wait_for_zero_refcount
  namespace: Fix invalid wakeup in zap_pid_ns_processes
  rcutree: Fix invalid wakeup in rcu_wait
  time: Fix invalid wakeup in alarmtimer_do_nsleep
  trace: Fix invalid wakeup in wait_to_die
  trace: Fix invalid wakeup in ring_buffer_consumer_thread
  workqueue: Fix invalid wakeup in rescuer_thread
  klist: Fix invalid wakeup in klist_remove

 kernel/audit.c                       | 11 ++++-
 kernel/exit.c                        |  7 ++-
 kernel/hrtimer.c                     |  7 ++-
 kernel/irq/manage.c                  |  5 ++
 kernel/kthread.c                     |  7 ++-
 kernel/module.c                      |  6 ++-
 kernel/pid_namespace.c               |  4 ++
 kernel/rcutree.h                     |  4 ++
 kernel/time/alarmtimer.c             |  7 ++-
 kernel/trace/ring_buffer_benchmark.c | 14 ++++++
 kernel/workqueue.c                   | 92 +++++++++++++++++++-----------------
 lib/klist.c                          |  4 ++
 12 files changed, 118 insertions(+), 50 deletions(-)

-- 
1.8.2.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2013-09-12 13:37 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-29 13:57 [PATCH 00/14] Fix bug about invalid wake up problem Libin
2013-08-29 13:57 ` [PATCH 01/14] kthread: Fix invalid wakeup in kthreadd Libin
2013-08-30  0:20   ` Paul E. McKenney
2013-08-29 13:57 ` [PATCH 02/14] audit: Fix invalid wakeup in kauditd_thread Libin
2013-08-29 13:57 ` [PATCH 03/14] audit: Fix invalid wakeup in wait_for_auditd Libin
2013-08-29 13:57 ` [PATCH 04/14] exit: Fix invalid wakeup in do_wait Libin
2013-08-29 13:57 ` [PATCH 05/14] hrtimer: Fix invalid wakeup in do_nanosleep Libin
2013-09-12 13:33   ` Thomas Gleixner
2013-08-29 13:57 ` [PATCH 06/14] irq: Fix invalid wakeup in irq_wait_for_interrupt Libin
2013-09-12 13:36   ` Thomas Gleixner
2013-08-29 13:57 ` [PATCH 07/14] module: Fix invalid wakeup in wait_for_zero_refcount Libin
2013-08-29 13:57 ` [PATCH 08/14] namespace: Fix invalid wakeup in zap_pid_ns_processes Libin
2013-08-29 13:57 ` [PATCH 09/14] rcutree: Fix invalid wakeup in rcu_wait Libin
2013-08-30  0:23   ` Paul E. McKenney
2013-08-29 13:57 ` [PATCH 10/14] time: Fix invalid wakeup in alarmtimer_do_nsleep Libin
2013-09-12 13:36   ` Thomas Gleixner
2013-08-29 13:57 ` [PATCH 11/14] trace: Fix invalid wakeup in wait_to_die Libin
2013-08-29 13:57 ` [PATCH 12/14] trace: Fix invalid wakeup in ring_buffer_consumer_thread Libin
2013-08-29 13:57 ` [PATCH 13/14] workqueue: Fix invalid wakeup in rescuer_thread Libin
2013-08-29 13:57 ` [PATCH 14/14] klist: Fix invalid wakeup in klist_remove Libin
2013-08-29 14:08 ` [PATCH 00/14] Fix bug about invalid wake up problem Libin
2013-08-29 14:12   ` Tejun Heo
2013-08-29 14:10 ` Tejun Heo
2013-08-29 23:39 ` Libin
2013-08-30  0:18 ` Paul E. McKenney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).