Thread (33 messages) 33 messages, 6 authors, 2010-09-21

Re: [BUG] object: is not initialized, yet kobject_put() is being called

From: Jiri Kosina <hidden>
Date: 2010-08-12 12:58:04
Also in: lkml
Subsystem: hid core layer, the rest, usb hid/hidbp drivers (usb keyboards, mice, remote controls, ...) · Maintainers: Jiri Kosina, Benjamin Tissoires, Linus Torvalds

On Thu, 12 Aug 2010, Jiri Kosina wrote:
quoted
quoted
quoted
quoted
quoted
quoted
Guys, could you please send me your .config with which you are 
experiencing the problem, so that I can try to reproduce it with it?
Attached.
So I had to add support for HW of mine (SATA_VIA, PATA_VIA, disabled the 
radeon firmware stuff, and, most importantly, enabled UHCI, which is what 
is on machine I am using now for testing), and disconnect-connect cycle 
works nicely:

usb 3-2: USB disconnect, address 3
usb 3-2: new low speed USB device using uhci_hcd and address 4
input: mouse USB mouse with wheel as /devices/pci0000:00/0000:00:10.1/usb3/3-2/3-2:1.0/input/input6
generic-usb 0003:05B8:3091.0004: input,hidraw0: USB HID v1.10 Mouse [mouse USB mouse with wheel] on usb-0000:00:10.1-2/input0
input: mouse USB mouse with wheel as /devices/pci0000:00/0000:00:10.1/usb3/3-2/3-2:1.1/input/input7
generic-usb 0003:05B8:3091.0005: input,hidraw1: USB HID v1.10 Keyboard [mouse USB mouse with wheel] on usb-0000:00:10.1-2/input1

so still no BUG from kobject refcounting, and the hidraw numbers are the 
same. The major difference seems to be that I am using UHCI and you have 
your HID devices connected through OHCI, is that correct?
Correct. And I should add that it very easy to reproduce here; just
disconnecting the usb receiver triggers the WARNING.
Disabling USB_HIDDEV in my .config solves the problem (there is no
WARNING anymore when disconnecting the receiver).
Reverting bd25f4dd6972755579d0ea50d1a5ace2e9b00d1a with USB_HIDDEV
enabled also solves the problem. So there must be a bug in that patch:

commit bd25f4dd6972755579d0ea50d1a5ace2e9b00d1a
Author: Arnd Bergmann [off-list ref]
Date:   Sun Jul 11 15:34:05 2010 +0200

    HID: hiddev: use usb_find_interface, get rid of BKL
    
    This removes the private hiddev_table in the usbhid
    driver and changes it to use usb_find_interface
    instead.
    
    The advantage is that we can avoid the race between
    usb_register_dev and usb_open and no longer need the
    big kernel lock.
    
    This doesn't introduce race condition -- the intf pointer could be
    invalidated only in hiddev_disconnect() through usb_deregister_dev(),
    but that will block on minor_rwsem and not actually remove the device
    until usb_open().
    
    Signed-off-by: Arnd Bergmann [off-list ref]
    Cc: Jiri Kosina [off-list ref]
    Cc: "Greg Kroah-Hartman" [off-list ref]
    Signed-off-by: Jiri Kosina [off-list ref]
Thanks, I had my suspicion about this commit (that's why I asked to you 
verify with CONFIG_USB_HIDDEV turned off as well).

Adding Arnd to CC and will look into it myself as well soon.

Arnd, the complete thread can be found at 
http://lkml.org/lkml/2010/8/10/280
Could please those of you, who are able to reproduce the problem, verify 
whether the patch below (completely untested) makes everything behave 
again? Thanks.



 drivers/hid/usbhid/hiddev.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 254a003..0dcb79a 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -266,13 +266,15 @@ static int hiddev_open(struct inode *inode, struct file *file)
 {
 	struct hiddev_list *list;
 	struct usb_interface *intf;
+	struct hid_device *hid;
 	struct hiddev *hiddev;
 	int res;
 
 	intf = usb_find_interface(&hiddev_driver, iminor(inode));
 	if (!intf)
 		return -ENODEV;
-	hiddev = usb_get_intfdata(intf);
+	hid = usb_get_intfdata(intf);
+	hiddev = hid->hiddev;
 
 	if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
 		return -ENOMEM;
@@ -888,7 +890,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
 	hid->hiddev = hiddev;
 	hiddev->hid = hid;
 	hiddev->exist = 1;
-	usb_set_intfdata(usbhid->intf, usbhid);
 	retval = usb_register_dev(usbhid->intf, &hiddev_class);
 	if (retval) {
 		err_hid("Not able to get a minor for this device.");

-- 
Jiri Kosina
SUSE Labs, Novell Inc.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help