Re: rmmod uhci_hcd -> BUG: atomic counter underflow

Alan Stern <[email protected]>
Newsgroups gmane.linux.usb.devel,gmane.linux.kernel
Message-ID <[email protected]>
On Mon, 12 Mar 2007, Jiri Slaby wrote:

> Jiri Slaby napsal(a):
> > Alan Stern napsal(a):
> >> On Mon, 12 Mar 2007, Jiri Slaby wrote:
> >>> After rmmoding of uhci_hcd on fresh booted 2.6.21-rc3-mm2 I got this:
> >>>
> >>> BUG: atomic counter underflow at:
> > [...]
> >>>   [<c01db754>] kobject_put+0x14/0x16
> >>>   [<c01db8a3>] kobject_unregister+0x22/0x25
> >>>   [<c024c987>] bus_remove_driver+0x75/0x82
> >>>   [<c024d3b8>] driver_unregister+0xb/0x18
> >>>   [<c01e7020>] pci_unregister_driver+0x13/0x73
> >>>   [<f88dbbd9>] uhci_hcd_cleanup+0xd/0x2d [uhci_hcd]
> > [...]
> >> Would it be possible for you to add the atomic counter underflow check 
> >> to 2.6.21-rc3 and see if the problem still occurs?  If it doesn't, 
> >> that's a good indication the USB stack isn't guilty -- the bus 
> >> registration code hasn't changed for several kernel releases.
> > 
> > Yes.
> 
> I can confirm, that this issue went upstream and is currently present there.

I found the problem, but I don't know how to fix it.  Hopefully Greg or 
Rusty will know.

There are two bugs in kernel/module.c:module_remove_driver(), right at the 
end of the routine:

	/*
	 * Undo the additional reference we added in module_add_driver()
	 * via kset_find_obj()
	 */
	if (drv->mod_name)
		kobject_put(&drv->kobj);

It's supposed to undo this code in module_add_driver():

	if (mod)
		mk = &mod->mkobj;
	else if (drv->mod_name) {
		struct kobject *mkobj;

		/* Lookup built-in module entry in /sys/modules */
		mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
		if (mkobj)
			mk = container_of(mkobj, struct module_kobject, kobj);
	}

The first bug is in the condition of the "if (drv->mod_name)" statement.  
If "mod" isn't NULL then kset_find_obj() doesn't get called, but the "if" 
can succeed anyway.  (Maybe this isn't a real bug -- it would depend on 
all the callers; I don't know.)

The second bug is the argument to kobject_put().  drv->kobj is _not_ the 
kobject whose refcount gets incremented by the kset_find_obj() call.  
That's why the BUG occurred; the kobject's refcount was getting 
decremented without being incremented first.

Alan Stern


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.