It took me a while to figure out how this locking worked, and I think this patch, or something like it, may help other people figure it out quicker, assuming it's right. http://marc.theaimsgroup.com/?l=linux-net&m=94968855718670&w=2 seems to imply that it's right. These are against test10-pre5. --- drivers/net/Space.c.orig Wed Oct 25 11:34:49 2000 +++ drivers/net/Space.c Wed Oct 25 11:48:34 2000 @@ -702,6 +702,25 @@ struct net_device loopback_dev = {"lo", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, loopback_init}; +/* + * The @dev_base list is protected by @dev_base_lock and the rtln + * semaphore. + * + * Pure readers hold dev_base_lock for reading. + * + * Writers must hold the rtnl semaphore while they loop through the + * dev_base list, and hold dev_base_lock for writing when they do the + * actual updates. This allows pure readers to access the list even + * while a writer is preparing to update it. + * + * To put it another way, dev_base_lock is held for writing only to + * protect against pure readers; the rtnl semaphore provides the + * protection against other writers. + * + * See, for example usages, register_netdevice() and + * unregister_netdevice(), which must be called with the rtnl + * semaphore held. + */ struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; --- net/core/dev.c.orig Wed Oct 25 11:34:57 2000 +++ net/core/dev.c Wed Oct 25 11:52:12 2000 @@ -2231,9 +2231,9 @@ /** * dev_new_index - allocate an ifindex * - * Returns a suitable unique value for a new device interface number. - * The caller must hold the rtnl semaphore to be sure it remains - * unique. + * Returns a suitable unique value for a new device interface + * number. The caller must hold the rtnl semaphore or the + * dev_base_lock to be sure it remains unique. */ int dev_new_index(void) @@ -2258,6 +2258,10 @@ * chain. 0 is returned on success. A negative errno code is returned * on a failure to set up the device, or if the name is a duplicate. * + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. You may want + * register_netdev() instead of this. + * * BUGS: * The locking appears insufficient to guarantee two parallel registers * will not get the same name. @@ -2405,6 +2409,10 @@ * This function shuts down a device interface and removes it * from the kernel tables. On success 0 is returned, on a failure * a negative errno code is returned. + * + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. You may want + * unregister_netdev() instead of this. */ int unregister_netdevice(struct net_device *dev) @@ -2538,6 +2546,11 @@ extern void dv_init(void); #endif /* CONFIG_NET_DIVERT */ + +/* + * Callers must hold the rtnl semaphore. See the comment at the + * end of Space.c for details about the locking. + */ int __init net_dev_init(void) { struct net_device *dev, **dp; -- Paul Cassella pwc@sgi.com - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org