More fixes for bugs found by the Checker.
Semaphore's really aren't my thing. But I think these fixes (against 
2.4.19-pre10 and 2.5.21) in the error paths are OK. Please review and merge 
if appropriate.

Brad

----------  Forwarded Message  ----------

Subject: [CHECKER] 18 potential missing unlocks in 2.4.17
Date: Mon, 10 Jun 2002 13:54
From: Dawson Engler <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]

Hi All,
enclosed is an error log for a checker that warns when a lock/disable
was not paired with an unlock/enable.  These errors could be tricky,
and they only got a quick inspection, so treat the reports as potential
rather than guaranteed bugs.
<snip>
---------------------------------------------------------
[BUG]  doesn't seem to initialize for retry, so if nothing else will
 deadlock?
 /u2/engler/mc/oses/linux/2.4.17/drivers/usb/dabusb.c:608:dabusb_open:
 ERROR:A_B:604:608:Did not reverse 'down' [COUNTER=down:604] [fit=5]
 [fit_fn=10] [fn_ex=2] [fn_counter=1] [ex=926] [counter=148] [z =
 -13.2026997616315] [fn-z = -2.25170500701057] schedule_timeout (HZ / 2);
                if (signal_pending (current)) {
                        return -EAGAIN;
                }
Start --->
                down (&s->mutex);
        }
        if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
                err("set_interface failed");
Error --->
                return -EINVAL;
        }
        s->opened = 1;
        up (&s->mutex);
---------------------------------------------------------
<snip>
---------------------------------------------------------
[BUG] does return with lock held..
/u2/engler/mc/oses/linux/2.4.17/drivers/usb/devices.c:501:usb_device_read:
 ERROR:A_B:494:501:Did not reverse 'down' [COUNTER=down:494] [fit=5]
 [fit_fn=18] [fn_ex=1] [fn_counter=1] [ex=926] [counter=148] [z =
 -13.2026997616315] [fn-z = -2.91998558035372] return 0;
        if (!access_ok(VERIFY_WRITE, buf, nbytes))
                return -EFAULT;
        /* enumerate busses */
Start --->
        down (&usb_bus_list_lock);
        for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist =
 buslist->next) { /* print devices for this bus */
                bus = list_entry(buslist, struct usb_bus, bus_list);
                /* recurse through all children of the root hub */
                ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, 
bus,
 0, 0, 0); if (ret < 0)
Error --->
                        return ret;
                total_written += ret;
        }
        up (&usb_bus_list_lock);

-------------------------------------------------------

-- 
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.
diff -Naur -X dontdiff linux-2.4.19-pre10-clean/drivers/usb/dabusb.c linux-2.4.19-pre10-sembugs/drivers/usb/dabusb.c
--- linux-2.4.19-pre10-clean/drivers/usb/dabusb.c	Sat Dec 22 04:41:55 2001
+++ linux-2.4.19-pre10-sembugs/drivers/usb/dabusb.c	Mon Jun 10 20:49:16 2002
@@ -605,6 +605,7 @@
 	}
 	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
 		err("set_interface failed");
+		up(&s->mutex);
 		return -EINVAL;
 	}
 	s->opened = 1;
diff -Naur -X dontdiff linux-2.4.19-pre10-clean/drivers/usb/devices.c linux-2.4.19-pre10-sembugs/drivers/usb/devices.c
--- linux-2.4.19-pre10-clean/drivers/usb/devices.c	Mon Jun 10 15:51:06 2002
+++ linux-2.4.19-pre10-sembugs/drivers/usb/devices.c	Mon Jun 10 20:49:21 2002
@@ -573,8 +573,10 @@
 		bus = list_entry(buslist, struct usb_bus, bus_list);
 		/* recurse through all children of the root hub */
 		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
-		if (ret < 0)
+		if (ret < 0) {
+			up(&usb_bus_list_lock);
 			return ret;
+		}
 		total_written += ret;
 	}
 	up (&usb_bus_list_lock);
diff -Naur -X dontdiff linux-2.5.21/drivers/usb/core/devices.c linux-2.5.21-sembugs/drivers/usb/core/devices.c
--- linux-2.5.21/drivers/usb/core/devices.c	Sun Jun  9 15:29:30 2002
+++ linux-2.5.21-sembugs/drivers/usb/core/devices.c	Mon Jun 10 20:48:54 2002
@@ -574,8 +574,10 @@
 		bus = list_entry(buslist, struct usb_bus, bus_list);
 		/* recurse through all children of the root hub */
 		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
-		if (ret < 0)
+		if (ret < 0) {
+			up(&usb_bus_list_lock);
 			return ret;
+		}
 		total_written += ret;
 	}
 	up (&usb_bus_list_lock);
diff -Naur -X dontdiff linux-2.5.21/drivers/usb/media/dabusb.c linux-2.5.21-sembugs/drivers/usb/media/dabusb.c
--- linux-2.5.21/drivers/usb/media/dabusb.c	Sun Jun  9 15:30:30 2002
+++ linux-2.5.21-sembugs/drivers/usb/media/dabusb.c	Mon Jun 10 20:49:03 2002
@@ -609,6 +609,7 @@
 		down (&s->mutex);
 	}
 	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
+		up(&s->mutex);
 		err("set_interface failed");
 		return -EINVAL;
 	}

Reply via email to