Re: [PATCH v3] drivers/base/core: refcount kobject and bus on device attribute read / store

From: Greg KH
Date: Wed Jun 23 2021 - 12:28:10 EST


On Wed, Jun 23, 2021 at 09:14:34AM -0700, Luis Chamberlain wrote:
> On Wed, Jun 23, 2021 at 10:32:53AM +0200, Greg KH wrote:
> > On Tue, Jun 22, 2021 at 05:36:30PM -0700, Luis Chamberlain wrote:
> > > diff --git a/drivers/base/core.c b/drivers/base/core.c
> > > index 4a8bf8cda52b..f69aa040b56d 100644
> > > --- a/drivers/base/core.c
> > > +++ b/drivers/base/core.c
> > > @@ -2042,28 +2042,56 @@ EXPORT_SYMBOL(dev_driver_string);
> > > static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
> > > char *buf)
> > > {
> > > - struct device_attribute *dev_attr = to_dev_attr(attr);
> > > - struct device *dev = kobj_to_dev(kobj);
> > > + struct device_attribute *dev_attr;
> > > + struct device *dev;
> > > + struct bus_type *bus = NULL;
> > > ssize_t ret = -EIO;
> > >
> > > + dev = get_device(kobj_to_dev(kobj));
> > > + if (dev->bus) {
> >
> > No need to test for this, right?
>
> dev_uevent() checks for dev->bus, so I thought that was a clear
> indication this isn't always set.
>
> >
> > > + bus = bus_get(dev->bus);
> > > + if (!bus)
> > > + goto out;

The point is that even if dev->bus is NULL, then bus_get(NULL) is NULL.
That's the only way that bus_get() can return NULL, which means this
check too is not needed.

> > > if (dev_attr->show)
> > > ret = dev_attr->show(dev, dev_attr, buf);
> > > if (ret >= (ssize_t)PAGE_SIZE) {
> > > printk("dev_attr_show: %pS returned bad count\n",
> > > dev_attr->show);
> > > }
> > > +
> > > + bus_put(bus);
> >
> > You are incrementing the bus, which is nice, but I do not understand why
> > it is needed. What is causing the bus to go away _before_ the devices
> > are going away? Busses almost never are removed from the system, and if
> > they are, all devices associated with them are removed first. So I do
> > not think you need to increment anything with that here.
>
> You tell me. It was your suggestion as a replacement for the type
> specific lock, in the zram case, its a block device so I was using
> bdgrab().

I did? Sorry, I do not remember, but this is not a lock, nor does it
protect anything.

I'll respond to the rest later...

greg k-h