Skip to content

Commit 8607056

Browse files
nicolincjgunthorpe
authored andcommitted
iommufd/selftest: Add refcount to mock_iommu_device
For an iommu_dev that can unplug (so far only this selftest does so), the viommu->iommu_dev pointer has no guarantee of its life cycle after it is copied from the idev->dev->iommu->iommu_dev. Track the user count of the iommu_dev. Postpone the exit routine using a completion, if refcount is unbalanced. The refcount inc/dec will be added in the following patch. Link: https://patch.msgid.link/r/33f28d64841b497eebef11b49a571e03103c5d24.1730836219.git.nicolinc@nvidia.com Suggested-by: Jason Gunthorpe <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 18f8199 commit 8607056

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

drivers/iommu/iommufd/selftest.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -533,14 +533,17 @@ static bool mock_domain_capable(struct device *dev, enum iommu_cap cap)
533533

534534
static struct iopf_queue *mock_iommu_iopf_queue;
535535

536-
static struct iommu_device mock_iommu_device = {
537-
};
536+
static struct mock_iommu_device {
537+
struct iommu_device iommu_dev;
538+
struct completion complete;
539+
refcount_t users;
540+
} mock_iommu;
538541

539542
static struct iommu_device *mock_probe_device(struct device *dev)
540543
{
541544
if (dev->bus != &iommufd_mock_bus_type.bus)
542545
return ERR_PTR(-ENODEV);
543-
return &mock_iommu_device;
546+
return &mock_iommu.iommu_dev;
544547
}
545548

546549
static void mock_domain_page_response(struct device *dev, struct iopf_fault *evt,
@@ -1556,24 +1559,27 @@ int __init iommufd_test_init(void)
15561559
if (rc)
15571560
goto err_platform;
15581561

1559-
rc = iommu_device_sysfs_add(&mock_iommu_device,
1562+
rc = iommu_device_sysfs_add(&mock_iommu.iommu_dev,
15601563
&selftest_iommu_dev->dev, NULL, "%s",
15611564
dev_name(&selftest_iommu_dev->dev));
15621565
if (rc)
15631566
goto err_bus;
15641567

1565-
rc = iommu_device_register_bus(&mock_iommu_device, &mock_ops,
1568+
rc = iommu_device_register_bus(&mock_iommu.iommu_dev, &mock_ops,
15661569
&iommufd_mock_bus_type.bus,
15671570
&iommufd_mock_bus_type.nb);
15681571
if (rc)
15691572
goto err_sysfs;
15701573

1574+
refcount_set(&mock_iommu.users, 1);
1575+
init_completion(&mock_iommu.complete);
1576+
15711577
mock_iommu_iopf_queue = iopf_queue_alloc("mock-iopfq");
15721578

15731579
return 0;
15741580

15751581
err_sysfs:
1576-
iommu_device_sysfs_remove(&mock_iommu_device);
1582+
iommu_device_sysfs_remove(&mock_iommu.iommu_dev);
15771583
err_bus:
15781584
bus_unregister(&iommufd_mock_bus_type.bus);
15791585
err_platform:
@@ -1583,15 +1589,32 @@ int __init iommufd_test_init(void)
15831589
return rc;
15841590
}
15851591

1592+
static void iommufd_test_wait_for_users(void)
1593+
{
1594+
if (refcount_dec_and_test(&mock_iommu.users))
1595+
return;
1596+
/*
1597+
* Time out waiting for iommu device user count to become 0.
1598+
*
1599+
* Note that this is just making an example here, since the selftest is
1600+
* built into the iommufd module, i.e. it only unplugs the iommu device
1601+
* when unloading the module. So, it is expected that this WARN_ON will
1602+
* not trigger, as long as any iommufd FDs are open.
1603+
*/
1604+
WARN_ON(!wait_for_completion_timeout(&mock_iommu.complete,
1605+
msecs_to_jiffies(10000)));
1606+
}
1607+
15861608
void iommufd_test_exit(void)
15871609
{
15881610
if (mock_iommu_iopf_queue) {
15891611
iopf_queue_free(mock_iommu_iopf_queue);
15901612
mock_iommu_iopf_queue = NULL;
15911613
}
15921614

1593-
iommu_device_sysfs_remove(&mock_iommu_device);
1594-
iommu_device_unregister_bus(&mock_iommu_device,
1615+
iommufd_test_wait_for_users();
1616+
iommu_device_sysfs_remove(&mock_iommu.iommu_dev);
1617+
iommu_device_unregister_bus(&mock_iommu.iommu_dev,
15951618
&iommufd_mock_bus_type.bus,
15961619
&iommufd_mock_bus_type.nb);
15971620
bus_unregister(&iommufd_mock_bus_type.bus);

0 commit comments

Comments
 (0)