Commit 3b4c7d64 authored by Sukadev Bhattiprolu's avatar Sukadev Bhattiprolu Committed by John W. Linville

[PATCH] kthread: airo.c

The airo driver is currently caching a pid for later use, but with the
implementation of containers, pids themselves do not uniquely identify a
task.  The driver is also using kernel_thread() which is deprecated in
drivers.

This patch essentially replaces the kernel_thread() with kthread_create().
It also stores the task_struct of the airo_thread rather than its pid.
Since this introduces a second task_struct in struct airo_info, the patch
renames airo_info.task to airo_info.list_bss_task.

As an extension of these changes, the patch further:

	 - replaces kill_proc() with kthread_stop()
	 - replaces signal_pending() with kthread_should_stop()
	 - removes thread completion synchronisation which is handled by
	   kthread_stop().

[akpm@osdl.org: fix races]
Signed-off-by: default avatarSukadev Bhattiprolu <sukadev@us.ibm.com>
Cc: Javier Achirica <achirica@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e4ac2663
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <net/ieee80211.h> #include <net/ieee80211.h>
#include <linux/kthread.h>
#include "airo.h" #include "airo.h"
...@@ -1187,11 +1188,10 @@ struct airo_info { ...@@ -1187,11 +1188,10 @@ struct airo_info {
int whichbap); int whichbap);
unsigned short *flash; unsigned short *flash;
tdsRssiEntry *rssi; tdsRssiEntry *rssi;
struct task_struct *task; struct task_struct *list_bss_task;
struct task_struct *airo_thread_task;
struct semaphore sem; struct semaphore sem;
pid_t thr_pid;
wait_queue_head_t thr_wait; wait_queue_head_t thr_wait;
struct completion thr_exited;
unsigned long expires; unsigned long expires;
struct { struct {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1733,12 +1733,12 @@ static int readBSSListRid(struct airo_info *ai, int first, ...@@ -1733,12 +1733,12 @@ static int readBSSListRid(struct airo_info *ai, int first,
cmd.cmd=CMD_LISTBSS; cmd.cmd=CMD_LISTBSS;
if (down_interruptible(&ai->sem)) if (down_interruptible(&ai->sem))
return -ERESTARTSYS; return -ERESTARTSYS;
ai->list_bss_task = current;
issuecommand(ai, &cmd, &rsp); issuecommand(ai, &cmd, &rsp);
up(&ai->sem); up(&ai->sem);
/* Let the command take effect */ /* Let the command take effect */
ai->task = current; schedule_timeout_uninterruptible(3 * HZ);
ssleep(3); ai->list_bss_task = NULL;
ai->task = NULL;
} }
rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext, rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
list, ai->bssListRidLen, 1); list, ai->bssListRidLen, 1);
...@@ -2400,8 +2400,7 @@ void stop_airo_card( struct net_device *dev, int freeres ) ...@@ -2400,8 +2400,7 @@ void stop_airo_card( struct net_device *dev, int freeres )
clear_bit(FLAG_REGISTERED, &ai->flags); clear_bit(FLAG_REGISTERED, &ai->flags);
} }
set_bit(JOB_DIE, &ai->jobs); set_bit(JOB_DIE, &ai->jobs);
kill_proc(ai->thr_pid, SIGTERM, 1); kthread_stop(ai->airo_thread_task);
wait_for_completion(&ai->thr_exited);
/* /*
* Clean out tx queue * Clean out tx queue
...@@ -2811,9 +2810,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2811,9 +2810,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
ai->config.len = 0; ai->config.len = 0;
ai->pci = pci; ai->pci = pci;
init_waitqueue_head (&ai->thr_wait); init_waitqueue_head (&ai->thr_wait);
init_completion (&ai->thr_exited); ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); if (IS_ERR(ai->airo_thread_task))
if (ai->thr_pid < 0)
goto err_out_free; goto err_out_free;
ai->tfm = NULL; ai->tfm = NULL;
rc = add_airo_dev( dev ); rc = add_airo_dev( dev );
...@@ -2930,8 +2928,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2930,8 +2928,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
del_airo_dev(dev); del_airo_dev(dev);
err_out_thr: err_out_thr:
set_bit(JOB_DIE, &ai->jobs); set_bit(JOB_DIE, &ai->jobs);
kill_proc(ai->thr_pid, SIGTERM, 1); kthread_stop(ai->airo_thread_task);
wait_for_completion(&ai->thr_exited);
err_out_free: err_out_free:
free_netdev(dev); free_netdev(dev);
return NULL; return NULL;
...@@ -3063,13 +3060,7 @@ static int airo_thread(void *data) { ...@@ -3063,13 +3060,7 @@ static int airo_thread(void *data) {
struct airo_info *ai = dev->priv; struct airo_info *ai = dev->priv;
int locked; int locked;
daemonize("%s", dev->name);
allow_signal(SIGTERM);
while(1) { while(1) {
if (signal_pending(current))
flush_signals(current);
/* make swsusp happy with our thread */ /* make swsusp happy with our thread */
try_to_freeze(); try_to_freeze();
...@@ -3097,7 +3088,7 @@ static int airo_thread(void *data) { ...@@ -3097,7 +3088,7 @@ static int airo_thread(void *data) {
set_bit(JOB_AUTOWEP, &ai->jobs); set_bit(JOB_AUTOWEP, &ai->jobs);
break; break;
} }
if (!signal_pending(current)) { if (!kthread_should_stop()) {
unsigned long wake_at; unsigned long wake_at;
if (!ai->expires || !ai->scan_timeout) { if (!ai->expires || !ai->scan_timeout) {
wake_at = max(ai->expires, wake_at = max(ai->expires,
...@@ -3109,7 +3100,7 @@ static int airo_thread(void *data) { ...@@ -3109,7 +3100,7 @@ static int airo_thread(void *data) {
schedule_timeout(wake_at - jiffies); schedule_timeout(wake_at - jiffies);
continue; continue;
} }
} else if (!signal_pending(current)) { } else if (!kthread_should_stop()) {
schedule(); schedule();
continue; continue;
} }
...@@ -3154,7 +3145,8 @@ static int airo_thread(void *data) { ...@@ -3154,7 +3145,8 @@ static int airo_thread(void *data) {
else /* Shouldn't get here, but we make sure to unlock */ else /* Shouldn't get here, but we make sure to unlock */
up(&ai->sem); up(&ai->sem);
} }
complete_and_exit (&ai->thr_exited, 0);
return 0;
} }
static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
...@@ -3235,8 +3227,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) ...@@ -3235,8 +3227,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) { if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
if (auto_wep) if (auto_wep)
apriv->expires = 0; apriv->expires = 0;
if (apriv->task) if (apriv->list_bss_task)
wake_up_process (apriv->task); wake_up_process(apriv->list_bss_task);
set_bit(FLAG_UPDATE_UNI, &apriv->flags); set_bit(FLAG_UPDATE_UNI, &apriv->flags);
set_bit(FLAG_UPDATE_MULTI, &apriv->flags); set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
......
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