staging: ced1401: fix GFP_KERNEL in spinlock context
Allowi() calls usb_submit_urb(pdx->pUrbCharIn, bInCallback ? GFP_ATOMIC : GFP_KERNEL) under spin_lock_irqsave(&pdx->charInLock, flags). That means it should use GFP_ATOMIC anyway. As soon as it is the only usage of bInCallback argument, the patch removes it at all. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
ccbdccd4a7
Коммит
955e7da82d
|
@ -123,7 +123,7 @@ int SendString(DEVICE_EXTENSION * pdx, const char __user * pData,
|
||||||
iReturn = PutChars(pdx, buffer, n);
|
iReturn = PutChars(pdx, buffer, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
Allowi(pdx, false); // make sure we have input int
|
Allowi(pdx); // make sure we have input int
|
||||||
mutex_unlock(&pdx->io_mutex);
|
mutex_unlock(&pdx->io_mutex);
|
||||||
|
|
||||||
return iReturn;
|
return iReturn;
|
||||||
|
@ -140,7 +140,7 @@ int SendChar(DEVICE_EXTENSION * pdx, char c)
|
||||||
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
iReturn = PutChars(pdx, &c, 1);
|
iReturn = PutChars(pdx, &c, 1);
|
||||||
dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c);
|
dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c);
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
mutex_unlock(&pdx->io_mutex);
|
mutex_unlock(&pdx->io_mutex);
|
||||||
return iReturn;
|
return iReturn;
|
||||||
}
|
}
|
||||||
|
@ -433,8 +433,8 @@ int GetChar(DEVICE_EXTENSION * pdx)
|
||||||
|
|
||||||
dev_dbg(&pdx->interface->dev, "GetChar");
|
dev_dbg(&pdx->interface->dev, "GetChar");
|
||||||
|
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
SendChars(pdx); // and send any buffered chars
|
SendChars(pdx); // and send any buffered chars
|
||||||
|
|
||||||
spin_lock_irq(&pdx->charInLock);
|
spin_lock_irq(&pdx->charInLock);
|
||||||
if (pdx->dwNumInput > 0) // worth looking
|
if (pdx->dwNumInput > 0) // worth looking
|
||||||
|
@ -447,7 +447,7 @@ int GetChar(DEVICE_EXTENSION * pdx)
|
||||||
iReturn = U14ERR_NOIN; // no input data to read
|
iReturn = U14ERR_NOIN; // no input data to read
|
||||||
spin_unlock_irq(&pdx->charInLock);
|
spin_unlock_irq(&pdx->charInLock);
|
||||||
|
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
|
|
||||||
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
return iReturn;
|
return iReturn;
|
||||||
|
@ -472,7 +472,7 @@ int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
SendChars(pdx); // and send any buffered chars
|
SendChars(pdx); // and send any buffered chars
|
||||||
|
|
||||||
spin_lock_irq(&pdx->charInLock);
|
spin_lock_irq(&pdx->charInLock);
|
||||||
|
@ -518,7 +518,7 @@ int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n)
|
||||||
} else
|
} else
|
||||||
spin_unlock_irq(&pdx->charInLock);
|
spin_unlock_irq(&pdx->charInLock);
|
||||||
|
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
|
|
||||||
return iReturn;
|
return iReturn;
|
||||||
|
@ -531,7 +531,7 @@ int Stat1401(DEVICE_EXTENSION * pdx)
|
||||||
{
|
{
|
||||||
int iReturn;
|
int iReturn;
|
||||||
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
Allowi(pdx, false); // make sure we allow pending chars
|
Allowi(pdx); // make sure we allow pending chars
|
||||||
SendChars(pdx); // in both directions
|
SendChars(pdx); // in both directions
|
||||||
iReturn = pdx->dwNumInput; // no lock as single read
|
iReturn = pdx->dwNumInput; // no lock as single read
|
||||||
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
|
@ -550,7 +550,7 @@ int LineCount(DEVICE_EXTENSION * pdx)
|
||||||
int iReturn = 0; // will be count of line ends
|
int iReturn = 0; // will be count of line ends
|
||||||
|
|
||||||
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o
|
||||||
Allowi(pdx, false); // Make sure char reads are running
|
Allowi(pdx); // Make sure char reads are running
|
||||||
SendChars(pdx); // and send any buffered chars
|
SendChars(pdx); // and send any buffered chars
|
||||||
spin_lock_irq(&pdx->charInLock); // Get protection
|
spin_lock_irq(&pdx->charInLock); // Get protection
|
||||||
|
|
||||||
|
|
|
@ -697,7 +697,7 @@ static void staged_callback(struct urb *pUrb)
|
||||||
// in Allowi as if it were protected by the char lock. In any case, most systems will
|
// in Allowi as if it were protected by the char lock. In any case, most systems will
|
||||||
// not be upset by char input during DMA... sigh. Needs sorting out.
|
// not be upset by char input during DMA... sigh. Needs sorting out.
|
||||||
if (bRestartCharInput) // may be out of date, but...
|
if (bRestartCharInput) // may be out of date, but...
|
||||||
Allowi(pdx, true); // ...Allowi tests a lock too.
|
Allowi(pdx); // ...Allowi tests a lock too.
|
||||||
dev_dbg(&pdx->interface->dev, "%s done", __func__);
|
dev_dbg(&pdx->interface->dev, "%s done", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1172,7 +1172,7 @@ static void ced_readchar_callback(struct urb *pUrb)
|
||||||
pdx->bReadCharsPending = false; // No longer have a pending read
|
pdx->bReadCharsPending = false; // No longer have a pending read
|
||||||
spin_unlock(&pdx->charInLock); // already at irq level
|
spin_unlock(&pdx->charInLock); // already at irq level
|
||||||
|
|
||||||
Allowi(pdx, true); // see if we can do the next one
|
Allowi(pdx); // see if we can do the next one
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -1182,7 +1182,7 @@ static void ced_readchar_callback(struct urb *pUrb)
|
||||||
** we can pick up any inward transfers. This can be called in multiple contexts
|
** we can pick up any inward transfers. This can be called in multiple contexts
|
||||||
** so we use the irqsave version of the spinlock.
|
** so we use the irqsave version of the spinlock.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback)
|
int Allowi(DEVICE_EXTENSION * pdx)
|
||||||
{
|
{
|
||||||
int iReturn = U14ERR_NOERROR;
|
int iReturn = U14ERR_NOERROR;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1211,9 +1211,7 @@ int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback)
|
||||||
pdx, pdx->bInterval);
|
pdx, pdx->bInterval);
|
||||||
pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default
|
pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default
|
||||||
usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it
|
usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it
|
||||||
iReturn =
|
iReturn = usb_submit_urb(pdx->pUrbCharIn, GFP_ATOMIC);
|
||||||
usb_submit_urb(pdx->pUrbCharIn,
|
|
||||||
bInCallback ? GFP_ATOMIC : GFP_KERNEL);
|
|
||||||
if (iReturn) {
|
if (iReturn) {
|
||||||
usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs
|
usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs
|
||||||
pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
|
pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later
|
||||||
|
|
|
@ -204,7 +204,7 @@ typedef struct _DEVICE_EXTENSION
|
||||||
|
|
||||||
/// Definitions of routimes used between compilation object files
|
/// Definitions of routimes used between compilation object files
|
||||||
// in usb1401.c
|
// in usb1401.c
|
||||||
extern int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback);
|
extern int Allowi(DEVICE_EXTENSION* pdx);
|
||||||
extern int SendChars(DEVICE_EXTENSION* pdx);
|
extern int SendChars(DEVICE_EXTENSION* pdx);
|
||||||
extern void ced_draw_down(DEVICE_EXTENSION *pdx);
|
extern void ced_draw_down(DEVICE_EXTENSION *pdx);
|
||||||
extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
|
extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче