Driver core: race between remove device and register driver

From: Alan Stern
Date: Mon Feb 20 2006 - 15:37:40 EST


Pat, James, and Greg:

There's an obvious race in the driver core when a device is removed at the
same time a new driver is registered. The core has to guarantee that the
device isn't somehow bound to the driver when the device_del() call
returns.

Right now we handle it by making bus_remove_device() call klist_remove(),
which doesn't return until the device's entry is completely gone from the
bus's klist of all registered devices. This works okay, but it's contrary
to the principles of the reference-counting approach. I'm sure that James
at least would much prefer to have the code avoid waiting for the
klist_node's refcount to go to 0.

The problem is that we have no way of telling when a struct device has
been unregistered other than to check whether it is still on the bus's
klist. Adding a single "is_registered" bitflag to struct device would
solve the problem and allow us to get rid of one of the few callers of
klist_remove(). The other callers can be removed in similar ways,
allowing us eventually to get rid of klist_remove() altogether -- and
thereby also get rid of the struct completion embedded in every
klist_node.

Does this seems like a good way to go?

By the way, there's also the converse race: adding a new device while
unregistering a driver. This race is also solved by waiting, but here it
doesn't matter so much. Unregistering a driver necessarily involves
waiting, since the driver's code can't be unloaded until no more threads
are executing it.

Alan Stern

P.S.: James, klist_del() and klist_next() both call klist_dec_and_del()
(which does a kref_put()) while holding a spinlock. This may be a good
place to use execute_in_process_context().

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/