On Tue, Jul 20, 2021 at 07:12:26PM +0300, Diana Craciun OSS wrote:
> On 7/15/2021 3:20 AM, Jason Gunthorpe wrote:
> > FSL uses the internal reflck to implement the open_device() functionality,
> > conversion to the core code is straightforward.
> > 
> > The decision on which set to be part of is trivially based on the
> > is_fsl_mc_bus_dprc() and we use a 'struct device *' pointer as the set_id.
> > 
> > It isn't entirely clear what the device set lock is actually protecting,
> > but I think it is related to the interrupt setup.
> 
> Yes, it is protecting the interrupts setup. The FSL MC devices are using
> MSIs and only the DPRC device is allocating the MSIs from the MSI domain.
> The other devices just take interrupts from a pool. The lock is protecting
> the access to this pool.

It would be much clearer if the lock was near the data it was
protecting, the DPRC pool seems in an entirely different layer..

> > -static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
> > +static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
> >   {
> >     struct vfio_fsl_mc_device *vdev =
> >             container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
> > +   struct fsl_mc_device *mc_dev = vdev->mc_dev;
> > +   struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
> > +   struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
> >     int ret;
> > -   mutex_lock(&vdev->reflck->lock);
> > +   vfio_fsl_mc_regions_cleanup(vdev);
> > -   if (!(--vdev->refcnt)) {
> > -           struct fsl_mc_device *mc_dev = vdev->mc_dev;
> > -           struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
> > -           struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
> > -
> > -           vfio_fsl_mc_regions_cleanup(vdev);
> > +   /* reset the device before cleaning up the interrupts */
> > +   ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle,
> > +                              mc_cont->obj_desc.id,
> > +                              DPRC_RESET_OPTION_NON_RECURSIVE);
> > -           /* reset the device before cleaning up the interrupts */
> > -           ret = dprc_reset_container(mc_cont->mc_io, 0,
> > -                 mc_cont->mc_handle,
> > -                     mc_cont->obj_desc.id,
> > -                     DPRC_RESET_OPTION_NON_RECURSIVE);
> > +   if (WARN_ON(ret))
> > +           dev_warn(&mc_cont->dev,
> > +                    "VFIO_FLS_MC: reset device has failed (%d)\n", ret);
> > -           if (ret) {
> > -                   dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has 
> > failed (%d)\n",
> > -                            ret);
> > -                   WARN_ON(1);
> > -           }
> > +   vfio_fsl_mc_irqs_cleanup(vdev);
> > -           vfio_fsl_mc_irqs_cleanup(vdev);
> > -
> > -           fsl_mc_cleanup_irq_pool(mc_cont);
> 
> There is also a need for the lock here. Eventhough the close function is
> called only once, there might be a race between the devices in the
> set. 

vfio_fsl_mc_close_device() is already called under this lock:

        mutex_lock(&device->dev_set->lock);
        if (!--device->open_count && device->ops->close_device)
                device->ops->close_device(device);
        mutex_unlock(&device->dev_set->lock);

Thanks,
Jason
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to