* [PATCH v4 0/2] Remove vfio_device_get_from_dev()
@ 2022-05-05 23:21 Jason Gunthorpe
2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Jason Gunthorpe @ 2022-05-05 23:21 UTC (permalink / raw)
To: Alex Williamson, Cornelia Huck, Kevin Tian, kvm, Longfang Liu,
Shameer Kolothum, Yishai Hadas
Cc: Abhishek Sahu, Kirti Wankhede
Use drvdata instead of searching to find the struct vfio_device for the
pci_driver callbacks.
This applies on top of the gvt series and at least rc3 - there are no
conflicts with the mdev vfio_group series, or the iommu series.
v4:
- Put back missing rebase hunk for vfio_group_get_from_dev()
- Move the WARN_ON to vfio_pci_core_register_device() and move the
dev_set_drvdata() to match
v3: https://lore.kernel.org/r/0-v3-4adf6c1b8e7c+170-vfio_get_from_dev_jgg@nvidia.com
- Directly access the drvdata from vfio_pci_core by making drvdata always
point to the core struct. This will help later patches adding PM
callbacks as well.
v2: https://lore.kernel.org/r/0-v2-0f36bcf6ec1e+64d-vfio_get_from_dev_jgg@nvidia.com
- Rebase on the vfio_mdev_no_group branch
- Delete vfio_group_get_from_dev() as well due to the rebase
v1: https://lore.kernel.org/r/0-v1-7f2292e6b2ba+44839-vfio_get_from_dev_jgg@nvidia.com
Jason Gunthorpe (2):
vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in
drvdata
vfio/pci: Remove vfio_device_get_from_dev()
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++--
drivers/vfio/pci/mlx5/main.c | 15 +++++--
drivers/vfio/pci/vfio_pci.c | 6 ++-
drivers/vfio/pci/vfio_pci_core.c | 36 +++++-----------
drivers/vfio/vfio.c | 41 +------------------
include/linux/vfio.h | 2 -
include/linux/vfio_pci_core.h | 3 +-
7 files changed, 39 insertions(+), 79 deletions(-)
base-commit: 21ce7c292b5684f930cc63f3841ec692bbd6c10a
--
2.36.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata 2022-05-05 23:21 [PATCH v4 0/2] Remove vfio_device_get_from_dev() Jason Gunthorpe @ 2022-05-05 23:21 ` Jason Gunthorpe 2022-05-06 15:42 ` Alex Williamson 2022-05-09 6:35 ` Abhishek Sahu 2022-05-05 23:21 ` [PATCH v4 2/2] vfio/pci: Remove vfio_device_get_from_dev() Jason Gunthorpe 2022-05-12 18:21 ` [PATCH v4 0/2] " Alex Williamson 2 siblings, 2 replies; 7+ messages in thread From: Jason Gunthorpe @ 2022-05-05 23:21 UTC (permalink / raw) To: Alex Williamson, Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas Cc: Abhishek Sahu, Kirti Wankhede Having a consistent pointer in the drvdata will allow the next patch to make use of the drvdata from some of the core code helpers. Use a WARN_ON inside vfio_pci_core_enable() to detect drivers that miss this. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++++++++---- drivers/vfio/pci/mlx5/main.c | 15 +++++++++++---- drivers/vfio/pci/vfio_pci.c | 2 +- drivers/vfio/pci/vfio_pci_core.c | 4 ++++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 767b5d47631a49..e92376837b29e6 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm) return 0; } +static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev) +{ + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); + + return container_of(core_device, struct hisi_acc_vf_core_device, + core_device); +} + static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev, struct hisi_qm *qm) { @@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev, static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev) { - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); if (hisi_acc_vdev->core_device.vdev.migration_flags != VFIO_MIGRATION_STOP_COPY) @@ -1274,11 +1282,10 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device &hisi_acc_vfio_pci_ops); } + dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device); ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device); if (ret) goto out_free; - - dev_set_drvdata(&pdev->dev, hisi_acc_vdev); return 0; out_free: @@ -1289,7 +1296,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev) { - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device); vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index bbec5d288fee97..9f59f5807b8ab1 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -39,6 +39,14 @@ struct mlx5vf_pci_core_device { struct mlx5_vf_migration_file *saving_migf; }; +static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) +{ + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); + + return container_of(core_device, struct mlx5vf_pci_core_device, + core_device); +} + static struct page * mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, unsigned long offset) @@ -505,7 +513,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev, static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev) { - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); if (!mvdev->migrate_cap) return; @@ -614,11 +622,10 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, } } + dev_set_drvdata(&pdev->dev, &mvdev->core_device); ret = vfio_pci_core_register_device(&mvdev->core_device); if (ret) goto out_free; - - dev_set_drvdata(&pdev->dev, mvdev); return 0; out_free: @@ -629,7 +636,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, static void mlx5vf_pci_remove(struct pci_dev *pdev) { - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); vfio_pci_core_unregister_device(&mvdev->core_device); vfio_pci_core_uninit_device(&mvdev->core_device); diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 58839206d1ca7f..e34db35b8d61a1 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -151,10 +151,10 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; vfio_pci_core_init_device(vdev, pdev, &vfio_pci_ops); + dev_set_drvdata(&pdev->dev, vdev); ret = vfio_pci_core_register_device(vdev); if (ret) goto out_free; - dev_set_drvdata(&pdev->dev, vdev); return 0; out_free: diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 06b6f3594a1316..65587fd5c021bb 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1821,6 +1821,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) struct pci_dev *pdev = vdev->pdev; int ret; + /* Drivers must set the vfio_pci_core_device to their drvdata */ + if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev))) + return -EINVAL; + if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) return -EINVAL; -- 2.36.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata 2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe @ 2022-05-06 15:42 ` Alex Williamson 2022-05-06 17:57 ` Jason Gunthorpe 2022-05-09 6:35 ` Abhishek Sahu 1 sibling, 1 reply; 7+ messages in thread From: Alex Williamson @ 2022-05-06 15:42 UTC (permalink / raw) To: Jason Gunthorpe Cc: Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas, Abhishek Sahu, Kirti Wankhede On Thu, 5 May 2022 20:21:39 -0300 Jason Gunthorpe <jgg@nvidia.com> wrote: > Having a consistent pointer in the drvdata will allow the next patch to > make use of the drvdata from some of the core code helpers. > > Use a WARN_ON inside vfio_pci_core_enable() to detect drivers that miss > this. Stale comment, I'll s/vfio_pci_core_enable/vfio_pci_core_register_device/ on commit. Looks ok otherwise. Thanks, Alex > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > --- > drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++++++++---- > drivers/vfio/pci/mlx5/main.c | 15 +++++++++++---- > drivers/vfio/pci/vfio_pci.c | 2 +- > drivers/vfio/pci/vfio_pci_core.c | 4 ++++ > 4 files changed, 27 insertions(+), 9 deletions(-) > > diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > index 767b5d47631a49..e92376837b29e6 100644 > --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > @@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm) > return 0; > } > > +static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct hisi_acc_vf_core_device, > + core_device); > +} > + > static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev, > struct hisi_qm *qm) > { > @@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev, > > static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > if (hisi_acc_vdev->core_device.vdev.migration_flags != > VFIO_MIGRATION_STOP_COPY) > @@ -1274,11 +1282,10 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > &hisi_acc_vfio_pci_ops); > } > > + dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device); > ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device); > if (ret) > goto out_free; > - > - dev_set_drvdata(&pdev->dev, hisi_acc_vdev); > return 0; > > out_free: > @@ -1289,7 +1296,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > > static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device); > vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device); > diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c > index bbec5d288fee97..9f59f5807b8ab1 100644 > --- a/drivers/vfio/pci/mlx5/main.c > +++ b/drivers/vfio/pci/mlx5/main.c > @@ -39,6 +39,14 @@ struct mlx5vf_pci_core_device { > struct mlx5_vf_migration_file *saving_migf; > }; > > +static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct mlx5vf_pci_core_device, > + core_device); > +} > + > static struct page * > mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, > unsigned long offset) > @@ -505,7 +513,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev, > > static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > if (!mvdev->migrate_cap) > return; > @@ -614,11 +622,10 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > } > } > > + dev_set_drvdata(&pdev->dev, &mvdev->core_device); > ret = vfio_pci_core_register_device(&mvdev->core_device); > if (ret) > goto out_free; > - > - dev_set_drvdata(&pdev->dev, mvdev); > return 0; > > out_free: > @@ -629,7 +636,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > > static void mlx5vf_pci_remove(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > vfio_pci_core_unregister_device(&mvdev->core_device); > vfio_pci_core_uninit_device(&mvdev->core_device); > diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c > index 58839206d1ca7f..e34db35b8d61a1 100644 > --- a/drivers/vfio/pci/vfio_pci.c > +++ b/drivers/vfio/pci/vfio_pci.c > @@ -151,10 +151,10 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > return -ENOMEM; > vfio_pci_core_init_device(vdev, pdev, &vfio_pci_ops); > > + dev_set_drvdata(&pdev->dev, vdev); > ret = vfio_pci_core_register_device(vdev); > if (ret) > goto out_free; > - dev_set_drvdata(&pdev->dev, vdev); > return 0; > > out_free: > diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c > index 06b6f3594a1316..65587fd5c021bb 100644 > --- a/drivers/vfio/pci/vfio_pci_core.c > +++ b/drivers/vfio/pci/vfio_pci_core.c > @@ -1821,6 +1821,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) > struct pci_dev *pdev = vdev->pdev; > int ret; > > + /* Drivers must set the vfio_pci_core_device to their drvdata */ > + if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev))) > + return -EINVAL; > + > if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) > return -EINVAL; > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata 2022-05-06 15:42 ` Alex Williamson @ 2022-05-06 17:57 ` Jason Gunthorpe 0 siblings, 0 replies; 7+ messages in thread From: Jason Gunthorpe @ 2022-05-06 17:57 UTC (permalink / raw) To: Alex Williamson Cc: Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas, Abhishek Sahu, Kirti Wankhede On Fri, May 06, 2022 at 09:42:53AM -0600, Alex Williamson wrote: > On Thu, 5 May 2022 20:21:39 -0300 > Jason Gunthorpe <jgg@nvidia.com> wrote: > > > Having a consistent pointer in the drvdata will allow the next patch to > > make use of the drvdata from some of the core code helpers. > > > > Use a WARN_ON inside vfio_pci_core_enable() to detect drivers that miss > > this. > > Stale comment, I'll > > s/vfio_pci_core_enable/vfio_pci_core_register_device/ > > on commit. Looks ok otherwise. Thanks, Yes, thanks Jason ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata 2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe 2022-05-06 15:42 ` Alex Williamson @ 2022-05-09 6:35 ` Abhishek Sahu 1 sibling, 0 replies; 7+ messages in thread From: Abhishek Sahu @ 2022-05-09 6:35 UTC (permalink / raw) To: Jason Gunthorpe, Alex Williamson, Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas Cc: Kirti Wankhede On 5/6/2022 4:51 AM, Jason Gunthorpe wrote: > Having a consistent pointer in the drvdata will allow the next patch to > make use of the drvdata from some of the core code helpers. > > Use a WARN_ON inside vfio_pci_core_enable() to detect drivers that miss > this. > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > --- > drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++++++++---- > drivers/vfio/pci/mlx5/main.c | 15 +++++++++++---- > drivers/vfio/pci/vfio_pci.c | 2 +- > drivers/vfio/pci/vfio_pci_core.c | 4 ++++ > 4 files changed, 27 insertions(+), 9 deletions(-) > > diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > index 767b5d47631a49..e92376837b29e6 100644 > --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > @@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm) > return 0; > } > > +static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct hisi_acc_vf_core_device, > + core_device); > +} > + > static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev, > struct hisi_qm *qm) > { > @@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev, > > static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > if (hisi_acc_vdev->core_device.vdev.migration_flags != > VFIO_MIGRATION_STOP_COPY) > @@ -1274,11 +1282,10 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > &hisi_acc_vfio_pci_ops); > } > > + dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device); > ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device); > if (ret) > goto out_free; > - > - dev_set_drvdata(&pdev->dev, hisi_acc_vdev); > return 0; > > out_free: > @@ -1289,7 +1296,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device > > static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev) > { > - struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev); > + struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev); > > vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device); > vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device); > diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c > index bbec5d288fee97..9f59f5807b8ab1 100644 > --- a/drivers/vfio/pci/mlx5/main.c > +++ b/drivers/vfio/pci/mlx5/main.c > @@ -39,6 +39,14 @@ struct mlx5vf_pci_core_device { > struct mlx5_vf_migration_file *saving_migf; > }; > > +static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev) > +{ > + struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); > + > + return container_of(core_device, struct mlx5vf_pci_core_device, > + core_device); > +} > + > static struct page * > mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf, > unsigned long offset) > @@ -505,7 +513,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev, > > static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > if (!mvdev->migrate_cap) > return; > @@ -614,11 +622,10 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > } > } > > + dev_set_drvdata(&pdev->dev, &mvdev->core_device); > ret = vfio_pci_core_register_device(&mvdev->core_device); > if (ret) > goto out_free; > - > - dev_set_drvdata(&pdev->dev, mvdev); > return 0; > > out_free: > @@ -629,7 +636,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, > > static void mlx5vf_pci_remove(struct pci_dev *pdev) > { > - struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev); > + struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev); > > vfio_pci_core_unregister_device(&mvdev->core_device); > vfio_pci_core_uninit_device(&mvdev->core_device); > diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c > index 58839206d1ca7f..e34db35b8d61a1 100644 > --- a/drivers/vfio/pci/vfio_pci.c > +++ b/drivers/vfio/pci/vfio_pci.c > @@ -151,10 +151,10 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > return -ENOMEM; > vfio_pci_core_init_device(vdev, pdev, &vfio_pci_ops); > > + dev_set_drvdata(&pdev->dev, vdev); > ret = vfio_pci_core_register_device(vdev); > if (ret) > goto out_free; > - dev_set_drvdata(&pdev->dev, vdev); > return 0; > > out_free: > diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c > index 06b6f3594a1316..65587fd5c021bb 100644 > --- a/drivers/vfio/pci/vfio_pci_core.c > +++ b/drivers/vfio/pci/vfio_pci_core.c > @@ -1821,6 +1821,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) > struct pci_dev *pdev = vdev->pdev; > int ret; > > + /* Drivers must set the vfio_pci_core_device to their drvdata */ > + if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev))) > + return -EINVAL; > + > if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) > return -EINVAL; > Thanks Jason. I have applied this patch locally and confirmed that my power management changes works fine without my dev_set_drvdata() patch. Regards, Abhishek ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 2/2] vfio/pci: Remove vfio_device_get_from_dev() 2022-05-05 23:21 [PATCH v4 0/2] Remove vfio_device_get_from_dev() Jason Gunthorpe 2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe @ 2022-05-05 23:21 ` Jason Gunthorpe 2022-05-12 18:21 ` [PATCH v4 0/2] " Alex Williamson 2 siblings, 0 replies; 7+ messages in thread From: Jason Gunthorpe @ 2022-05-05 23:21 UTC (permalink / raw) To: Alex Williamson, Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas Cc: Abhishek Sahu, Kirti Wankhede The last user of this function is in PCI callbacks that want to convert their struct pci_dev to a vfio_device. Instead of searching use the vfio_device available trivially through the drvdata. When a callback in the device_driver is called, the caller must hold the device_lock() on dev. The purpose of the device_lock is to prevent remove() from being called (see __device_release_driver), and allow the driver to safely interact with its drvdata without races. The PCI core correctly follows this and holds the device_lock() when calling error_detected (see report_error_detected) and sriov_configure (see sriov_numvfs_store). Further, since the drvdata holds a positive refcount on the vfio_device any access of the drvdata, under the device_lock(), from a driver callback needs no further protection or refcounting. Thus the remark in the vfio_device_get_from_dev() comment does not apply here, VFIO PCI drivers all call vfio_unregister_group_dev() from their remove callbacks under the device_lock() and cannot race with the remaining callers. Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com> Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/vfio/pci/vfio_pci.c | 4 +++- drivers/vfio/pci/vfio_pci_core.c | 32 +++++-------------------- drivers/vfio/vfio.c | 41 +------------------------------- include/linux/vfio.h | 2 -- include/linux/vfio_pci_core.h | 3 ++- 5 files changed, 12 insertions(+), 70 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index e34db35b8d61a1..4d1a97415a27bf 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -174,10 +174,12 @@ static void vfio_pci_remove(struct pci_dev *pdev) static int vfio_pci_sriov_configure(struct pci_dev *pdev, int nr_virtfn) { + struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); + if (!enable_sriov) return -ENOENT; - return vfio_pci_core_sriov_configure(pdev, nr_virtfn); + return vfio_pci_core_sriov_configure(vdev, nr_virtfn); } static const struct pci_device_id vfio_pci_table[] = { diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 65587fd5c021bb..100ab98c7ff021 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1894,9 +1894,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_register_device); void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev) { - struct pci_dev *pdev = vdev->pdev; - - vfio_pci_core_sriov_configure(pdev, 0); + vfio_pci_core_sriov_configure(vdev, 0); vfio_unregister_group_dev(&vdev->vdev); @@ -1911,14 +1909,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_unregister_device); pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct vfio_pci_core_device *vdev; - struct vfio_device *device; - - device = vfio_device_get_from_dev(&pdev->dev); - if (device == NULL) - return PCI_ERS_RESULT_DISCONNECT; - - vdev = container_of(device, struct vfio_pci_core_device, vdev); + struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); mutex_lock(&vdev->igate); @@ -1927,26 +1918,18 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, mutex_unlock(&vdev->igate); - vfio_device_put(device); - return PCI_ERS_RESULT_CAN_RECOVER; } EXPORT_SYMBOL_GPL(vfio_pci_core_aer_err_detected); -int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn) +int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev, + int nr_virtfn) { - struct vfio_pci_core_device *vdev; - struct vfio_device *device; + struct pci_dev *pdev = vdev->pdev; int ret = 0; device_lock_assert(&pdev->dev); - device = vfio_device_get_from_dev(&pdev->dev); - if (!device) - return -ENODEV; - - vdev = container_of(device, struct vfio_pci_core_device, vdev); - if (nr_virtfn) { mutex_lock(&vfio_pci_sriov_pfs_mutex); /* @@ -1964,8 +1947,7 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn) ret = pci_enable_sriov(pdev, nr_virtfn); if (ret) goto out_del; - ret = nr_virtfn; - goto out_put; + return nr_virtfn; } pci_disable_sriov(pdev); @@ -1975,8 +1957,6 @@ int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn) list_del_init(&vdev->sriov_pfs_item); out_unlock: mutex_unlock(&vfio_pci_sriov_pfs_mutex); -out_put: - vfio_device_put(device); return ret; } EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure); diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index f7d1898129ad1c..fcff23fd256a67 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -444,31 +444,15 @@ static void vfio_group_get(struct vfio_group *group) refcount_inc(&group->users); } -static struct vfio_group *vfio_group_get_from_dev(struct device *dev) -{ - struct iommu_group *iommu_group; - struct vfio_group *group; - - iommu_group = iommu_group_get(dev); - if (!iommu_group) - return NULL; - - group = vfio_group_get_from_iommu(iommu_group); - iommu_group_put(iommu_group); - - return group; -} - /* * Device objects - create, release, get, put, search */ /* Device reference always implies a group reference */ -void vfio_device_put(struct vfio_device *device) +static void vfio_device_put(struct vfio_device *device) { if (refcount_dec_and_test(&device->refcount)) complete(&device->comp); } -EXPORT_SYMBOL_GPL(vfio_device_put); static bool vfio_device_try_get(struct vfio_device *device) { @@ -633,29 +617,6 @@ int vfio_register_emulated_iommu_dev(struct vfio_device *device) } EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev); -/* - * Get a reference to the vfio_device for a device. Even if the - * caller thinks they own the device, they could be racing with a - * release call path, so we can't trust drvdata for the shortcut. - * Go the long way around, from the iommu_group to the vfio_group - * to the vfio_device. - */ -struct vfio_device *vfio_device_get_from_dev(struct device *dev) -{ - struct vfio_group *group; - struct vfio_device *device; - - group = vfio_group_get_from_dev(dev); - if (!group) - return NULL; - - device = vfio_group_get_device(group, dev); - vfio_group_put(group); - - return device; -} -EXPORT_SYMBOL_GPL(vfio_device_get_from_dev); - static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group, char *buf) { diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 9a9981c2622896..de8dd31b0639b0 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -125,8 +125,6 @@ void vfio_uninit_group_dev(struct vfio_device *device); int vfio_register_group_dev(struct vfio_device *device); int vfio_register_emulated_iommu_dev(struct vfio_device *device); void vfio_unregister_group_dev(struct vfio_device *device); -extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); -extern void vfio_device_put(struct vfio_device *device); int vfio_assign_device_set(struct vfio_device *device, void *set_id); diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 48f2dd3c568c83..23c176d4b073f1 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -227,8 +227,9 @@ void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev, int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev); void vfio_pci_core_uninit_device(struct vfio_pci_core_device *vdev); void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev); -int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn); extern const struct pci_error_handlers vfio_pci_core_err_handlers; +int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev, + int nr_virtfn); long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd, unsigned long arg); int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags, -- 2.36.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v4 0/2] Remove vfio_device_get_from_dev() 2022-05-05 23:21 [PATCH v4 0/2] Remove vfio_device_get_from_dev() Jason Gunthorpe 2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe 2022-05-05 23:21 ` [PATCH v4 2/2] vfio/pci: Remove vfio_device_get_from_dev() Jason Gunthorpe @ 2022-05-12 18:21 ` Alex Williamson 2 siblings, 0 replies; 7+ messages in thread From: Alex Williamson @ 2022-05-12 18:21 UTC (permalink / raw) To: Jason Gunthorpe Cc: Cornelia Huck, Kevin Tian, kvm, Longfang Liu, Shameer Kolothum, Yishai Hadas, Abhishek Sahu, Kirti Wankhede On Thu, 5 May 2022 20:21:38 -0300 Jason Gunthorpe <jgg@nvidia.com> wrote: > Use drvdata instead of searching to find the struct vfio_device for the > pci_driver callbacks. > > This applies on top of the gvt series and at least rc3 - there are no > conflicts with the mdev vfio_group series, or the iommu series. > > v4: > - Put back missing rebase hunk for vfio_group_get_from_dev() > - Move the WARN_ON to vfio_pci_core_register_device() and move the > dev_set_drvdata() to match > v3: https://lore.kernel.org/r/0-v3-4adf6c1b8e7c+170-vfio_get_from_dev_jgg@nvidia.com > - Directly access the drvdata from vfio_pci_core by making drvdata always > point to the core struct. This will help later patches adding PM > callbacks as well. > v2: https://lore.kernel.org/r/0-v2-0f36bcf6ec1e+64d-vfio_get_from_dev_jgg@nvidia.com > - Rebase on the vfio_mdev_no_group branch > - Delete vfio_group_get_from_dev() as well due to the rebase > v1: https://lore.kernel.org/r/0-v1-7f2292e6b2ba+44839-vfio_get_from_dev_jgg@nvidia.com > > Jason Gunthorpe (2): > vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in > drvdata > vfio/pci: Remove vfio_device_get_from_dev() > > .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++-- > drivers/vfio/pci/mlx5/main.c | 15 +++++-- > drivers/vfio/pci/vfio_pci.c | 6 ++- > drivers/vfio/pci/vfio_pci_core.c | 36 +++++----------- > drivers/vfio/vfio.c | 41 +------------------ > include/linux/vfio.h | 2 - > include/linux/vfio_pci_core.h | 3 +- > 7 files changed, 39 insertions(+), 79 deletions(-) Applied to vfio next branch for v5.19. Thanks, Alex ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-05-12 18:21 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-05-05 23:21 [PATCH v4 0/2] Remove vfio_device_get_from_dev() Jason Gunthorpe 2022-05-05 23:21 ` [PATCH v4 1/2] vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata Jason Gunthorpe 2022-05-06 15:42 ` Alex Williamson 2022-05-06 17:57 ` Jason Gunthorpe 2022-05-09 6:35 ` Abhishek Sahu 2022-05-05 23:21 ` [PATCH v4 2/2] vfio/pci: Remove vfio_device_get_from_dev() Jason Gunthorpe 2022-05-12 18:21 ` [PATCH v4 0/2] " Alex Williamson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox