2003-01-03 23:58:33

by Matt Domsch

[permalink] [raw]
Subject: kobject_init() sets kobj->subsys wrong?

Pat, I need your help tracking this one down... :-)

Your recent patch creating find_bus("scsi") always returns NULL. I see
that's because bus_subsys.list is empty. Now, why is it empty, when the
SCSI driver did a bus_register()? It comes down to the code in
kobject_add(), where struct subsystem *s = kobj->subsys == NULL, thus the
list_add_tail code never gets called in there.

The calls go something like this:

scsi_sysfs_register()
bus_register(&scsi_bus_type)
subsystem_register(scsi_bus_type->subsys)
subsystem_init()
kobject_init() sets kobj->subsys = subsys_get(kobj->subsys) which
seems wrong
kobject_register()
kobject_add() where kobject->subsys is NULL

Strange, but true, and it may be kobject_init() that's borked setting
kobj->subsys.

Please advise.

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions http://www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


2003-01-04 20:03:27

by Matt Domsch

[permalink] [raw]
Subject: Re: kobject_init() sets kobj->subsys wrong?

> Your recent patch creating find_bus("scsi") always returns NULL. I see
> that's because bus_subsys.list is empty.

In kobject_add(), with kobj->subsys = NULL, this kobject (embedded inside
struct subsystem embedded inside struct bus_type) never gets added to
either it's parent's list, nor to the (NULL) subsystem's list. It appears
that the object can be on either a parent's list or a subsystem's list,
but not both, by virtue of there being only one struct list_head entry in
struct kobject.

You're far more versed in how this should work than I. Some ideas...

1) in bus_register(), don't set bus->subsys.parent = &bus_subsys, instead
set bus->subsys.kobj.subsys = &bus_subsys. I did this, and now find_bus()
works as expected, but now the busses created don't have parents unless
they're specified prior to calling bus_register(), so this doesn't seem
quite right.

===== linux-2.5-edd-work/drivers/base/bus.c 1.26 vs edited =====
--- 1.26/drivers/base/bus.c Sun Dec 1 23:22:04 2002
+++ edited/linux-2.5-edd-work/drivers/base/bus.c Sat Jan 4 13:58:31 2003
@@ -495,7 +520,7 @@

down(&bus_sem);
strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
- bus->subsys.parent = &bus_subsys;
+ bus->subsys.kobj.subsys = &bus_subsys;
subsystem_register(&bus->subsys);

snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");


2) set both bus->subsys.parent and bus->subsys.kobj.subsys, but then fix
the test in kobject_add() to put the object on the subsystem's list if
possible, then fall back to the parent list otherwise. Again, doesn't
seem quite right.

3) Add another struct list_head to kobject to let it reside on both a
parent list and a subsystem list if either exist.

There are probably other options. Please advise.

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions http://www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


2003-01-04 20:16:23

by Patrick Mochel

[permalink] [raw]
Subject: Re: kobject_init() sets kobj->subsys wrong?


Hi Matt.


On Sat, 4 Jan 2003, Matt Domsch wrote:

> > Your recent patch creating find_bus("scsi") always returns NULL. I see
> > that's because bus_subsys.list is empty.
>
> In kobject_add(), with kobj->subsys = NULL, this kobject (embedded inside
> struct subsystem embedded inside struct bus_type) never gets added to
> either it's parent's list, nor to the (NULL) subsystem's list. It appears
> that the object can be on either a parent's list or a subsystem's list,
> but not both, by virtue of there being only one struct list_head entry in
> struct kobject.

Actually, the objects are always placed on their subsystem's list, never
their parent's. An object's parent is only used to determine the location
to insert the object. This gives the subsystem the ability to maintain an
ordered list of all objects registered with it, even when the objects
compose an arbitrarily deep hierarchy.

This is docuemented somewhere, but I'll be sure to add a comment to
kobject_add() explaining this.

> 1) in bus_register(), don't set bus->subsys.parent = &bus_subsys, instead
> set bus->subsys.kobj.subsys = &bus_subsys. I did this, and now find_bus()
> works as expected, but now the busses created don't have parents unless
> they're specified prior to calling bus_register(), so this doesn't seem
> quite right.

This is correct. Also in kobject_add(), orphan objects are adopted by
the subsystem they belong to.

-pat