mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-06 17:43:43 +00:00
18ecbb4771
The pvrusb2 driver was getting had by this scenario: 1. Task A calls kthread_stop() for task B. 2. Before exiting, then Task B calls kthread_stop() for task C. The problem is, kthread_stop() wants to allocate an internal resource to itself (i.e. acquire a lock), which won't be released until kthread_stop() returns. But kthread_stop() won't return until task B is dead. But task B won't die until it finishes its call to kthread_stop() for task C, and that will block waiting on the resource already allocated inside task A. Deadlock. With the pvrusb2 driver, task A is the caller to pvr_exit(), task B is the control thread run inside of pvrusb2-context.c, and task C is any worker thread run inside of pvrusb2-hdw.c. This problem got introduced by the previous threading setup change, which was itself an attempt to fix a module tear-down race (which it actually did fix). The lesson here is that a task being waited on as part of a kthread_stop() simply cannot be allow to also issue a kthread_stop() - or we make sure not to issue the enclosing kthread_stop() until we know that the inner kthread_stop() has completed first. The solution for the pvrusb2 driver is some hackish code which changes the main control thread tear down into a two step process. This then makes it possible to delay issuing the kthread_stop() on the control thread until after we know that everything has been torn down first. (And yes, we really need that kthread_stop() because it's the only way to safely guarantee that a module-referencing kernel thread has safely returned back out of the module before we finally remove the module.) Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org> |
||
---|---|---|
.. | ||
Kconfig | ||
Makefile | ||
pvrusb2-audio.c | ||
pvrusb2-audio.h | ||
pvrusb2-context.c | ||
pvrusb2-context.h | ||
pvrusb2-ctrl.c | ||
pvrusb2-ctrl.h | ||
pvrusb2-cx2584x-v4l.c | ||
pvrusb2-cx2584x-v4l.h | ||
pvrusb2-debug.h | ||
pvrusb2-debugifc.c | ||
pvrusb2-debugifc.h | ||
pvrusb2-devattr.c | ||
pvrusb2-devattr.h | ||
pvrusb2-dvb.c | ||
pvrusb2-dvb.h | ||
pvrusb2-eeprom.c | ||
pvrusb2-eeprom.h | ||
pvrusb2-encoder.c | ||
pvrusb2-encoder.h | ||
pvrusb2-fx2-cmd.h | ||
pvrusb2-hdw-internal.h | ||
pvrusb2-hdw.c | ||
pvrusb2-hdw.h | ||
pvrusb2-i2c-chips-v4l2.c | ||
pvrusb2-i2c-cmd-v4l2.c | ||
pvrusb2-i2c-cmd-v4l2.h | ||
pvrusb2-i2c-core.c | ||
pvrusb2-i2c-core.h | ||
pvrusb2-io.c | ||
pvrusb2-io.h | ||
pvrusb2-ioread.c | ||
pvrusb2-ioread.h | ||
pvrusb2-main.c | ||
pvrusb2-std.c | ||
pvrusb2-std.h | ||
pvrusb2-sysfs.c | ||
pvrusb2-sysfs.h | ||
pvrusb2-tuner.c | ||
pvrusb2-tuner.h | ||
pvrusb2-util.h | ||
pvrusb2-v4l2.c | ||
pvrusb2-v4l2.h | ||
pvrusb2-video-v4l.c | ||
pvrusb2-video-v4l.h | ||
pvrusb2-wm8775.c | ||
pvrusb2-wm8775.h | ||
pvrusb2.h |