Messages in this thread Patch in this message | | | Subject | [PATCH] Fix race in pktcdvd kernel thread handling | From | Peter Osterlund <> | Date | 04 Jul 2004 14:30:08 +0200 |
| |
Running "pktsetup -d" immediately after running "pktsetup" can deadlock, because if the kcdrwd thread hasn't flushed the pending signals before pkt_remove_dev() calls kill_proc(), kcdrwd() will not be woken up.
This patch fixes it by making sure the kcdrwd() thread has finished its initialization before the thread creator returns from pkt_new_dev().
Signed-off-by: Peter Osterlund <petero2@telia.com>
---
linux-petero/drivers/block/pktcdvd.c | 9 ++++++--- linux-petero/include/linux/pktcdvd.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-)
diff -puN drivers/block/pktcdvd.c~packet-kthread-race-fix drivers/block/pktcdvd.c --- linux/drivers/block/pktcdvd.c~packet-kthread-race-fix 2004-07-04 14:09:40.183162592 +0200 +++ linux-petero/drivers/block/pktcdvd.c 2004-07-04 14:09:40.192161224 +0200 @@ -1182,6 +1182,8 @@ static int kcdrwd(void *foobar) siginitsetinv(¤t->blocked, sigmask(SIGKILL)); flush_signals(current); + up(&pd->cdrw.thr_sem); + for (;;) { DECLARE_WAITQUEUE(wait, current); @@ -1276,7 +1278,7 @@ work_to_do: pkt_iosched_process_queue(pd); } - complete_and_exit(&pd->cdrw.thr_compl, 0); + up(&pd->cdrw.thr_sem); return 0; } @@ -2407,7 +2409,7 @@ static int pkt_new_dev(struct pktcdvd_de sprintf(pd->name, "pktcdvd%d", minor); atomic_set(&pd->refcnt, 0); init_waitqueue_head(&pd->wqueue); - init_completion(&pd->cdrw.thr_compl); + init_MUTEX_LOCKED(&pd->cdrw.thr_sem); pkt_init_queue(pd); @@ -2418,6 +2420,7 @@ static int pkt_new_dev(struct pktcdvd_de ret = -EBUSY; goto out_thread; } + down(&pd->cdrw.thr_sem); create_proc_read_entry(pd->name, 0, pkt_proc, pkt_read_proc, pd); DPRINTK("pktcdvd: writer %d mapped to %s\n", minor, bdevname(bdev, b)); @@ -2484,7 +2487,7 @@ static int pkt_remove_dev(struct pktcdvd printk("pkt_remove_dev: can't kill kernel thread\n"); return ret; } - wait_for_completion(&pd->cdrw.thr_compl); + down(&pd->cdrw.thr_sem); } /* diff -puN include/linux/pktcdvd.h~packet-kthread-race-fix include/linux/pktcdvd.h --- linux/include/linux/pktcdvd.h~packet-kthread-race-fix 2004-07-04 14:09:40.185162288 +0200 +++ linux-petero/include/linux/pktcdvd.h 2004-07-04 14:09:40.192161224 +0200 @@ -140,7 +140,7 @@ struct packet_cdrw spinlock_t active_list_lock; /* Serialize access to pkt_active_list */ pid_t pid; int time_to_die; - struct completion thr_compl; + struct semaphore thr_sem; elevator_merge_fn *elv_merge_fn; elevator_completed_req_fn *elv_completed_req_fn; merge_requests_fn *merge_requests_fn; _ -- Peter Osterlund - petero2@telia.com http://w1.894.telia.com/~u89404340 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |