On Thu, Mar 19, 2015 at 02:49:21PM +0000, Brian Russell wrote:
> On 19/03/15 14:23, Greg Kroah-Hartman wrote:
> > On Thu, Mar 19, 2015 at 02:11:19PM +0000, Brian Russell wrote:
> >>    if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
> >> -          ret = devm_request_irq(idev->dev, info->irq, uio_interrupt,
> >> +          ret = request_irq(info->irq, uio_interrupt,
> >>                              info->irq_flags, info->name, idev);
> > 
> > Why move this away from the device lifecycle?
> > 
> 
> I ran into a problem here: after device unregister the parent module (in my 
> case igb_uio in DPDK) can call pci_disable_msi. From the PCI MSI how to:
> 
> "Before calling this function, a device driver must always call free_irq()
> on any interrupt for which it previously called request_irq().
> Failure to do so results in a BUG_ON(), leaving the device with
> MSI enabled and thus leaking its vector."
> 
> So I need the free_irq, but the device may still have open fds and therefore 
> be around a bit longer waiting for them to be released.

Note, please wrap your email lines...

Anyway, ok, that makes sense.  But put in a big comment in here about
this so that someone doesn't try to convert it to devm_* in the future.

Can you do this in a separate patch first as well?  Burrying it in a
pointer conversion patch isn't good.

> >>  err_device_create:
> >>    uio_free_minor(idev);
> >>    return ret;
> >> @@ -871,8 +892,10 @@ void uio_unregister_device(struct uio_info *info)
> >>  
> >>    uio_dev_del_attributes(idev);
> >>  
> >> -  device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
> >> +  device_unregister(&idev->dev);
> >> +  free_irq(idev->info->irq, idev);
> >>  
> >> +  idev->info = NULL;
> > 
> > Why?  If this was the last reference count, isn't idev now gone?  You
> > shouldn't be referencing it anymore.
> > 
> 
> No, the device can be unregistered here but still have outstanding refcount 
> because of open fds. The count can get to zero in the release function, so 
> idev could still be around after this but the calling module could free info.

Yes, but if it was the last reference, idev is now a stale pointer and
you just derefrenced it.  Twice.  :(

Once you do a put, and don't have a reference on the pointer, you can't
touch that pointer again.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to