2006-02-04 08:13:43

by Artem Bityutskiy

[permalink] [raw]
Subject: [QUESTION/sysfs] strange refcounting

Hello folks,

I'm writing a simple device driver and want to expose some of its
attributes to userspace via sysfs.

As usually, I have main device description structure "struct
mydev_info". I've embedded a struct device object there. What I do is:

struct mydev_info mydev
{
struct device *dev;
... bla bla bla ...
} mydev;


mydev->dev=kzalloc(sizeof(struct device), GFP_KERNEL);
mydev->dev->bus_id = "mydev";
mydev->dev->release = mydev_release;
err = device_register(&mydev->dev);

Then, I see /sys/devices/mydev/ in sysfs. I open
pre-defined /sys/devices/mydev/power/state in userspace and don't close it.

Then I run lsmod, and see zero refcount to my module. Well, I run rmmod
mymod, module is unloaded.

Then I close /sys/devices/mydev/power/state, and enjoy segfault.

I thought sysfs subsystem have to increase module refcount when one
opens its sysfs files. Well, there is a release function, but it is also
unloaded with the module.

May be there is a problem because of I have mydev->dev->parent == NULL,
mydev->dev->bus == NULL, mydev->dev->driver == NULL? But I really don't
have any bus, any parent and I don't want to introduce struct
device_driver ...

Kernel is 2.6.15.1.

Although this is my first meet with sysfs, this looks strange.

Thanks.

--
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.


2006-02-04 12:04:47

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [QUESTION/sysfs] strange refcounting

Artem B. Bityutskiy wrote:
> Then, I see /sys/devices/mydev/ in sysfs. I open
> pre-defined /sys/devices/mydev/power/state in userspace and don't close it.
>
> Then I run lsmod, and see zero refcount to my module. Well, I run rmmod
> mymod, module is unloaded.
>
> Then I close /sys/devices/mydev/power/state, and enjoy segfault.
>
I actually forgot to formulate my question: why module's refcount is not
increased when somebody opens a sysfs file which belongs to this module?
How to withstan to an unexpected module unload?

Thanks.

--
Best Regards,
Artem B. Bityutskiy,
St.-Petersburg, Russia.

2006-02-04 13:33:40

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [QUESTION/sysfs] strange refcounting

Artem B. Bityutskiy wrote:
> I actually forgot to formulate my question: why module's refcount is not
> increased when somebody opens a sysfs file which belongs to this module?
> How to withstan to an unexpected module unload?
>
> Thanks.
I see this code drivers/base/core.c, device_add().

if (dev->driver)
dev->uevent_attr.attr.owner = dev->driver->owner;

I assume it is expected that I must have a driver structure. But I
don't. Why do I have to?

--
Best Regards,
Artem B. Bityutskiy,
St.-Petersburg, Russia.

2006-02-06 09:58:04

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [QUESTION/sysfs] strange refcounting

As &struct device structure has no @owner field, and corresponding
functions rely on the @owner field at &struct device_driver, I conclude
that I cannot use &struct device objects without bus and device driver
objects, just by design.

On the other hand, 'device_register()' accepts &struct device objects
with NULL-filled @bus and @driver fields perfectly fine, does not
complain, does not return any error, and I even see corresponding
entries at /sys/devices/. But there is a refcounting problem described
at my first mail.

This is obviously a confusing discrepancy. Sysfs has to either reject
bus-less and driver-less &struct device objects or deal with them
correctly. The latter is impossible due to lack of an @owner field in
&struct device.

In connection with this, I have a question. There is a whole bunch of
drivers which do not directly relate to hardware devices, but which
still want to expose their parameters via sysfs. For example, this could
be a filesystem, LVM, a compression layer on top of a file system of a
block device, whatever. These are "virtual" devices and they are not
physically connected to any bus. How should they deal with sysfs?

I see there is the "class" stuff in sysfs, but it seems that it is far
not as flexible as the "device, driver, and bus" stuff, because I cannot
create many nested layers within classes. I can create a class, which
goes to /sys/class/, and devices within this class, which go to
/sys/class/myclass/mydev/. But I cannot create a class, devices within
that class, and daughter devices within them, like:

/sys/class/myclass/
|-- mydev1/
| -- doughterdev1/
| -- doughterdev1/
| -- ...
|-- mydev2/
|-- mydev3/
|-- ...

Please, comment this.

Thanks.

--
Best Regards,
Artem B. Bityutskiy,
St.-Petersburg, Russia.

2006-02-06 17:20:32

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [QUESTION/sysfs] strange refcounting

Artem B. Bityutskiy wrote:
> In connection with this, I have a question. There is a whole bunch of
> drivers which do not directly relate to hardware devices, but which
> still want to expose their parameters via sysfs. For example, this could
> be a filesystem, LVM, a compression layer on top of a file system of a
> block device, whatever. These are "virtual" devices and they are not
> physically connected to any bus. How should they deal with sysfs?

For some reasons I missed Greg's reply to my first message and was
talking to myself. To end this thread, the answer to this question is:
"include/sysfs.h".

--
Best Regards,
Artem B. Bityutskiy,
St.-Petersburg, Russia.