From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Extend struct lineevent_data with a notifier block and use it to receive
the GPIO device unregister event. Upon reception, wake up the wait queue
so that the user-space be forced out of poll() and need to go into a new
system call which will then fail due to the chip being gone.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/gpio/gpiolib-cdev.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 0b21ea04fa52..bb6a011f7857 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -1830,9 +1830,15 @@ struct lineevent_state {
int irq;
wait_queue_head_t wait;
DECLARE_KFIFO(events, struct gpioevent_data, 16);
+ struct notifier_block nb;
u64 timestamp;
};
+static struct lineevent_state *to_lineevent_state(struct notifier_block *nb)
+{
+ return container_of(nb, struct lineevent_state, nb);
+}
+
#define GPIOEVENT_REQUEST_VALID_FLAGS \
(GPIOEVENT_REQUEST_RISING_EDGE | \
GPIOEVENT_REQUEST_FALLING_EDGE)
@@ -1947,6 +1953,9 @@ static ssize_t lineevent_read(struct file *file, char __user *buf,
static void lineevent_free(struct lineevent_state *le)
{
+ if (le->nb.notifier_call)
+ blocking_notifier_chain_unregister(&le->gdev->notifier,
+ &le->nb);
if (le->irq)
free_irq(le->irq, le);
if (le->desc)
@@ -2084,6 +2093,22 @@ static irqreturn_t lineevent_irq_handler(int irq, void *p)
return IRQ_WAKE_THREAD;
}
+static int lineevent_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct lineevent_state *le = to_lineevent_state(nb);
+
+ switch (action) {
+ case GPIO_CDEV_UNREGISTERED:
+ wake_up_poll(&le->wait, EPOLLIN | EPOLLERR);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+
static int lineevent_create(struct gpio_device *gdev, void __user *ip)
{
struct gpioevent_request eventreq;
@@ -2175,6 +2200,11 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
INIT_KFIFO(le->events);
init_waitqueue_head(&le->wait);
+ le->nb.notifier_call = lineevent_notify;
+ ret = blocking_notifier_chain_register(&gdev->notifier, &le->nb);
+ if (ret)
+ goto out_free_le;
+
/* Request a thread to read the events */
ret = request_threaded_irq(irq,
lineevent_irq_handler,
--
2.39.2
Hi Bartosz,
kernel test robot noticed the following build warnings:
[auto build test WARNING on brgl/gpio/for-next]
[also build test WARNING on linus/master v6.5-rc6 next-20230817]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Bartosz-Golaszewski/gpio-cdev-ignore-notifications-other-than-line-status-changes/20230816-202408
base: https://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git gpio/for-next
patch link: https://lore.kernel.org/r/20230816122032.15548-6-brgl%40bgdev.pl
patch subject: [PATCH 5/5] gpio: cdev: wake up lineevent poll() on device unbind
config: x86_64-randconfig-x016-20230817 (https://download.01.org/0day-ci/archive/20230817/202308171736.864z7YNW-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce: (https://download.01.org/0day-ci/archive/20230817/202308171736.864z7YNW-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308171736.864z7YNW-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/gpio/gpiolib-cdev.c:1835: warning: Function parameter or member 'nb' not described in 'lineevent_state'
vim +1835 drivers/gpio/gpiolib-cdev.c
925ca36913fc7d Kent Gibson 2020-06-16 1807
925ca36913fc7d Kent Gibson 2020-06-16 1808 /*
925ca36913fc7d Kent Gibson 2020-06-16 1809 * GPIO line event management
925ca36913fc7d Kent Gibson 2020-06-16 1810 */
925ca36913fc7d Kent Gibson 2020-06-16 1811
925ca36913fc7d Kent Gibson 2020-06-16 1812 /**
925ca36913fc7d Kent Gibson 2020-06-16 1813 * struct lineevent_state - contains the state of a userspace event
925ca36913fc7d Kent Gibson 2020-06-16 1814 * @gdev: the GPIO device the event pertains to
925ca36913fc7d Kent Gibson 2020-06-16 1815 * @label: consumer label used to tag descriptors
925ca36913fc7d Kent Gibson 2020-06-16 1816 * @desc: the GPIO descriptor held by this event
925ca36913fc7d Kent Gibson 2020-06-16 1817 * @eflags: the event flags this line was requested with
925ca36913fc7d Kent Gibson 2020-06-16 1818 * @irq: the interrupt that trigger in response to events on this GPIO
925ca36913fc7d Kent Gibson 2020-06-16 1819 * @wait: wait queue that handles blocking reads of events
925ca36913fc7d Kent Gibson 2020-06-16 1820 * @events: KFIFO for the GPIO events
925ca36913fc7d Kent Gibson 2020-06-16 1821 * @timestamp: cache for the timestamp storing it between hardirq
925ca36913fc7d Kent Gibson 2020-06-16 1822 * and IRQ thread, used to bring the timestamp close to the actual
925ca36913fc7d Kent Gibson 2020-06-16 1823 * event
925ca36913fc7d Kent Gibson 2020-06-16 1824 */
925ca36913fc7d Kent Gibson 2020-06-16 1825 struct lineevent_state {
925ca36913fc7d Kent Gibson 2020-06-16 1826 struct gpio_device *gdev;
925ca36913fc7d Kent Gibson 2020-06-16 1827 const char *label;
925ca36913fc7d Kent Gibson 2020-06-16 1828 struct gpio_desc *desc;
925ca36913fc7d Kent Gibson 2020-06-16 1829 u32 eflags;
925ca36913fc7d Kent Gibson 2020-06-16 1830 int irq;
925ca36913fc7d Kent Gibson 2020-06-16 1831 wait_queue_head_t wait;
925ca36913fc7d Kent Gibson 2020-06-16 1832 DECLARE_KFIFO(events, struct gpioevent_data, 16);
35c059f377b978 Bartosz Golaszewski 2023-08-16 1833 struct notifier_block nb;
925ca36913fc7d Kent Gibson 2020-06-16 1834 u64 timestamp;
925ca36913fc7d Kent Gibson 2020-06-16 @1835 };
925ca36913fc7d Kent Gibson 2020-06-16 1836
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.