On Thu, Jul 30, 2009 at 07:01:15PM +0200, Mike Galbraith wrote: > On Thu, 2009-07-30 at 08:22 -0700, Greg KH wrote: > > On Thu, Jul 30, 2009 at 11:38:55AM +0200, Mike Galbraith wrote: > > > -------- Forwarded Message -------- > > > From: Mike Galbraith <efault at gmx.de> > > > To: linux-wireless at vger.kernel.org > > > Cc: LKML <linux-kernel at vger.kernel.org>, John W. Linville > > > <linville at tuxdriver.com> > > > Subject: [wireless] rt2870sta BUGs on shutdown, 2.6.30.2->git.today > > > +git.wireless.today > > > Date: Thu, 30 Jul 2009 11:22:54 +0200 > > > > > > Greetings, > > > > > > $subject appears (at glance) to happen because threads have already > > > exited when we get to BUG_ON(), I haven't pursued it though. Using > > > rt3070sta instead of rt2870sta works a treat with same box/adapter. > > > > > > (the 2009_0521_RT2870_Linux_STA_V2.1.2.0 tree patches and rpm'd up for > > > opensuse-11.1 with kernels 27->29 doesn't BUG.. for 30 onward, I'm using > > > the in kernel staging drivers) > > > > Yeah, I think we need to just revert that patch, I'll go dig it up and > > do it later today... > > > > Can you test any proposed patches for this? > > Sure thing, only takes a couple minutes. Great, here's a patch against 2.6.30.1. Let me know if it solves the problem for you or not. thanks, greg k-h --------------- reverted: --- b/drivers/staging/rt2870/2870_main_dev.c +++ a/drivers/staging/rt2870/2870_main_dev.c @@ -265,7 +265,7 @@ */ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__)); + pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE; - pObj->MLMEThr_task = NULL; complete_and_exit (&pAd->mlmeComplete, 0); return 0; @@ -373,7 +373,7 @@ */ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); + pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE; - pObj->RTUSBCmdThr_task = NULL; complete_and_exit (&pAd->CmdQComplete, 0); return 0; @@ -467,7 +467,7 @@ */ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__)); + pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE; - pObj->TimerQThr_task = NULL; complete_and_exit(&pAd->TimerQComplete, 0); return 0; @@ -944,46 +944,69 @@ RTUSBCancelPendingIRPs(pAd); // Terminate Threads + CHECK_PID_LEGALITY(pObj->TimerQThr_pid) - BUG_ON(pObj->TimerQThr_task == NULL); - CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task)) { POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid)); - printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n", - pid_nr(task_pid(pObj->TimerQThr_task))); mb(); pAd->TimerFunc_kill = 1; mb(); + ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1); + if (ret) + { + printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n", + pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret); + } + else + { + wait_for_completion(&pAd->TimerQComplete); + pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE; + } - kthread_stop(pObj->TimerQThr_task); - pObj->TimerQThr_task = NULL; } + CHECK_PID_LEGALITY(pObj->MLMEThr_pid) - BUG_ON(pObj->MLMEThr_task == NULL); - CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task)) { + printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid)); - printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n", - pid_nr(task_pid(pObj->MLMEThr_task))); mb(); pAd->mlme_kill = 1; //RT28XX_MLME_HANDLER(pAd); mb(); + ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1); + if (ret) + { + printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n", + pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret); + } + else + { + //wait_for_completion (&pAd->notify); + wait_for_completion (&pAd->mlmeComplete); + pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE; + } - kthread_stop(pObj->MLMEThr_task); - pObj->MLMEThr_task = NULL; } + CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) - BUG_ON(pObj->RTUSBCmdThr_task == NULL); - CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task)) { + printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid)); - printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n", - pid_nr(task_pid(pObj->RTUSBCmdThr_task))); mb(); NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED; NdisReleaseSpinLock(&pAd->CmdQLock); mb(); //RTUSBCMDUp(pAd); + ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1); + if (ret) + { + printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n", + pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret); + } + else + { + //wait_for_completion (&pAd->notify); + wait_for_completion (&pAd->CmdQComplete); + pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE; + } - kthread_stop(pObj->RTUSBCmdThr_task); - pObj->RTUSBCmdThr_task = NULL; } @@ -1044,7 +1067,7 @@ if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor && dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) { + printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n", - printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n", dev_p->descriptor.idVendor, dev_p->descriptor.idProduct); break; } reverted: --- b/drivers/staging/rt2870/common/2870_rtmp_init.c +++ a/drivers/staging/rt2870/common/2870_rtmp_init.c @@ -727,8 +727,8 @@ usb_dev = pObj->pUsb_Dev; + pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE; + pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE; - pObj->MLMEThr_task = NULL; - pObj->RTUSBCmdThr_task = NULL; *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); @@ -765,7 +765,7 @@ { PRTMP_ADAPTER pAd = net_dev->ml_priv; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + pid_t pid_number = -1; - struct task_struct *tsk; //init_MUTEX(&(pAd->usbdev_semaphore)); @@ -779,39 +779,36 @@ init_completion (&pAd->TimerQComplete); // Creat MLME Thread + pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE; + pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM); + if (pid_number < 0) + { - pObj->MLMEThr_task = NULL; - tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name); - - if (IS_ERR(tsk)) { printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name); return NDIS_STATUS_FAILURE; } + pObj->MLMEThr_pid = GET_PID(pid_number); - - pObj->MLMEThr_task = tsk; // Wait for the thread to start wait_for_completion(&(pAd->mlmeComplete)); // Creat Command Thread + pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE; + pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM); + if (pid_number < 0) - pObj->RTUSBCmdThr_task = NULL; - tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name); - - if (IS_ERR(tsk) < 0) { printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name); return NDIS_STATUS_FAILURE; } + pObj->RTUSBCmdThr_pid = GET_PID(pid_number); - - pObj->RTUSBCmdThr_task = tsk; wait_for_completion(&(pAd->CmdQComplete)); + pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE; + pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM); + if (pid_number < 0) - pObj->TimerQThr_task = NULL; - tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name); - if (IS_ERR(tsk) < 0) { printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name); return NDIS_STATUS_FAILURE; } + pObj->TimerQThr_pid = GET_PID(pid_number); - pObj->TimerQThr_task = tsk; // Wait for the thread to start wait_for_completion(&(pAd->TimerQComplete)); reverted: --- b/drivers/staging/rt2870/common/cmm_data.c +++ a/drivers/staging/rt2870/common/cmm_data.c @@ -709,6 +709,9 @@ } return TRUE; + +FillTxBlkErr: + return FALSE; } reverted: --- b/drivers/staging/rt2870/common/rtmp_init.c +++ a/drivers/staging/rt2870/common/rtmp_init.c @@ -3655,7 +3655,7 @@ #ifdef RALINK_28xx_QA //pAd->ate.Repeat = 0; pAd->ate.TxStatus = 0; + pAd->ate.AtePid = THREAD_PID_INIT_VALUE; - pAd->ate.AtePid = NULL; #endif // RALINK_28xx_QA // #endif // RALINK_ATE // reverted: --- b/drivers/staging/rt2870/common/rtusb_io.c +++ a/drivers/staging/rt2870/common/rtusb_io.c @@ -958,8 +958,7 @@ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) - BUG_ON(pObj->RTUSBCmdThr_task == NULL); - CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task)) return (NDIS_STATUS_RESOURCES); status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt)); reverted: --- b/drivers/staging/rt2870/rt2870.h +++ a/drivers/staging/rt2870/rt2870.h @@ -577,16 +577,14 @@ #define RTUSBMlmeUp(pAd) \ { \ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \ + CHECK_PID_LEGALITY(pObj->MLMEThr_pid) \ - BUG_ON(pObj->MLMEThr_task == NULL); \ - CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task)) \ up(&(pAd->mlme_semaphore)); \ } #define RTUSBCMDUp(pAd) \ { \ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \ + CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) \ - BUG_ON(pObj->RTUSBCmdThr_task == NULL); \ - CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task)) \ up(&(pAd->RTUSBCmd_semaphore)); \ } reverted: --- b/drivers/staging/rt2870/rt_linux.h +++ a/drivers/staging/rt2870/rt_linux.h @@ -44,7 +44,6 @@ #include <linux/module.h> #include <linux/version.h> #include <linux/kernel.h> -#include <linux/kthread.h> #include <linux/spinlock.h> #include <linux/init.h> @@ -166,12 +165,14 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) typedef struct pid * THREAD_PID; +#define THREAD_PID_INIT_VALUE NULL #define GET_PID(_v) find_get_pid(_v) #define GET_PID_NUMBER(_v) pid_nr(_v) #define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0) #define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C) #else typedef pid_t THREAD_PID; +#define THREAD_PID_INIT_VALUE -1 #define GET_PID(_v) _v #define GET_PID_NUMBER(_v) _v #define CHECK_PID_LEGALITY(_pid) if (_pid >= 0) @@ -187,11 +188,11 @@ struct os_cookie { #ifdef RT2870 + struct usb_device *pUsb_Dev; - struct usb_device *pUsb_Dev; + THREAD_PID MLMEThr_pid; + THREAD_PID RTUSBCmdThr_pid; + THREAD_PID TimerQThr_pid; - struct task_struct *MLMEThr_task; - struct task_struct *RTUSBCmdThr_task; - struct task_struct *TimerQThr_task; #endif // RT2870 // struct tasklet_struct rx_done_task;