Procházet zdrojové kódy

USB: Remove BKL from poll()

Replace BKL with usbfs_mutex to protect a global counter
and a per file data structure

Signed-off-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Oliver Neukum před 15 roky
rodič
revize
554f76962d
1 změnil soubory, kde provedl 9 přidání a 19 odebrání
  1. 9 19
      drivers/usb/core/devices.c

+ 9 - 19
drivers/usb/core/devices.c

@@ -118,6 +118,7 @@ static const char *format_endpt =
  */
 
 static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
+/* guarded by usbfs_mutex */
 static unsigned int conndiscevcnt;
 
 /* this struct stores the poll state for <mountpoint>/devices pollers */
@@ -156,7 +157,9 @@ static const struct class_info clas_info[] =
 
 void usbfs_conn_disc_event(void)
 {
+	mutex_lock(&usbfs_mutex);
 	conndiscevcnt++;
+	mutex_unlock(&usbfs_mutex);
 	wake_up(&deviceconndiscwq);
 }
 
@@ -629,42 +632,29 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
 static unsigned int usb_device_poll(struct file *file,
 				    struct poll_table_struct *wait)
 {
-	struct usb_device_status *st = file->private_data;
+	struct usb_device_status *st;
 	unsigned int mask = 0;
 
-	lock_kernel();
+	mutex_lock(&usbfs_mutex);
+	st = file->private_data;
 	if (!st) {
 		st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
-
-		/* we may have dropped BKL -
-		 * need to check for having lost the race */
-		if (file->private_data) {
-			kfree(st);
-			st = file->private_data;
-			goto lost_race;
-		}
-		/* we haven't lost - check for allocation failure now */
 		if (!st) {
-			unlock_kernel();
+			mutex_unlock(&usbfs_mutex);
 			return POLLIN;
 		}
 
-		/*
-		 * need to prevent the module from being unloaded, since
-		 * proc_unregister does not call the release method and
-		 * we would have a memory leak
-		 */
 		st->lastev = conndiscevcnt;
 		file->private_data = st;
 		mask = POLLIN;
 	}
-lost_race:
+
 	if (file->f_mode & FMODE_READ)
 		poll_wait(file, &deviceconndiscwq, wait);
 	if (st->lastev != conndiscevcnt)
 		mask |= POLLIN;
 	st->lastev = conndiscevcnt;
-	unlock_kernel();
+	mutex_unlock(&usbfs_mutex);
 	return mask;
 }