[PATCH v2 5/7] HID: sensor: custom: Serialize misc device reads

From: Srinivas Pandruvada

Date: Wed Nov 04 2026 - 17:07:27 EST


The misc device permits only one open file, but threads sharing that
file can still read concurrently. Serialize readers to preserve the
single-reader assumption of the FIFO while keeping removal independent
of a stalled user copy.

Fixes: 4a7de0519df5 ("HID: sensor: Custom and Generic sensor support")
Reported-by: Семён Марьясин <simeon@xxxxxxxxxxxxx>
Closes: https://lore.kernel.org/all/CAM2dg7ewfVJSP4rFyhkCB1Rmd1+X56sAg=eUdbPthG2xrLqwQQ@xxxxxxxxxxxxxx/
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>
---
drivers/hid/hid-sensor-custom.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c
index 2a3b502821c7..4f824cadd370 100644
--- a/drivers/hid/hid-sensor-custom.c
+++ b/drivers/hid/hid-sensor-custom.c
@@ -38,6 +38,7 @@ struct hid_sensor_custom_field {

struct hid_sensor_custom {
struct mutex mutex;
+ struct mutex read_mutex;
struct kref ref;
bool removed;
struct platform_device *pdev;
@@ -668,25 +669,39 @@ static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf,
if (count < sizeof(struct hid_sensor_sample))
return -EINVAL;

+ if (file->f_flags & O_NONBLOCK) {
+ if (!mutex_trylock(&sensor_inst->read_mutex))
+ return -EAGAIN;
+ } else {
+ ret = mutex_lock_interruptible(&sensor_inst->read_mutex);
+ if (ret)
+ return ret;
+ }
+
for (;;) {
- if (READ_ONCE(sensor_inst->removed))
- return -ENODEV;
+ if (READ_ONCE(sensor_inst->removed)) {
+ ret = -ENODEV;
+ break;
+ }

ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count,
&copied);
if (ret || copied)
break;

- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }

ret = wait_event_interruptible(sensor_inst->wait,
READ_ONCE(sensor_inst->removed) ||
!kfifo_is_empty(&sensor_inst->data_fifo));
if (ret)
- return ret;
+ break;
}

+ mutex_unlock(&sensor_inst->read_mutex);
if (ret)
return ret;

@@ -1014,6 +1029,7 @@ static int hid_sensor_custom_probe(struct platform_device *pdev)
sensor_inst->hsdev = hsdev;
sensor_inst->pdev = pdev;
mutex_init(&sensor_inst->mutex);
+ mutex_init(&sensor_inst->read_mutex);
kref_init(&sensor_inst->ref);
platform_set_drvdata(pdev, sensor_inst);

--
2.56.0