On 2/27/2018 7:20 AM, Jeff Guo wrote:
> udev could not detect remove and add event of device when hotplug in
> and out devices, that related with the fix about using pointer of
> rte_uio_pci_dev as dev_id instead of uio_device for irq device handler,
> that would result igb uio irq failure when kernel version after than 3.17.
> 
> The root cause is that the older version of Linux kernel don't expose the
> uio_device structure, only for the kernel version after than 3.17 use
> uio_device. so this patch correct it by use a macro to check before handle
> the pci interrupt.
> 
> Fixes: 6b9ed026a870 ("igb_uio: fix build with kernel <= 3.17")
> Signed-off-by: Jeff Guo <jia....@intel.com>
> ---
> v2->v1:
> use macro in compat.h to replace of version check in .c file, benifit for
> future backport and make more readable. 
> ---
>  lib/librte_eal/linuxapp/igb_uio/compat.h  |  4 ++++
>  lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 16 ++++++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/lib/librte_eal/linuxapp/igb_uio/compat.h 
> b/lib/librte_eal/linuxapp/igb_uio/compat.h
> index ce456d4..2c61190 100644
> --- a/lib/librte_eal/linuxapp/igb_uio/compat.h
> +++ b/lib/librte_eal/linuxapp/igb_uio/compat.h
> @@ -132,3 +132,7 @@ static bool pci_check_and_mask_intx(struct pci_dev *pdev)
>  #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
>  #define HAVE_PCI_MSI_MASK_IRQ 1
>  #endif
> +
> +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 17, 0)
> +#define HAVE_UIO_DEVICE_STRUCTURE 1
> +#endif
> diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c 
> b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
> index 4cae4dd..99018f4 100644
> --- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
> +++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
> @@ -192,8 +192,14 @@ igbuio_pci_irqcontrol(struct uio_info *info, s32 
> irq_state)
>  static irqreturn_t
>  igbuio_pci_irqhandler(int irq, void *dev_id)
>  {
> +#ifndef HAVE_UIO_DEVICE_STRUCTURE
>       struct rte_uio_pci_dev *udev = (struct rte_uio_pci_dev *)dev_id;
>       struct uio_info *info = &udev->info;
> +#else
> +     struct uio_device *idev = (struct uio_device *)dev_id;
> +     struct uio_info *info = idev->info;
> +     struct rte_uio_pci_dev *udev = info->priv;
> +#endif
>  
>       /* Legacy mode need to mask in hardware */
>       if (udev->mode == RTE_INTR_MODE_LEGACY &&
> @@ -279,9 +285,15 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev 
> *udev)
>       }
>  
>       if (udev->info.irq != UIO_IRQ_NONE)
> +#ifndef HAVE_UIO_DEVICE_STRUCTURE
>               err = request_irq(udev->info.irq, igbuio_pci_irqhandler,
>                                 udev->info.irq_flags, udev->info.name,
>                                 udev);
> +#else
> +             err = request_irq(udev->info.irq, igbuio_pci_irqhandler,
> +                               udev->info.irq_flags, udev->info.name,
> +                               udev->info.uio_dev);
> +#endif

Hi Jeff,

Can you please describe how this is solving the problem. Isn't only requirement
for dev_id to be unique? Why it differs to pass uio_dev instead of udev pointer?

>       dev_info(&udev->pdev->dev, "uio device registered with irq %ld\n",
>                udev->info.irq);
>  
> @@ -292,7 +304,11 @@ static void
>  igbuio_pci_disable_interrupts(struct rte_uio_pci_dev *udev)
>  {
>       if (udev->info.irq) {
> +#ifndef HAVE_UIO_DEVICE_STRUCTURE
>               free_irq(udev->info.irq, udev);
> +#else
> +             free_irq(udev->info.irq, udev->info.uio_dev);
> +#endif
>               udev->info.irq = 0;
>       }
>  
> 

Reply via email to