[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241015-iio-read-avail-release-v3-1-ac3e08f25cb3@gmail.com>
Date: Tue, 15 Oct 2024 13:06:34 +0200
From: Matteo Martelli <matteomartelli3@...il.com>
To: Jonathan Cameron <jic23@...nel.org>,
Lars-Peter Clausen <lars@...afoo.de>,
Michael Hennerich <Michael.Hennerich@...log.com>,
Alisa-Dariana Roman <alisa.roman@...log.com>,
Christian Eggers <ceggers@...i.de>, Peter Rosin <peda@...ntia.se>,
Paul Cercueil <paul@...pouillou.net>, Sebastian Reichel <sre@...nel.org>
Cc: linux-iio@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-mips@...r.kernel.org, linux-pm@...r.kernel.org,
Matteo Martelli <matteomartelli3@...il.com>
Subject: [PATCH v3 1/5] iio: core: add read_avail_release_resource callback
to fix race
Some iio drivers currently share an available info buffer that might be
changed while iio core prints it to sysfs. To avoid the buffer
corruption, add a release callback to let iio drivers allocate a copy of
the available info buffer and later free it in the release callback.
Such control is kept in the driver logic so that some driver that needs
a big available info buffer might also perform some check to keep the
copied buffer around in case no race has occurred.
Signed-off-by: Matteo Martelli <matteomartelli3@...il.com>
---
drivers/iio/industrialio-core.c | 14 +++++++++++---
include/linux/iio/iio.h | 4 ++++
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 6a6568d4a2cb3a3f63381d5a6f25a2881b3ba2ed..4aea9de9f15a4d70f9d02fb3d47df49eef8c8423 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -859,12 +859,20 @@ static ssize_t iio_read_channel_info_avail(struct device *dev,
return ret;
switch (ret) {
case IIO_AVAIL_LIST:
- return iio_format_avail_list(buf, vals, type, length);
+ ret = iio_format_avail_list(buf, vals, type, length);
+ break;
case IIO_AVAIL_RANGE:
- return iio_format_avail_range(buf, vals, type);
+ ret = iio_format_avail_range(buf, vals, type);
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
+
+ if (indio_dev->info->read_avail_release_resource)
+ indio_dev->info->read_avail_release_resource(
+ indio_dev, this_attr->c, vals, this_attr->address);
+
+ return ret;
}
/**
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 3a9b57187a958d6e65c699cf7814df5bac9a99e3..03bb765670a0c5f0129fc677c3a4a4cb38f4dad1 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -491,6 +491,10 @@ struct iio_info {
int *length,
long mask);
+ void (*read_avail_release_resource)(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int *vals, long mask);
+
int (*write_raw)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
--
2.47.0
Powered by blists - more mailing lists