Am Donnerstag, 15. September 2011, 08:51:16 schrieb Greg KH:
Within usb_register_dev() there is a call to device_create(usb_class->class, &intf->dev, MKDEV(USB_MAJOR, minor), class_driver, "%s", temp). Within device_create() there is a call to device_create_vargs() which returns ENODEV (19)
struct device * device_create_vargs(class, parent, devt, drvdata, fmt, vargs)
The callstack then looks like usb_register_dev() device_create() device_create_vargs() <-- returns ENODEV in case of the race condition
This is the default error return of device_create_vargs(). Do you know which error case happens?
I am now wondering if my observations and thoughts are reasonable. Assuming that there is indeed such a race I would like to know if the following trivial patch is the correct approach?
This code depends on serialization static int init_usb_class(void) { int result = 0; if (usb_class != NULL) { kref_get(&usb_class->kref); goto exit; } usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL); if (!usb_class) { result = -ENOMEM; goto exit; } Very strage things could happen if you are preempted at the wrong time here. We probably should create usb_class much earlier. But after that it boils down to kref_get() which mustn't need locking.
Care to refresh it against the 3.0 kernel tree, and provide the proper Signed-off-by: line and cc: it to the linux-usb@vger.kernel.org mailing list and me, and we can take it from there?
But you also want to extend the lock down to device_create(). It should be possible to create two devices with a different major:minor at the same time. As far as locking is needed it should be provided by the driver core, not usbcore. So this approach seems wrong. Please take this to the list. Regards Oliver -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-kernel+help@opensuse.org