lkml.org 
[lkml]   [2004]   [Jul]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] Fix race in pktcdvd kernel thread handling
From
Date
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(&current->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/

\
 
 \ /
  Last update: 2005-03-22 14:04    [W:0.095 / U:0.108 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site