diff options
| author | Ian Abbott <abbotti@mev.co.uk> | 2025-04-15 13:39:01 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-05-02 07:44:39 +0200 |
| commit | 4e386645bc01db2d6f7593e0b539366064e72c25 (patch) | |
| tree | 62970a2ced59369097bee2be39800e3c8202f763 | |
| parent | a1166e98d80ccb2af4b4fb3bb30041ffc4e8fffc (diff) | |
| download | linux-4e386645bc01db2d6f7593e0b539366064e72c25.tar.gz linux-4e386645bc01db2d6f7593e0b539366064e72c25.tar.bz2 linux-4e386645bc01db2d6f7593e0b539366064e72c25.zip | |
comedi: jr3_pci: Fix synchronous deletion of timer
commit 44d9b3f584c59a606b521e7274e658d5b866c699 upstream.
When `jr3_pci_detach()` is called during device removal, it calls
`timer_delete_sync()` to stop the timer, but the timer expiry function
always reschedules the timer, so the synchronization is ineffective.
Call `timer_shutdown_sync()` instead. It does not matter that the timer
expiry function pointer is cleared, because the device is being removed.
Fixes: 07b509e6584a5 ("Staging: comedi: add jr3_pci driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://lore.kernel.org/r/20250415123901.13483-1-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/comedi/drivers/jr3_pci.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/comedi/drivers/jr3_pci.c b/drivers/comedi/drivers/jr3_pci.c index f963080dd61f..8ef13f5baf07 100644 --- a/drivers/comedi/drivers/jr3_pci.c +++ b/drivers/comedi/drivers/jr3_pci.c @@ -88,6 +88,7 @@ struct jr3_pci_poll_delay { struct jr3_pci_dev_private { struct timer_list timer; struct comedi_device *dev; + bool timer_enable; }; union jr3_pci_single_range { @@ -597,10 +598,11 @@ static void jr3_pci_poll_dev(struct timer_list *t) delay = sub_delay.max; } } + if (devpriv->timer_enable) { + devpriv->timer.expires = jiffies + msecs_to_jiffies(delay); + add_timer(&devpriv->timer); + } spin_unlock_irqrestore(&dev->spinlock, flags); - - devpriv->timer.expires = jiffies + msecs_to_jiffies(delay); - add_timer(&devpriv->timer); } static struct jr3_pci_subdev_private * @@ -749,6 +751,7 @@ static int jr3_pci_auto_attach(struct comedi_device *dev, devpriv->dev = dev; timer_setup(&devpriv->timer, jr3_pci_poll_dev, 0); devpriv->timer.expires = jiffies + msecs_to_jiffies(1000); + devpriv->timer_enable = true; add_timer(&devpriv->timer); return 0; @@ -758,8 +761,12 @@ static void jr3_pci_detach(struct comedi_device *dev) { struct jr3_pci_dev_private *devpriv = dev->private; - if (devpriv) - del_timer_sync(&devpriv->timer); + if (devpriv) { + spin_lock_bh(&dev->spinlock); + devpriv->timer_enable = false; + spin_unlock_bh(&dev->spinlock); + timer_delete_sync(&devpriv->timer); + } comedi_pci_detach(dev); } |
