USB: fix BUG: sleeping function called from invalid context at /home/jeremy/hg/xen/paravirt/linux/drivers/usb/core/urb.c:524, in_atomic():1, irqs_disabled():0
Clearly there's a bug in drivers/usb/serial/usb-serial.c:usb_serial_put(). It shouldn't call kref_put() while holding a spinlock. Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
f424490031
commit
3ddad8232c
|
@ -60,19 +60,19 @@ static struct usb_driver usb_serial_driver = {
|
|||
|
||||
static int debug;
|
||||
static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
|
||||
static spinlock_t table_lock;
|
||||
static DEFINE_MUTEX(table_lock);
|
||||
static LIST_HEAD(usb_serial_driver_list);
|
||||
|
||||
struct usb_serial *usb_serial_get_by_index(unsigned index)
|
||||
{
|
||||
struct usb_serial *serial;
|
||||
|
||||
spin_lock(&table_lock);
|
||||
mutex_lock(&table_lock);
|
||||
serial = serial_table[index];
|
||||
|
||||
if (serial)
|
||||
kref_get(&serial->kref);
|
||||
spin_unlock(&table_lock);
|
||||
mutex_unlock(&table_lock);
|
||||
return serial;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
|
|||
dbg("%s %d", __FUNCTION__, num_ports);
|
||||
|
||||
*minor = 0;
|
||||
spin_lock(&table_lock);
|
||||
mutex_lock(&table_lock);
|
||||
for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
|
||||
if (serial_table[i])
|
||||
continue;
|
||||
|
@ -106,10 +106,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
|
|||
serial_table[i] = serial;
|
||||
serial->port[j++]->number = i;
|
||||
}
|
||||
spin_unlock(&table_lock);
|
||||
mutex_unlock(&table_lock);
|
||||
return serial;
|
||||
}
|
||||
spin_unlock(&table_lock);
|
||||
mutex_unlock(&table_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -172,9 +172,9 @@ static void destroy_serial(struct kref *kref)
|
|||
|
||||
void usb_serial_put(struct usb_serial *serial)
|
||||
{
|
||||
spin_lock(&table_lock);
|
||||
mutex_lock(&table_lock);
|
||||
kref_put(&serial->kref, destroy_serial);
|
||||
spin_unlock(&table_lock);
|
||||
mutex_unlock(&table_lock);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -1129,7 +1129,6 @@ static int __init usb_serial_init(void)
|
|||
return -ENOMEM;
|
||||
|
||||
/* Initialize our global data */
|
||||
spin_lock_init(&table_lock);
|
||||
for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
|
||||
serial_table[i] = NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue