Am Mittwoch, 11. Dezember 2002 02:15 schrieb Greg KH:
> On Wed, Dec 11, 2002 at 01:26:53AM +0100, Oliver Neukum wrote:
> > > > Doesn't sound easy to me.
> > >
> > > Ick, that's even messier :(
> > > In looking at your match, I think we only need the last bit, right?
> > > The other stuff was formatting cleanup, and code reorg from a first
> > > glance.
> >
> > The first hunk is editor junk, true, sorry.
> > The rest is essential. That code is shifted around for a reason.
> > The copy_to_user() must come after the tree has been walked,
> > because BKL may be dropped that way.
> > The downside of this is that memory consumption increases
> > drastically. Worst case is ~900K with GFP_ATOMIC.
>
> That's not acceptable :(
You are right.
Here's a version that changes usb_bus_list_lock to kill the race.
It survived compilation and boot. Would somebody test this ?
Regards
Oliver
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
[EMAIL PROTECTED], 2002-12-11 23:34:25+01:00, [EMAIL PROTECTED]
- fix race between reding devices and unplugging
devices.c | 7 ++++---
hcd.c | 12 ++++++------
usb.c | 6 ++++++
3 files changed, 16 insertions(+), 9 deletions(-)
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c Wed Dec 11 23:36:05 2002
+++ b/drivers/usb/core/devices.c Wed Dec 11 23:36:05 2002
@@ -60,6 +60,7 @@
#include <asm/uaccess.h>
#include "hcd.h"
+extern struct rw_semaphore usb_topology_lock;
#define MAX_TOPO_LEVEL 6
@@ -569,19 +570,19 @@
return -EFAULT;
/* enumerate busses */
- down (&usb_bus_list_lock);
+ down_write (&usb_topology_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) {
- up(&usb_bus_list_lock);
+ up_write(&usb_topology_lock);
return ret;
}
total_written += ret;
}
- up (&usb_bus_list_lock);
+ up_write (&usb_topology_lock);
return total_written;
}
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c Wed Dec 11 23:36:05 2002
+++ b/drivers/usb/core/hcd.c Wed Dec 11 23:36:05 2002
@@ -90,8 +90,8 @@
static struct usb_busmap busmap;
/* used when updating list of hcds */
-DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_list_lock);
+DECLARE_RWSEM (usb_topology_lock); /* exported only for usbfs */
+EXPORT_SYMBOL_GPL (usb_topology_lock);
/* used when updating hcd data */
static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
@@ -651,7 +651,7 @@
{
int busnum;
- down (&usb_bus_list_lock);
+ down_write (&usb_topology_lock);
busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
if (busnum < USB_MAXBUS) {
set_bit (busnum, busmap.busmap);
@@ -663,7 +663,7 @@
/* Add it to the list of buses */
list_add (&bus->bus_list, &usb_bus_list);
- up (&usb_bus_list_lock);
+ up_write (&usb_topology_lock);
usbfs_add_bus (bus);
@@ -688,9 +688,9 @@
* controller code, as well as having it call this when cleaning
* itself up
*/
- down (&usb_bus_list_lock);
+ down_write (&usb_topology_lock);
list_del (&bus->bus_list);
- up (&usb_bus_list_lock);
+ up_write (&usb_topology_lock);
usbfs_remove_bus (bus);
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c Wed Dec 11 23:36:05 2002
+++ b/drivers/usb/core/usb.c Wed Dec 11 23:36:05 2002
@@ -49,6 +49,8 @@
extern int usb_major_init(void);
extern void usb_major_cleanup(void);
+extern struct rw_semaphore usb_topology_lock;
+
int nousb; /* Disable USB when built into kernel image */
/* Not honored on modular build */
@@ -92,7 +94,9 @@
if (id) {
dbg ("%s - got id", __FUNCTION__);
down (&driver->serialize);
+ down_read (&usb_topology_lock);
error = driver->probe (intf, id);
+ up_read (&usb_topology_lock);
up (&driver->serialize);
}
if (!error)
@@ -128,6 +132,7 @@
* the holder of the lock guards against
* module unload */
down(&driver->serialize);
+ down_read(&usb_topology_lock);
if (intf->driver && intf->driver->disconnect)
intf->driver->disconnect(intf);
@@ -136,6 +141,7 @@
if (intf->driver)
usb_driver_release_interface(driver, intf);
+ up_read(&usb_topology_lock);
up(&driver->serialize);
module_put(driver->owner);
===================================================================
This BitKeeper patch contains the following changesets:
1.1101
## Wrapped with gzip_uu ##
begin 664 bkpatch1451
M'XL(`-6]]ST``ZU6;8_:.!#^C'_%2)6J7BO`+W%>.'':ZX+:U6VUB&W5.ZD2
M<A(#$2&.G*3L2OGQYSATM]S!LM"%H`GVX\EXYGG&>05?"JD''94FWZ5&K^"C
M*DKS5V8JD[VE6LLTR:J[GM(+,SE5RDSVF^%^NZ(?KKJEEK+H5RGER&`FHHR6
M8*:*08?TV,-(>9_+06<Z_O#E^L\I0L,A7"Y%MI"WLH3A$(6KB[B2:6^EE5@V
MCZL?IFN*,2&$<LRX2WA-?<:<FK@XC,UM3+U@'KH!6FBYN&B71VJ]NYP22@@V
M7X?4A+@^0R,@O68(,.T3<Q&@;,"<`>7O,!E@#.W^+O9E`MXQZ&+T'GX]Z$L4
M01?FR1UH$4D(9;F1,@,MXR1;0"R_)Y$L0&0Q5%F>5HN%&49_`>$^)VCRF$+4
M/?&#$!88_;%G"[%N-FX*6H3-KQ<];L7!`7%KRASNU)%+I>0^)5X4"H;Y4PG;
M\1DI+1\=V\I0RBCW:TJX1TU,>4.8I\):1O%VM:EI8[@3U"SPB%<S)Q"A(QPA
MB,.D[YP6UJ/CG\+BQF]P-%7;6NU)%_4HJ85O<N5Q4S>!0W\>G!;7CO.?8W,I
MQ<RJZ?":_?+ZA=C_*[5CX6)F+LZQ227GCF>U1^FN\NB`^\]1G@-=]H+*R[7*
MI8941:M&<'.E82-2>U\N)32MS<BMS?(-=/7&7D8^DR<2?H88KUP*!,F[4NH,
MBE)740EZ,ROD6N1+XQS,4V:ERE6J%O>S)MS?T<BHQ2RZ:DTG5IMLMM%)*>'-
MZ__!?[/XH,4WIM/I5'F+/P0WZFG@UCR`#SC?2T&K\N/T.Z'+'*7>3F/!),`,
M!S7FS,%MR_>\\WCGOFS'7U=E)5*0=U%:%8G*0,TMV2"R[@K8).6R'=GRT="P
M[8_':&@S<`X%N<G(B13\AJX"RXZ6?5J*^``_K@)N<89&3Z$(PP]<;G`'8?Z6
MDX=!>QEI&WS#R)<\8XZ2<N=8^4%*[CA;4GK^V9QT7Y"36E9%6^6P*F9I4I0V
ME89X[0EXC'AVEV<0;Q0P0[R&2!2-QI?F]7`\FWZ]'7^"-WOJVNF_-;+)E2YE
M#"I+[VW3-L!Y`6_[:/SWY&;Z>7;[SZ?W-]>S#Y/KO4[0R.6VN;7F&;W3=5V+
MM^98,QRY`;%H:Y[CW:3`XMES6NV/5^IH*:-54:V'4G#I.3A$_P(=\ALQSPL`
!````
`
end
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel