Skip to content

Commit da119f3

Browse files
jgunthorpeAlex Williamson
authored andcommitted
vfio/fsl: Move to the device set infrastructure
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. The dev_set lock 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. Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Tested-by: Diana Craciun OSS <diana.craciun@oss.nxp.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/6-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 17a1e4f commit da119f3

3 files changed

Lines changed: 28 additions & 139 deletions

File tree

drivers/vfio/fsl-mc/vfio_fsl_mc.c

Lines changed: 25 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -19,81 +19,10 @@
1919

2020
static struct fsl_mc_driver vfio_fsl_mc_driver;
2121

22-
static DEFINE_MUTEX(reflck_lock);
23-
24-
static void vfio_fsl_mc_reflck_get(struct vfio_fsl_mc_reflck *reflck)
25-
{
26-
kref_get(&reflck->kref);
27-
}
28-
29-
static void vfio_fsl_mc_reflck_release(struct kref *kref)
30-
{
31-
struct vfio_fsl_mc_reflck *reflck = container_of(kref,
32-
struct vfio_fsl_mc_reflck,
33-
kref);
34-
35-
mutex_destroy(&reflck->lock);
36-
kfree(reflck);
37-
mutex_unlock(&reflck_lock);
38-
}
39-
40-
static void vfio_fsl_mc_reflck_put(struct vfio_fsl_mc_reflck *reflck)
41-
{
42-
kref_put_mutex(&reflck->kref, vfio_fsl_mc_reflck_release, &reflck_lock);
43-
}
44-
45-
static struct vfio_fsl_mc_reflck *vfio_fsl_mc_reflck_alloc(void)
46-
{
47-
struct vfio_fsl_mc_reflck *reflck;
48-
49-
reflck = kzalloc(sizeof(*reflck), GFP_KERNEL);
50-
if (!reflck)
51-
return ERR_PTR(-ENOMEM);
52-
53-
kref_init(&reflck->kref);
54-
mutex_init(&reflck->lock);
55-
56-
return reflck;
57-
}
58-
59-
static int vfio_fsl_mc_reflck_attach(struct vfio_fsl_mc_device *vdev)
60-
{
61-
int ret = 0;
62-
63-
mutex_lock(&reflck_lock);
64-
if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
65-
vdev->reflck = vfio_fsl_mc_reflck_alloc();
66-
ret = PTR_ERR_OR_ZERO(vdev->reflck);
67-
} else {
68-
struct device *mc_cont_dev = vdev->mc_dev->dev.parent;
69-
struct vfio_device *device;
70-
struct vfio_fsl_mc_device *cont_vdev;
71-
72-
device = vfio_device_get_from_dev(mc_cont_dev);
73-
if (!device) {
74-
ret = -ENODEV;
75-
goto unlock;
76-
}
77-
78-
cont_vdev =
79-
container_of(device, struct vfio_fsl_mc_device, vdev);
80-
if (!cont_vdev || !cont_vdev->reflck) {
81-
vfio_device_put(device);
82-
ret = -ENODEV;
83-
goto unlock;
84-
}
85-
vfio_fsl_mc_reflck_get(cont_vdev->reflck);
86-
vdev->reflck = cont_vdev->reflck;
87-
vfio_device_put(device);
88-
}
89-
90-
unlock:
91-
mutex_unlock(&reflck_lock);
92-
return ret;
93-
}
94-
95-
static int vfio_fsl_mc_regions_init(struct vfio_fsl_mc_device *vdev)
22+
static int vfio_fsl_mc_open_device(struct vfio_device *core_vdev)
9623
{
24+
struct vfio_fsl_mc_device *vdev =
25+
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
9726
struct fsl_mc_device *mc_dev = vdev->mc_dev;
9827
int count = mc_dev->obj_desc.region_count;
9928
int i;
@@ -136,58 +65,30 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev)
13665
kfree(vdev->regions);
13766
}
13867

139-
static int vfio_fsl_mc_open(struct vfio_device *core_vdev)
140-
{
141-
struct vfio_fsl_mc_device *vdev =
142-
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
143-
int ret = 0;
144-
145-
mutex_lock(&vdev->reflck->lock);
146-
if (!vdev->refcnt) {
147-
ret = vfio_fsl_mc_regions_init(vdev);
148-
if (ret)
149-
goto out;
150-
}
151-
vdev->refcnt++;
152-
out:
153-
mutex_unlock(&vdev->reflck->lock);
15468

155-
return ret;
156-
}
157-
158-
static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
69+
static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
15970
{
16071
struct vfio_fsl_mc_device *vdev =
16172
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
73+
struct fsl_mc_device *mc_dev = vdev->mc_dev;
74+
struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
75+
struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
16276
int ret;
16377

164-
mutex_lock(&vdev->reflck->lock);
165-
166-
if (!(--vdev->refcnt)) {
167-
struct fsl_mc_device *mc_dev = vdev->mc_dev;
168-
struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
169-
struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
170-
171-
vfio_fsl_mc_regions_cleanup(vdev);
78+
vfio_fsl_mc_regions_cleanup(vdev);
17279

173-
/* reset the device before cleaning up the interrupts */
174-
ret = dprc_reset_container(mc_cont->mc_io, 0,
175-
mc_cont->mc_handle,
176-
mc_cont->obj_desc.id,
177-
DPRC_RESET_OPTION_NON_RECURSIVE);
80+
/* reset the device before cleaning up the interrupts */
81+
ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle,
82+
mc_cont->obj_desc.id,
83+
DPRC_RESET_OPTION_NON_RECURSIVE);
17884

179-
if (ret) {
180-
dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n",
181-
ret);
182-
WARN_ON(1);
183-
}
85+
if (WARN_ON(ret))
86+
dev_warn(&mc_cont->dev,
87+
"VFIO_FLS_MC: reset device has failed (%d)\n", ret);
18488

185-
vfio_fsl_mc_irqs_cleanup(vdev);
89+
vfio_fsl_mc_irqs_cleanup(vdev);
18690

187-
fsl_mc_cleanup_irq_pool(mc_cont);
188-
}
189-
190-
mutex_unlock(&vdev->reflck->lock);
91+
fsl_mc_cleanup_irq_pool(mc_cont);
19192
}
19293

19394
static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
@@ -504,8 +405,8 @@ static int vfio_fsl_mc_mmap(struct vfio_device *core_vdev,
504405

505406
static const struct vfio_device_ops vfio_fsl_mc_ops = {
506407
.name = "vfio-fsl-mc",
507-
.open = vfio_fsl_mc_open,
508-
.release = vfio_fsl_mc_release,
408+
.open_device = vfio_fsl_mc_open_device,
409+
.close_device = vfio_fsl_mc_close_device,
509410
.ioctl = vfio_fsl_mc_ioctl,
510411
.read = vfio_fsl_mc_read,
511412
.write = vfio_fsl_mc_write,
@@ -625,26 +526,23 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
625526
vdev->mc_dev = mc_dev;
626527
mutex_init(&vdev->igate);
627528

628-
ret = vfio_fsl_mc_reflck_attach(vdev);
529+
if (is_fsl_mc_bus_dprc(mc_dev))
530+
ret = vfio_assign_device_set(&vdev->vdev, &mc_dev->dev);
531+
else
532+
ret = vfio_assign_device_set(&vdev->vdev, mc_dev->dev.parent);
629533
if (ret)
630534
goto out_uninit;
631535

632536
ret = vfio_fsl_mc_init_device(vdev);
633537
if (ret)
634-
goto out_reflck;
538+
goto out_uninit;
635539

636540
ret = vfio_register_group_dev(&vdev->vdev);
637541
if (ret) {
638542
dev_err(dev, "VFIO_FSL_MC: Failed to add to vfio group\n");
639543
goto out_device;
640544
}
641545

642-
/*
643-
* This triggers recursion into vfio_fsl_mc_probe() on another device
644-
* and the vfio_fsl_mc_reflck_attach() must succeed, which relies on the
645-
* vfio_add_group_dev() above. It has no impact on this vdev, so it is
646-
* safe to be after the vfio device is made live.
647-
*/
648546
ret = vfio_fsl_mc_scan_container(mc_dev);
649547
if (ret)
650548
goto out_group_dev;
@@ -655,8 +553,6 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
655553
vfio_unregister_group_dev(&vdev->vdev);
656554
out_device:
657555
vfio_fsl_uninit_device(vdev);
658-
out_reflck:
659-
vfio_fsl_mc_reflck_put(vdev->reflck);
660556
out_uninit:
661557
vfio_uninit_group_dev(&vdev->vdev);
662558
kfree(vdev);
@@ -675,7 +571,7 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)
675571

676572
dprc_remove_devices(mc_dev, NULL, 0);
677573
vfio_fsl_uninit_device(vdev);
678-
vfio_fsl_mc_reflck_put(vdev->reflck);
574+
679575
vfio_uninit_group_dev(&vdev->vdev);
680576
kfree(vdev);
681577
vfio_iommu_group_put(mc_dev->dev.iommu_group, dev);

drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev,
120120
if (start != 0 || count != 1)
121121
return -EINVAL;
122122

123-
mutex_lock(&vdev->reflck->lock);
123+
mutex_lock(&vdev->vdev.dev_set->lock);
124124
ret = fsl_mc_populate_irq_pool(mc_cont,
125125
FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
126126
if (ret)
@@ -129,7 +129,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev,
129129
ret = vfio_fsl_mc_irqs_allocate(vdev);
130130
if (ret)
131131
goto unlock;
132-
mutex_unlock(&vdev->reflck->lock);
132+
mutex_unlock(&vdev->vdev.dev_set->lock);
133133

134134
if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
135135
s32 fd = *(s32 *)data;
@@ -154,7 +154,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev,
154154
return 0;
155155

156156
unlock:
157-
mutex_unlock(&vdev->reflck->lock);
157+
mutex_unlock(&vdev->vdev.dev_set->lock);
158158
return ret;
159159

160160
}

drivers/vfio/fsl-mc/vfio_fsl_mc_private.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ struct vfio_fsl_mc_irq {
2222
char *name;
2323
};
2424

25-
struct vfio_fsl_mc_reflck {
26-
struct kref kref;
27-
struct mutex lock;
28-
};
29-
3025
struct vfio_fsl_mc_region {
3126
u32 flags;
3227
u32 type;
@@ -39,9 +34,7 @@ struct vfio_fsl_mc_device {
3934
struct vfio_device vdev;
4035
struct fsl_mc_device *mc_dev;
4136
struct notifier_block nb;
42-
int refcnt;
4337
struct vfio_fsl_mc_region *regions;
44-
struct vfio_fsl_mc_reflck *reflck;
4538
struct mutex igate;
4639
struct vfio_fsl_mc_irq *mc_irqs;
4740
};

0 commit comments

Comments
 (0)