Re: [PATCH v2 0/4] Fix device_lock deadlock on two probe() paths

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2023-08-18 at 15:15 -0300, Jason Gunthorpe wrote:
> On Fri, Aug 18, 2023 at 02:00:21PM -0400, Eric Farman wrote:
> 
> > Well, I'm trying to chase down an apparent deadlock in the mdev
> > cases
> > that is introduced with the commit [1] blamed by these fixes. Seems
> > that when iommu_group_{add|remove}_device gets called out of vfio
> > (for
> > example, vfio-ap or -ccw), the device lock is already held so
> > attempting to get it again isn't going to go well.
> 
> Oh, yes. Thankfully due to all the recent cleanup there is now only
> one caller of iommu_group_add_device() - VFIO and only on the
> vfio_register_emulated_iommu_dev() path.
> 
> All those callers are under mdev probe callbacks so they all must
> have
> the device lock held. iommu_group_remove_device is the same. Simple
> fix to just assert the device lock is held.

Agreed.

> 
> > I'm puzzled why lockdep isn't shouting over this for me, so I added
> > a
> > lockdep_assert_not_held() in those paths to get a proper callchain:
> 
> The driver core mostly disables lockdep on the device_lock() :(

Ah, TIL. Thanks!

> 
> Does this work for you?

Yup, for both -ap and -ccw devices that I have handy. Thanks for the
quick turnaround!

Thanks,
Eric

> 
> Thanks,
> Jason
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 18162049bd2294..1f58bfacb47951 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1166,12 +1166,11 @@ int iommu_group_add_device(struct iommu_group
> *group, struct device *dev)
>  {
>         struct group_device *gdev;
>  
> -       device_lock(dev);
> +       device_lock_assert(dev);
> +
>         gdev = iommu_group_alloc_device(group, dev);
> -       if (IS_ERR(gdev)) {
> -               device_unlock(dev);
> +       if (IS_ERR(gdev))
>                 return PTR_ERR(gdev);
> -       }
>  
>         iommu_group_ref_get(group);
>         dev->iommu_group = group;
> @@ -1179,7 +1178,6 @@ int iommu_group_add_device(struct iommu_group
> *group, struct device *dev)
>         mutex_lock(&group->mutex);
>         list_add_tail(&gdev->list, &group->devices);
>         mutex_unlock(&group->mutex);
> -       device_unlock(dev);
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(iommu_group_add_device);
> @@ -1195,14 +1193,13 @@ void iommu_group_remove_device(struct device
> *dev)
>  {
>         struct iommu_group *group;
>  
> -       device_lock(dev);
> +       device_lock_assert(dev);
> +
>         group = dev->iommu_group;
>         if (group) {
>                 dev_info(dev, "Removing from iommu group %d\n",
> group->id);
>                 __iommu_group_remove_device(dev);
>         }
> -       device_unlock(dev);
> -
>  }
>  EXPORT_SYMBOL_GPL(iommu_group_remove_device);
>  





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux