Re: [PATCH v2 13/23] counter: Provide alternative counter registration functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

On Tue, Dec 28, 2021 at 06:00:17PM +0000, Jonathan Cameron wrote:
> On Mon, 27 Dec 2021 10:45:16 +0100
> Uwe Kleine-König         <u.kleine-koenig@xxxxxxxxxxxxxx> wrote:
> 
> > +struct counter_device_allochelper {
> > +	struct counter_device counter;
> > +	unsigned long privdata[];
> Nice to keep this opaque. We danced around how to do this in IIO for
> a while and never got to a solution we all liked.  Slight disadvantage
> is this might matter in hot paths where the compiler doesn't have visibility
> to know it can very cheaply access the privdata.
> 
> I guess that can be looked at if anyone ever measures it as an important
> element (they probably never will!)

*nod*

> > +};
> > +
> >  static void counter_device_release(struct device *dev)
> >  {
> >  	struct counter_device *const counter =
> > @@ -31,6 +37,9 @@ static void counter_device_release(struct device *dev)
> >  
> >  	counter_chrdev_remove(counter);
> >  	ida_free(&counter_ida, dev->id);
> > +
> > +	if (!counter->legacy_device)
> > +		kfree(container_of(counter, struct counter_device_allochelper, counter));
> >  }
> >  
> >  static struct device_type counter_device_type = {
> > @@ -53,7 +62,14 @@ static dev_t counter_devt;
> >   */
> >  void *counter_priv(const struct counter_device *const counter)
> >  {
> > -	return counter->priv;
> > +	if (counter->legacy_device) {
> > +		return counter->priv;
> > +	} else {
> > +		struct counter_device_allochelper *ch =
> > +			container_of(counter, struct counter_device_allochelper, counter);
> > +
> > +		return &ch->privdata;
> > +	}
> >  }
> >  EXPORT_SYMBOL_GPL(counter_priv);
> >  
> > @@ -74,6 +90,8 @@ int counter_register(struct counter_device *const counter)
> >  	int id;
> >  	int err;
> >  
> > +	counter->legacy_device = true;
> > +
> >  	/* Acquire unique ID */
> >  	id = ida_alloc(&counter_ida, GFP_KERNEL);
> >  	if (id < 0)
> > @@ -114,6 +132,100 @@ int counter_register(struct counter_device *const counter)
> >  }
> >  EXPORT_SYMBOL_GPL(counter_register);
> >  
> > +/**
> > + * counter_alloc - allocate a counter_device
> > + * @sizeof_priv: size of the driver private data
> > + *
> > + * This is part one of counter registration. The structure is allocated
> > + * dynamically to ensure the right lifetime for the embedded struct device.
> > + *
> > + * If this succeeds, call counter_put() to get rid of the counter_device again.
> > + */
> > +struct counter_device *counter_alloc(size_t sizeof_priv)
> > +{
> > +	struct counter_device_allochelper *ch;
> > +	struct counter_device *counter;
> > +	struct device *dev;
> > +	int id, err;
> > +
> > +	ch = kzalloc(sizeof(*ch) + sizeof_priv, GFP_KERNEL);
> > +	if (!ch) {
> > +		err = -ENOMEM;
> > +		goto err_alloc_ch;
> > +	}
> > +
> > +	counter = &ch->counter;
> > +	dev = &counter->dev;
> > +
> > +	/* Acquire unique ID */
> > +	err = ida_alloc(&counter_ida, GFP_KERNEL);
> > +	if (err < 0) {
> > +		goto err_ida_alloc;
> > +	}
> > +	dev->id = err;
> > +
> > +	err = counter_chrdev_add(counter);
> 
> Should think about renaming  counter_chrdev_add() given it
> does init and allocation stuff but no adding.

This is orthogonal to this series though. So I won't address this in the
context of the lifetime fixes here.

> Personal inclination here would be to keep the elements in here
> in the same order as in counter_register() where it doesn't matter
> in the interests of slightly easier comparison of the code.

I reordered a bit because counter_register fails to undo ida_alloc() in
the error path. However I might have missed that some initialisation has
to be done before calling counter_chrdev_add().

Will check in detail for v3.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux