From 5b864f8db0bd33216895f3fe0bb1ec245c596c8e Mon Sep 17 00:00:00 2001 From: Danish Khateeb Date: Tue, 29 Sep 2026 07:49:37 -0500 Subject: [PATCH] pps: generators: wake up PPS_GEN_FETCHEVENT readers on unregister A reader sleeping in PPS_GEN_FETCHEVENT waits for the next event, but no event comes after pps_gen_unregister_source(), so the reader sleeps until it gets a signal. A PPS_GEN_FETCHEVENT issued after the unregister sleeps the same way. Wake up the readers on unregister, and make PPS_GEN_FETCHEVENT fail with -ENODEV once the generator is gone, like the other ioctls. The wait checks info without info_lock, so clear it with WRITE_ONCE(). Fixes: 86b525bed275 ("drivers pps: add PPS generators support") Suggested-by: Rodolfo Giometti Assisted-by: LLM Signed-off-by: Danish Khateeb Acked-by: Rodolfo Giometti Link: https://patch.msgid.link/20260929124937.51114-5-danishkhateeb03@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/pps/generators/pps_gen.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/pps/generators/pps_gen.c b/drivers/pps/generators/pps_gen.c index 452cc12a96f2..474e17c36458 100644 --- a/drivers/pps/generators/pps_gen.c +++ b/drivers/pps/generators/pps_gen.c @@ -103,11 +103,14 @@ static long pps_gen_cdev_ioctl(struct file *file, dev_dbg(&pps_gen->dev, "PPS_GEN_FETCHEVENT\n"); ret = wait_event_interruptible(pps_gen->queue, - ev != pps_gen->last_ev); + ev != pps_gen->last_ev || + !READ_ONCE(pps_gen->info)); if (ret == -ERESTARTSYS) { dev_dbg(&pps_gen->dev, "pending signal caught\n"); return -EINTR; } + if (!READ_ONCE(pps_gen->info)) + return -ENODEV; spin_lock_irq(&pps_gen->lock); info.sequence = pps_gen->sequence; @@ -238,9 +241,12 @@ static void pps_gen_unregister_cdev(struct pps_gen_device *pps_gen) pps_gen->info->enable(pps_gen, false); pps_gen->enabled = false; } - pps_gen->info = NULL; + WRITE_ONCE(pps_gen->info, NULL); } + /* Wake up the readers in PPS_GEN_FETCHEVENT, they fail now as well */ + wake_up_interruptible_all(&pps_gen->queue); + put_device(&pps_gen->dev); }