[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: Sukadev Bhattiprolu <sukadev@us.ibm.com> Cc: Javier Achirica <achirica@gmail.com> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
e4ac2663ea
commit
3b4c7d6403
@@ -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 {
|
|||||||
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,
|
|||||||
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 )
|
|||||||
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,
|
|||||||
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 @@ err_out_unlink:
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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)
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user