lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 23 Nov 2020 14:22:49 +0200
From:   Alexandru Ardelean <ardeleanalex@...il.com>
To:     Jonathan Cameron <jic23@...nel.org>
Cc:     Alexandru Ardelean <alexandru.ardelean@...log.com>,
        linux-iio <linux-iio@...r.kernel.org>,
        LKML <linux-kernel@...r.kernel.org>,
        Lars-Peter Clausen <lars@...afoo.de>
Subject: Re: [RFC PATCH 06/12] iio: buffer: re-route scan_elements via it's kobj_type

On Sat, Nov 21, 2020 at 8:34 PM Jonathan Cameron <jic23@...nel.org> wrote:
>
> On Tue, 17 Nov 2020 18:23:34 +0200
> Alexandru Ardelean <alexandru.ardelean@...log.com> wrote:
>
> > The scan_elements attributes are solely located inside
> > 'industrialio-buffer-sysfs.c'. In order to support more than one buffer per
> > IIO device, we need to expand scan_elements attributes directly to IIO
> > buffer object, and not the IIO device.
> >
> > This also requires that a new 'iio_buffer_attr' type be added which is
> > mostly a copy of 'iio_dev_attr', but this expands to an IIO buffer object.
> >
> > The 'iio_dev_attr' type could have been re-used here, but managing 'device'
> > objects is a bit more tricky (than it looks at first). A 'device' object
> > needs to be initialized & managed and we only need to the 'kobj' to expand
> > from the 'bufferX' directory back to an IIO buffer.
> > kobjects are simpler to manage.
> >
> > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@...log.com>
> One trivial thing inline but otherwise looks fine to me.
>
> Jonathan
>
> > ---
> >  drivers/iio/iio_core.h            |   5 +
> >  drivers/iio/industrialio-buffer.c | 162 +++++++++++++++++++++++-------
> >  drivers/iio/industrialio-core.c   |   1 -
> >  3 files changed, 129 insertions(+), 39 deletions(-)
> >
> > diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
> > index fced02cadcc3..43d44ec92781 100644
> > --- a/drivers/iio/iio_core.h
> > +++ b/drivers/iio/iio_core.h
> > @@ -31,6 +31,11 @@ void iio_device_ioctl_handler_register(struct iio_dev *indio_dev,
> >                                      struct iio_ioctl_handler *h);
> >  void iio_device_ioctl_handler_unregister(struct iio_ioctl_handler *h);
> >
> > +int iio_attr_init(struct attribute *attr,
> > +               const char *postfix,
> > +               struct iio_chan_spec const *chan,
> > +               enum iio_shared_by shared_by);
> > +
> >  int __iio_add_chan_devattr(const char *postfix,
> >                          struct iio_chan_spec const *chan,
> >                          ssize_t (*func)(struct device *dev,
> > diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
> > index 62c8bd6b67cd..445709ef245c 100644
> > --- a/drivers/iio/industrialio-buffer.c
> > +++ b/drivers/iio/industrialio-buffer.c
> > @@ -26,6 +26,26 @@
> >  #include <linux/iio/buffer.h>
> >  #include <linux/iio/buffer_impl.h>
> >
> > +/**
> > + * struct iio_buf_attr - iio buffer specific attribute
> > + * @attr:    underlying attribute
> > + * @address: associated register address
> > + * @l:               list head for maintaining list of dynamically created attrs
> > + * @c:               specification for the underlying channel
> > + * @show:    sysfs show hook for this attribute
> > + * @store:   sysfs store hook for this attribute
> > + */
> > +struct iio_buf_attr {
> > +     struct attribute attr;
> > +     u64 address;
> > +     struct list_head l;
> > +     struct iio_chan_spec const *c;
> > +     ssize_t (*show)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
> > +                     char *buf);
> > +     ssize_t (*store)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
> > +                      const char *buf, size_t count);
> > +};
> > +
> >  static const char * const iio_endian_prefix[] = {
> >       [IIO_BE] = "be",
> >       [IIO_LE] = "le",
> > @@ -210,18 +230,17 @@ void iio_buffer_init(struct iio_buffer *buffer)
> >  }
> >  EXPORT_SYMBOL(iio_buffer_init);
> >
> > -static ssize_t iio_show_scan_index(struct device *dev,
> > -                                struct device_attribute *attr,
> > +static ssize_t iio_show_scan_index(struct iio_buffer *buffer,
> > +                                struct iio_buf_attr *attr,
> >                                  char *buf)
> >  {
> > -     return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index);
> > +     return sprintf(buf, "%u\n", attr->c->scan_index);
> >  }
> >
> > -static ssize_t iio_show_fixed_type(struct device *dev,
> > -                                struct device_attribute *attr,
> > +static ssize_t iio_show_fixed_type(struct iio_buffer *buffer,
> > +                                struct iio_buf_attr *this_attr,
> >                                  char *buf)
> >  {
> > -     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> >       u8 type = this_attr->c->scan_type.endianness;
> >
> >       if (type == IIO_CPU) {
> > @@ -248,17 +267,14 @@ static ssize_t iio_show_fixed_type(struct device *dev,
> >                      this_attr->c->scan_type.shift);
> >  }
> >
> > -static ssize_t iio_scan_el_show(struct device *dev,
> > -                             struct device_attribute *attr,
> > +static ssize_t iio_scan_el_show(struct iio_buffer *buffer,
> > +                             struct iio_buf_attr *attr,
> >                               char *buf)
> >  {
> >       int ret;
> > -     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > -     struct iio_buffer *buffer = indio_dev->buffer;
> >
> >       /* Ensure ret is 0 or 1. */
> > -     ret = !!test_bit(to_iio_dev_attr(attr)->address,
> > -                    buffer->scan_mask);
> > +     ret = !!test_bit(attr->address, buffer->scan_mask);
> >
> >       return sprintf(buf, "%d\n", ret);
> >  }
> > @@ -359,16 +375,14 @@ static int iio_scan_mask_query(struct iio_dev *indio_dev,
> >       return !!test_bit(bit, buffer->scan_mask);
> >  };
> >
> > -static ssize_t iio_scan_el_store(struct device *dev,
> > -                              struct device_attribute *attr,
> > +static ssize_t iio_scan_el_store(struct iio_buffer *buffer,
> > +                              struct iio_buf_attr *this_attr,
> >                                const char *buf,
> >                                size_t len)
> >  {
> > +     struct iio_dev *indio_dev = buffer->indio_dev;
> >       int ret;
> >       bool state;
> > -     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > -     struct iio_buffer *buffer = indio_dev->buffer;
> > -     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> >
> >       ret = strtobool(buf, &state);
> >       if (ret < 0)
> > @@ -398,24 +412,20 @@ static ssize_t iio_scan_el_store(struct device *dev,
> >
> >  }
> >
> > -static ssize_t iio_scan_el_ts_show(struct device *dev,
> > -                                struct device_attribute *attr,
> > +static ssize_t iio_scan_el_ts_show(struct iio_buffer *buffer,
> > +                                struct iio_buf_attr *attr,
> >                                  char *buf)
> >  {
> > -     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > -     struct iio_buffer *buffer = indio_dev->buffer;
> > -
> >       return sprintf(buf, "%d\n", buffer->scan_timestamp);
> >  }
> >
> > -static ssize_t iio_scan_el_ts_store(struct device *dev,
> > -                                 struct device_attribute *attr,
> > +static ssize_t iio_scan_el_ts_store(struct iio_buffer *buffer,
> > +                                 struct iio_buf_attr *attr,
> >                                   const char *buf,
> >                                   size_t len)
> >  {
> > +     struct iio_dev *indio_dev = buffer->indio_dev;
> >       int ret;
> > -     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > -     struct iio_buffer *buffer = indio_dev->buffer;
> >       bool state;
> >
> >       ret = strtobool(buf, &state);
> > @@ -434,13 +444,88 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
> >       return ret ? ret : len;
> >  }
> >
> > +static int __iio_add_chan_bufattr(const char *postfix,
> > +                               struct iio_chan_spec const *chan,
> > +                               ssize_t (*readfunc)(struct iio_buffer *buffer,
> > +                                                   struct iio_buf_attr *attr,
> > +                                                   char *buf),
> > +                               ssize_t (*writefunc)(struct iio_buffer *buffer,
> > +                                                    struct iio_buf_attr *attr,
> > +                                                    const char *buf,
> > +                                                    size_t len),
> > +                               u64 mask,
> > +                               enum iio_shared_by shared_by,
> > +                               struct device *dev,
> > +                               struct list_head *attr_list)
> > +{
> > +     struct iio_buf_attr *iio_attr, *t;
> > +     int ret;
> > +
> > +     iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL);
> > +     if (iio_attr == NULL)
> > +             return -ENOMEM;
> > +
> > +     ret = iio_attr_init(&iio_attr->attr, postfix, chan, shared_by);
> > +     if (ret)
> > +             goto error_iio_buf_attr_free;
> > +
> > +     iio_attr->c = chan;
> > +     iio_attr->address = mask;
> > +     list_for_each_entry(t, attr_list, l) {
> > +             if (strcmp(t->attr.name, iio_attr->attr.name) == 0) {
> > +                     if (shared_by == IIO_SEPARATE)
> > +                             dev_err(dev, "tried to double register : %s\n",
> > +                                     t->attr.name);
> > +                     ret = -EBUSY;
> > +                     goto error_iio_buf_attr_deinit;
> > +             }
> > +     }
> > +     list_add(&iio_attr->l, attr_list);
> > +
> > +     if (readfunc) {
> > +             iio_attr->attr.mode |= S_IRUGO;
> > +             iio_attr->show = readfunc;
> > +     }
> > +
> > +     if (writefunc) {
> > +             iio_attr->attr.mode |= S_IWUSR;
> > +             iio_attr->store = writefunc;
> > +     }
> > +
> > +     return 0;
> > +
> > +error_iio_buf_attr_deinit:
> > +     kfree(iio_attr->attr.name);
> > +error_iio_buf_attr_free:
> > +     kfree(iio_attr);
> > +     return ret;
> > +}
> > +
> > +/**
> > + * iio_free_chan_bufattr_list() - Free a list of IIO buffer attributes
> > + * @attr_list: List of IIO buffer attributes
> > + *
> > + * This function frees the memory allocated for each of the IIO buffer
> > + * attributes in the list.
> > + */
> > +static void iio_free_chan_bufattr_list(struct list_head *attr_list)
> > +{
> > +     struct iio_buf_attr *p, *n;
> > +
> > +     list_for_each_entry_safe(p, n, attr_list, l) {
> > +             kfree(p->attr.name);
>
> Trivial but ordering in here seems a bit odd.  Take it off
> list before doing the name free makes more sense to me.

Ack.

>
> > +             list_del(&p->l);
> > +             kfree(p);
> > +     }
> > +}
> > +
> >  static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
> >                                       struct iio_buffer *buffer,
> >                                       const struct iio_chan_spec *chan)
> >  {
> >       int ret, attrcount = 0;
> >
> > -     ret = __iio_add_chan_devattr("index",
> > +     ret = __iio_add_chan_bufattr("index",
> >                                    chan,
> >                                    &iio_show_scan_index,
> >                                    NULL,
> > @@ -451,7 +536,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
> >       if (ret)
> >               return ret;
> >       attrcount++;
> > -     ret = __iio_add_chan_devattr("type",
> > +     ret = __iio_add_chan_bufattr("type",
> >                                    chan,
> >                                    &iio_show_fixed_type,
> >                                    NULL,
> > @@ -463,7 +548,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
> >               return ret;
> >       attrcount++;
> >       if (chan->type != IIO_TIMESTAMP)
> > -             ret = __iio_add_chan_devattr("en",
> > +             ret = __iio_add_chan_bufattr("en",
> >                                            chan,
> >                                            &iio_scan_el_show,
> >                                            &iio_scan_el_store,
> > @@ -472,7 +557,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
> >                                            &indio_dev->dev,
> >                                            &buffer->scan_el_dev_attr_list);
> >       else
> > -             ret = __iio_add_chan_devattr("en",
> > +             ret = __iio_add_chan_bufattr("en",
> >                                            chan,
> >                                            &iio_scan_el_ts_show,
> >                                            &iio_scan_el_ts_store,
> > @@ -1251,6 +1336,7 @@ static struct attribute *iio_buffer_attrs[] = {
> >  };
> >
> >  #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
> > +#define to_iio_buf_attr(_attr) container_of(_attr, struct iio_buf_attr, attr)
> >
> >  static ssize_t iio_buffer_dir_attr_show(struct kobject *kobj,
> >                                       struct attribute *attr,
> > @@ -1291,9 +1377,9 @@ static ssize_t iio_scan_el_dir_attr_show(struct kobject *kobj,
> >                                        char *buf)
> >  {
> >       struct iio_buffer *buffer = container_of(kobj, struct iio_buffer, scan_el_dir);
> > -     struct device_attribute *dattr = to_dev_attr(attr);
> > +     struct iio_buf_attr *battr = to_iio_buf_attr(attr);
> >
> > -     return dattr->show(&buffer->indio_dev->dev, dattr, buf);
> > +     return battr->show(buffer, battr, buf);
> >  }
> >
> >  static ssize_t iio_scan_el_dir_attr_store(struct kobject *kobj,
> > @@ -1302,9 +1388,9 @@ static ssize_t iio_scan_el_dir_attr_store(struct kobject *kobj,
> >                                         size_t len)
> >  {
> >       struct iio_buffer *buffer = container_of(kobj, struct iio_buffer, scan_el_dir);
> > -     struct device_attribute *dattr = to_dev_attr(attr);
> > +     struct iio_buf_attr *battr = to_iio_buf_attr(attr);
> >
> > -     return dattr->store(&buffer->indio_dev->dev, dattr, buf, len);
> > +     return battr->store(buffer, battr, buf, len);
> >  }
> >
> >  static const struct sysfs_ops iio_scan_el_dir_sysfs_ops = {
> > @@ -1349,7 +1435,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
> >                                            struct iio_dev *indio_dev,
> >                                            unsigned int idx)
> >  {
> > -     struct iio_dev_attr *p;
> > +     struct iio_buf_attr *p;
> >       struct attribute **attr;
> >       int ret, i, attrn, attrcount;
> >       const struct iio_chan_spec *channels;
> > @@ -1430,7 +1516,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
> >
> >       attrn = 0;
> >       list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
> > -             buffer->scan_el_attrs[attrn++] = &p->dev_attr.attr;
> > +             buffer->scan_el_attrs[attrn++] = &p->attr;
> >
> >       ret = iio_sysfs_add_attrs(&buffer->scan_el_dir, buffer->scan_el_attrs);
> >       if (ret)
> > @@ -1446,7 +1532,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
> >       bitmap_free(buffer->scan_mask);
> >  error_cleanup_dynamic:
> >       iio_sysfs_del_attrs(&buffer->buffer_dir, buffer->buffer_attrs);
> > -     iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
> > +     iio_free_chan_bufattr_list(&buffer->scan_el_dev_attr_list);
> >  error_buffer_kobject_put:
> >       kobject_put(&buffer->buffer_dir);
> >  error_buffer_free_attrs:
> > @@ -1507,7 +1593,7 @@ static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer)
> >       kfree(buffer->scan_el_attrs);
> >       bitmap_free(buffer->scan_mask);
> >       iio_sysfs_del_attrs(&buffer->buffer_dir, buffer->buffer_attrs);
> > -     iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
> > +     iio_free_chan_bufattr_list(&buffer->scan_el_dev_attr_list);
> >       kobject_put(&buffer->buffer_dir);
> >       kfree(buffer->buffer_attrs);
> >  }
> > diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> > index e9aa84f5b05a..28830e87e8cb 100644
> > --- a/drivers/iio/industrialio-core.c
> > +++ b/drivers/iio/industrialio-core.c
> > @@ -972,7 +972,6 @@ static ssize_t iio_write_channel_info(struct device *dev,
> >       return len;
> >  }
> >
> > -static
> >  int iio_attr_init(struct attribute *attr,
> >                 const char *postfix,
> >                 struct iio_chan_spec const *chan,
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ