Commit cc975786 authored by Ben Collins's avatar Ben Collins

[IEEE1394]: Fix deadlock in killing kernel thread

parent c910f1cd
...@@ -994,7 +994,7 @@ void abort_timedouts(unsigned long __opaque) ...@@ -994,7 +994,7 @@ void abort_timedouts(unsigned long __opaque)
* packets that have a "complete" function are sent here. This way, the * packets that have a "complete" function are sent here. This way, the
* completion is run out of kernel context, and doesn't block the rest of * completion is run out of kernel context, and doesn't block the rest of
* the stack. */ * the stack. */
static int khpsbpkt_pid = -1; static int khpsbpkt_pid = -1, khpsbpkt_kill;
static DECLARE_COMPLETION(khpsbpkt_complete); static DECLARE_COMPLETION(khpsbpkt_complete);
struct sk_buff_head hpsbpkt_queue; struct sk_buff_head hpsbpkt_queue;
static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); static DECLARE_MUTEX_LOCKED(khpsbpkt_sig);
...@@ -1021,6 +1021,9 @@ static int hpsbpkt_thread(void *__hi) ...@@ -1021,6 +1021,9 @@ static int hpsbpkt_thread(void *__hi)
daemonize("khpsbpkt"); daemonize("khpsbpkt");
while (!down_interruptible(&khpsbpkt_sig)) { while (!down_interruptible(&khpsbpkt_sig)) {
if (khpsbpkt_kill)
break;
while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) {
packet = (struct hpsb_packet *)skb->data; packet = (struct hpsb_packet *)skb->data;
...@@ -1094,7 +1097,9 @@ static void __exit ieee1394_cleanup(void) ...@@ -1094,7 +1097,9 @@ static void __exit ieee1394_cleanup(void)
bus_unregister(&ieee1394_bus_type); bus_unregister(&ieee1394_bus_type);
if (khpsbpkt_pid >= 0) { if (khpsbpkt_pid >= 0) {
kill_proc(khpsbpkt_pid, SIGTERM, 1); khpsbpkt_kill = 1;
mb();
up(&khpsbpkt_sig);
wait_for_completion(&khpsbpkt_complete); wait_for_completion(&khpsbpkt_complete);
} }
......
...@@ -117,6 +117,7 @@ struct host_info { ...@@ -117,6 +117,7 @@ struct host_info {
struct semaphore reset_sem; struct semaphore reset_sem;
int pid; int pid;
char daemon_name[15]; char daemon_name[15];
int kill_me;
}; };
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
...@@ -1478,6 +1479,9 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1478,6 +1479,9 @@ static int nodemgr_host_thread(void *__hi)
unsigned int generation = 0; unsigned int generation = 0;
int i; int i;
if (hi->kill_me)
break;
/* Pause for 1/4 second in 1/16 second intervals, /* Pause for 1/4 second in 1/16 second intervals,
* to make sure things settle down. */ * to make sure things settle down. */
for (i = 0; i < 4 ; i++) { for (i = 0; i < 4 ; i++) {
...@@ -1678,7 +1682,9 @@ static void nodemgr_remove_host(struct hpsb_host *host) ...@@ -1678,7 +1682,9 @@ static void nodemgr_remove_host(struct hpsb_host *host)
if (hi) { if (hi) {
if (hi->pid >= 0) { if (hi->pid >= 0) {
kill_proc(hi->pid, SIGTERM, 1); hi->kill_me = 1;
mb();
up(&hi->reset_sem);
wait_for_completion(&hi->exited); wait_for_completion(&hi->exited);
nodemgr_remove_host_dev(&host->device); nodemgr_remove_host_dev(&host->device);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment