vduse: Tie vduse mgmtdev and its device
[ Upstream commit 0e0348ac3f
]
vduse devices are not backed by any real devices such as PCI. Hence it
doesn't have any parent device linked to it.
Kernel driver model in [1] suggests to avoid an empty device
release callback.
Hence tie the mgmtdevice object's life cycle to an allocate dummy struct
device instead of static one.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/core-api/kobject.rst?h=v5.18-rc7#n284
Signed-off-by: Parav Pandit <parav@nvidia.com>
Message-Id: <20220613195223.473966-1-parav@nvidia.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Xie Yongji <xieyongji@bytedance.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
b34dbeb2b0
Коммит
65d7a723fd
|
@ -1466,16 +1466,12 @@ static char *vduse_devnode(struct device *dev, umode_t *mode)
|
|||
return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static void vduse_mgmtdev_release(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static struct device vduse_mgmtdev = {
|
||||
.init_name = "vduse",
|
||||
.release = vduse_mgmtdev_release,
|
||||
struct vduse_mgmt_dev {
|
||||
struct vdpa_mgmt_dev mgmt_dev;
|
||||
struct device dev;
|
||||
};
|
||||
|
||||
static struct vdpa_mgmt_dev mgmt_dev;
|
||||
static struct vduse_mgmt_dev *vduse_mgmt;
|
||||
|
||||
static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
|
||||
{
|
||||
|
@ -1500,7 +1496,7 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
|
|||
}
|
||||
set_dma_ops(&vdev->vdpa.dev, &vduse_dev_dma_ops);
|
||||
vdev->vdpa.dma_dev = &vdev->vdpa.dev;
|
||||
vdev->vdpa.mdev = &mgmt_dev;
|
||||
vdev->vdpa.mdev = &vduse_mgmt->mgmt_dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1545,34 +1541,52 @@ static struct virtio_device_id id_table[] = {
|
|||
{ 0 },
|
||||
};
|
||||
|
||||
static struct vdpa_mgmt_dev mgmt_dev = {
|
||||
.device = &vduse_mgmtdev,
|
||||
.id_table = id_table,
|
||||
.ops = &vdpa_dev_mgmtdev_ops,
|
||||
};
|
||||
static void vduse_mgmtdev_release(struct device *dev)
|
||||
{
|
||||
struct vduse_mgmt_dev *mgmt_dev;
|
||||
|
||||
mgmt_dev = container_of(dev, struct vduse_mgmt_dev, dev);
|
||||
kfree(mgmt_dev);
|
||||
}
|
||||
|
||||
static int vduse_mgmtdev_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = device_register(&vduse_mgmtdev);
|
||||
if (ret)
|
||||
vduse_mgmt = kzalloc(sizeof(*vduse_mgmt), GFP_KERNEL);
|
||||
if (!vduse_mgmt)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = dev_set_name(&vduse_mgmt->dev, "vduse");
|
||||
if (ret) {
|
||||
kfree(vduse_mgmt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = vdpa_mgmtdev_register(&mgmt_dev);
|
||||
vduse_mgmt->dev.release = vduse_mgmtdev_release;
|
||||
|
||||
ret = device_register(&vduse_mgmt->dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto dev_reg_err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
device_unregister(&vduse_mgmtdev);
|
||||
vduse_mgmt->mgmt_dev.id_table = id_table;
|
||||
vduse_mgmt->mgmt_dev.ops = &vdpa_dev_mgmtdev_ops;
|
||||
vduse_mgmt->mgmt_dev.device = &vduse_mgmt->dev;
|
||||
ret = vdpa_mgmtdev_register(&vduse_mgmt->mgmt_dev);
|
||||
if (ret)
|
||||
device_unregister(&vduse_mgmt->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
dev_reg_err:
|
||||
put_device(&vduse_mgmt->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void vduse_mgmtdev_exit(void)
|
||||
{
|
||||
vdpa_mgmtdev_unregister(&mgmt_dev);
|
||||
device_unregister(&vduse_mgmtdev);
|
||||
vdpa_mgmtdev_unregister(&vduse_mgmt->mgmt_dev);
|
||||
device_unregister(&vduse_mgmt->dev);
|
||||
}
|
||||
|
||||
static int vduse_init(void)
|
||||
|
|
Загрузка…
Ссылка в новой задаче