Commit 955e7da8 authored by Alexey Khoroshilov's avatar Alexey Khoroshilov Committed by Greg Kroah-Hartman

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: default avatarAlexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ccbdccd4
...@@ -123,7 +123,7 @@ int SendString(DEVICE_EXTENSION * pdx, const char __user * pData, ...@@ -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) ...@@ -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,7 +433,7 @@ int GetChar(DEVICE_EXTENSION * pdx) ...@@ -433,7 +433,7 @@ 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);
...@@ -447,7 +447,7 @@ int GetChar(DEVICE_EXTENSION * pdx) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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,
......
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