[PATCH 12/12] staging: comedi: comedi_pci: free_irq() in comedi_pci_disable()

H Hartley Sweeten hartleys at visionengravers.com
Thu Apr 18 20:39:43 UTC 2013


On Thursday, April 18, 2013 10:44 AM, Ian Abbott wrote:
> On 2013/04/18 04:51 PM, H Hartley Sweeten wrote:
>> On Thursday, April 18, 2013 5:06 AM, Ian Abbott wrote:
>>> On 2013-04-17 19:20, H Hartley Sweeten wrote:
>>>> All the PCI comedi drivers call comedi_pci_disable() either directly
>>>> or as part of their (*detach). Move the free_irq() into comedi_pci_disable()
>>>> so that the drivers don't have to deal with it.
>>>>
>>>> For drivers that then only call comedi_pci_disable() in their
>>>> private (*detach), remove the private function and use the helper
>>>> directly for the (*detach).
>>>>
>>>> For aesthetic reasons, tidy up the (*detach) in the icp_multi, ni_6527,
>>>> and ni_65xx drivers.
>>>>
>>>> In the rtd520 driver, the write to the PLX_INTRCS_REG register to disable
>>>> the interrupts is not needed. The previous call to rtd_reset() already
>>>> cleared the register.
>>>>
>>>> Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
>>>> Cc: Ian Abbott <abbotti at mev.co.uk>
>>>> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
>>>
>>> There is potential for this being unsafe for some drivers, particularly 
>>> for those interrupt handlers that don't check dev->attached as a 
>>> precaution before doing anything else, but instead read some ioremapped 
>>> register to check whether it needs to do anything.  PCI devices used 
>>> shared IRQs so their interrupt handlers can be called even when the 
>>> device is not interrupting.
>> 
>> But, the unsafe condition probably already exists. This patch shouldn't
>> change anything other than the point where the irq is released.
>> 
>> The PCI drivers should be disabling interrupts in their (*detach) and doing
>> any other driver specific cleanup before comedi_pci_disable() is called.
>
> You're missing the point that the interrupt handler will still be called
> even if the driver has stopped the PCI device generating interrupts,
> because the IRQ is (potentially) shared with other PCI devices, so the
> ordering of calls to free_irq() and freeing of things used by the
> interrupt handler matters unless the interrupt handler is careful not to
> access things that might have been freed.

I didn't miss the point, I think I just didn't think about it as deeply as you
have.

I was assuming that the core would only call the (*detach) if the device
was not processing a command. And interrupts are only generated by
the board if a command is being executed.

do_devconfig_ioctl() has this:

		if (is_device_busy(dev))
			return -EBUSY;

before calling comedi_device_detach().

I did overlook the dev->attached issue in the PCI interrupt functions
to make sure the board is actually attached and "could" be the source
of the interrupt.

>> Maybe a (*reset) callback should be added to the comedi_driver? I
>> think I saw a comment in one of the drivers about it.
>
> Certainly any driver that sets up the (*cmd) callback for a subdevice
> should also set up the (*cancel) callback, as asynchronous command
> support is the main use of interrupts.  The (*cancel) should disable any
> interrupt sources used by the asynchronous command.  Some of the drivers
> set (*cmd) without setting (*cancel) and I consider them broken.  Comedi
> should probably refuse to set up asynchronous command support for those.

I agree. Any comedi driver that supports commands should provide a
(*do_cmd), (*do_cmdtest), and (*cancel) function for the subdevice.

But, the (*cancel) is subdevice specific. I think a board level (*reset) function
might be a good idea. Many of the drivers actually have a function that does
this. It's just a matter of tying them into the comedi_driver.

>>> The only ones below that seem to suffer from the above problem are 
>>> cb_pcidas64.c, icp_multi.c, and ni6527.c.  Just checking dev->attached 
>>> and returning early before using anything that might have already been 
>>> freed would be enough to solve the problem for those drivers.
>> 
>> Since PCI interrupts are shared, all the comedi PCI drivers should probably
>> have the dev->attached check in their interrupt functions. But, that should
>> be a separate patch. Again, I don't think this patch makes the PCI drivers 
>> any worse than they already are.
>
> It does for the particular drivers I mentioned.

OK.

>>> amplc_pci224.c's interrupt handler also reads an interrupt status 
>>> register at the start, but since it isn't ioremapped, it shouldn't matter.
>>>
>>> ni_labpc.c's interrupt handler doesn't have the problem, although it 
>>> does print a nasty message if !dev->attached and returns IRQ_HANDLED 
>>> instead of IRQ_NONE.  I just noticed it in passing, so am leaving this 
>>> here as a reminder.
>>>
>>> I recommend skipping this patch until the problematic drivers are sorted 
>>> out.
>> 
>> If you still feel this patch should be skipped please let me know. If
>> possible I would like to get this series in before Greg closes his tree.
>
> I still think it should be skipped for now.  We certainly don't want it
> remaining broken at the time Greg closes his tree.

OK. I'll drop this piece until after the next merge window closes and Greg
reopens the staging tree.

I assume you are ok with the free_irq() patch for the legacy drivers. I'll
leave that patch in the series I will repost later today.

Thanks,
Hartley




More information about the devel mailing list