kernel-fxtec-pro1x/drivers/block/drbd
Lars Ellenberg 725a97e43e drbd: fix potential access of on-stack wait_queue_head_t after return
I run into something declaring itself as "spinlock deadlock",
 BUG: spinlock lockup on CPU#1, kjournald/27816, ffff88000ad6bca0
 Pid: 27816, comm: kjournald Tainted: G        W 2.6.34.6 #2
 Call Trace:
  <IRQ>  [<ffffffff811ba0aa>] do_raw_spin_lock+0x11e/0x14d
  [<ffffffff81340fde>] _raw_spin_lock_irqsave+0x6a/0x81
  [<ffffffff8103b694>] ? __wake_up+0x22/0x50
  [<ffffffff8103b694>] __wake_up+0x22/0x50
  [<ffffffffa07ff661>] bm_async_io_complete+0x258/0x299 [drbd]
but the call traces do not fit at all,
all other cpus are cpu_idle.

I think it may be this race:

drbd_bm_write_page
 wait_queue_head_t io_wait;
 atomic_t in_flight;
 bm_async_io
  submit_bio
					bm_async_io_complete
					  if (atomic_dec_and_test(in_flight))
 wait_event(io_wait,
	atomic_read(in_flight) == 0)
 return
					    wake_up(io_wait)

The wake_up now accesses the wait_queue_head_t spinlock, which is no
longer valid, since the stack frame of drbd_bm_write_page has been
clobbered now.

Fix this by using struct completion, which does both the condition test
as well as the wake_up inside its spinlock, so this race cannot happen.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
2011-03-10 11:45:08 +01:00
..
drbd_actlog.c drbd: bitmap keep track of changes vs on-disk bitmap 2011-03-10 11:43:19 +01:00
drbd_bitmap.c drbd: fix potential access of on-stack wait_queue_head_t after return 2011-03-10 11:45:08 +01:00
drbd_int.h drbd: serialize sending of resync uuid with pending w_send_oos 2011-03-10 11:43:35 +01:00
drbd_main.c drbd: improve on bitmap write out timing 2011-03-10 11:43:40 +01:00
drbd_nl.c drbd: allow petabyte storage on 64bit arch 2011-03-10 11:43:24 +01:00
drbd_proc.c drbd: allow petabyte storage on 64bit arch 2011-03-10 11:43:24 +01:00
drbd_receiver.c drbd: add debugging assert to make sure the protocol is clean 2011-03-10 11:43:34 +01:00
drbd_req.c drbd: Documenting drbd_should_do_remote() and drbd_should_send_oos() 2011-03-10 11:43:32 +01:00
drbd_req.h drbd: Begin to account BIO processing time before inc_ap_bio() 2011-03-10 11:34:57 +01:00
drbd_strings.c drbd: Rename enum drbd_state_ret_codes to enum drbd_state_rv 2011-03-10 11:36:18 +01:00
drbd_vli.h
drbd_worker.c drbd: serialize sending of resync uuid with pending w_send_oos 2011-03-10 11:43:35 +01:00
drbd_wrappers.h drbd: Get rid of unnecessary macros (2) 2011-03-10 11:36:15 +01:00
Kconfig drbd: Kconfig fix 2009-12-29 17:38:28 +01:00
Makefile drbd: remove tracing bits 2009-10-01 21:17:58 +02:00