vfio/mdev: simplify mdev_type handling
Instead of abusing struct attribute_group to control initialization of struct mdev_type, just define the actual attributes in the mdev_driver, allocate the mdev_type structures in the caller and pass them to mdev_register_parent. This allows the caller to use container_of to get at the containing structure and thus significantly simplify the code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com> Reviewed-by: Eric Farman <farman@linux.ibm.com> Link: https://lore.kernel.org/r/20220923092652.100656-6-hch@lst.de Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
89345d5177
commit
da44c340c4
17 changed files with 165 additions and 326 deletions
|
|
@ -99,23 +99,27 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
|
|||
#define MBOCHS_TYPE_2 "medium"
|
||||
#define MBOCHS_TYPE_3 "large"
|
||||
|
||||
static const struct mbochs_type {
|
||||
static struct mbochs_type {
|
||||
struct mdev_type type;
|
||||
const char *name;
|
||||
u32 mbytes;
|
||||
u32 max_x;
|
||||
u32 max_y;
|
||||
} mbochs_types[] = {
|
||||
{
|
||||
.type.sysfs_name = MBOCHS_TYPE_1,
|
||||
.name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
|
||||
.mbytes = 4,
|
||||
.max_x = 800,
|
||||
.max_y = 600,
|
||||
}, {
|
||||
.type.sysfs_name = MBOCHS_TYPE_2,
|
||||
.name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
|
||||
.mbytes = 16,
|
||||
.max_x = 1920,
|
||||
.max_y = 1440,
|
||||
}, {
|
||||
.type.sysfs_name = MBOCHS_TYPE_3,
|
||||
.name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
|
||||
.mbytes = 64,
|
||||
.max_x = 0,
|
||||
|
|
@ -123,6 +127,11 @@ static const struct mbochs_type {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mdev_type *mbochs_mdev_types[] = {
|
||||
&mbochs_types[0].type,
|
||||
&mbochs_types[1].type,
|
||||
&mbochs_types[2].type,
|
||||
};
|
||||
|
||||
static dev_t mbochs_devt;
|
||||
static struct class *mbochs_class;
|
||||
|
|
@ -510,8 +519,8 @@ static int mbochs_init_dev(struct vfio_device *vdev)
|
|||
struct mdev_state *mdev_state =
|
||||
container_of(vdev, struct mdev_state, vdev);
|
||||
struct mdev_device *mdev = to_mdev_device(vdev->dev);
|
||||
const struct mbochs_type *type =
|
||||
&mbochs_types[mdev_get_type_group_id(mdev)];
|
||||
struct mbochs_type *type =
|
||||
container_of(mdev->type, struct mbochs_type, type);
|
||||
int avail_mbytes = atomic_read(&mbochs_avail_mbytes);
|
||||
int ret = -ENOMEM;
|
||||
|
||||
|
|
@ -1345,8 +1354,8 @@ static const struct attribute_group *mdev_dev_groups[] = {
|
|||
static ssize_t name_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
const struct mbochs_type *type =
|
||||
&mbochs_types[mtype_get_type_group_id(mtype)];
|
||||
struct mbochs_type *type =
|
||||
container_of(mtype, struct mbochs_type, type);
|
||||
|
||||
return sprintf(buf, "%s\n", type->name);
|
||||
}
|
||||
|
|
@ -1355,8 +1364,8 @@ static MDEV_TYPE_ATTR_RO(name);
|
|||
static ssize_t description_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
const struct mbochs_type *type =
|
||||
&mbochs_types[mtype_get_type_group_id(mtype)];
|
||||
struct mbochs_type *type =
|
||||
container_of(mtype, struct mbochs_type, type);
|
||||
|
||||
return sprintf(buf, "virtual display, %d MB video memory\n",
|
||||
type ? type->mbytes : 0);
|
||||
|
|
@ -1367,8 +1376,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
|
|||
struct mdev_type_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
const struct mbochs_type *type =
|
||||
&mbochs_types[mtype_get_type_group_id(mtype)];
|
||||
struct mbochs_type *type =
|
||||
container_of(mtype, struct mbochs_type, type);
|
||||
int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes;
|
||||
|
||||
return sprintf(buf, "%d\n", count);
|
||||
|
|
@ -1382,7 +1391,7 @@ static ssize_t device_api_show(struct mdev_type *mtype,
|
|||
}
|
||||
static MDEV_TYPE_ATTR_RO(device_api);
|
||||
|
||||
static struct attribute *mdev_types_attrs[] = {
|
||||
static const struct attribute *mdev_types_attrs[] = {
|
||||
&mdev_type_attr_name.attr,
|
||||
&mdev_type_attr_description.attr,
|
||||
&mdev_type_attr_device_api.attr,
|
||||
|
|
@ -1390,28 +1399,6 @@ static struct attribute *mdev_types_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group1 = {
|
||||
.name = MBOCHS_TYPE_1,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group2 = {
|
||||
.name = MBOCHS_TYPE_2,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group3 = {
|
||||
.name = MBOCHS_TYPE_3,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group *mdev_type_groups[] = {
|
||||
&mdev_type_group1,
|
||||
&mdev_type_group2,
|
||||
&mdev_type_group3,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct vfio_device_ops mbochs_dev_ops = {
|
||||
.close_device = mbochs_close_device,
|
||||
.init = mbochs_init_dev,
|
||||
|
|
@ -1431,7 +1418,7 @@ static struct mdev_driver mbochs_driver = {
|
|||
},
|
||||
.probe = mbochs_probe,
|
||||
.remove = mbochs_remove,
|
||||
.supported_type_groups = mdev_type_groups,
|
||||
.types_attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static const struct file_operations vd_fops = {
|
||||
|
|
@ -1476,7 +1463,9 @@ static int __init mbochs_dev_init(void)
|
|||
if (ret)
|
||||
goto err_class;
|
||||
|
||||
ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
|
||||
ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver,
|
||||
mbochs_mdev_types,
|
||||
ARRAY_SIZE(mbochs_mdev_types));
|
||||
if (ret)
|
||||
goto err_device;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ MODULE_PARM_DESC(count, "number of " MDPY_NAME " devices");
|
|||
#define MDPY_TYPE_2 "xga"
|
||||
#define MDPY_TYPE_3 "hd"
|
||||
|
||||
static const struct mdpy_type {
|
||||
static struct mdpy_type {
|
||||
struct mdev_type type;
|
||||
const char *name;
|
||||
u32 format;
|
||||
u32 bytepp;
|
||||
|
|
@ -59,18 +60,21 @@ static const struct mdpy_type {
|
|||
u32 height;
|
||||
} mdpy_types[] = {
|
||||
{
|
||||
.type.sysfs_name = MDPY_TYPE_1,
|
||||
.name = MDPY_CLASS_NAME "-" MDPY_TYPE_1,
|
||||
.format = DRM_FORMAT_XRGB8888,
|
||||
.bytepp = 4,
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
}, {
|
||||
.type.sysfs_name = MDPY_TYPE_2,
|
||||
.name = MDPY_CLASS_NAME "-" MDPY_TYPE_2,
|
||||
.format = DRM_FORMAT_XRGB8888,
|
||||
.bytepp = 4,
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
}, {
|
||||
.type.sysfs_name = MDPY_TYPE_3,
|
||||
.name = MDPY_CLASS_NAME "-" MDPY_TYPE_3,
|
||||
.format = DRM_FORMAT_XRGB8888,
|
||||
.bytepp = 4,
|
||||
|
|
@ -79,6 +83,12 @@ static const struct mdpy_type {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mdev_type *mdpy_mdev_types[] = {
|
||||
&mdpy_types[0].type,
|
||||
&mdpy_types[1].type,
|
||||
&mdpy_types[2].type,
|
||||
};
|
||||
|
||||
static dev_t mdpy_devt;
|
||||
static struct class *mdpy_class;
|
||||
static struct cdev mdpy_cdev;
|
||||
|
|
@ -222,7 +232,7 @@ static int mdpy_init_dev(struct vfio_device *vdev)
|
|||
container_of(vdev, struct mdev_state, vdev);
|
||||
struct mdev_device *mdev = to_mdev_device(vdev->dev);
|
||||
const struct mdpy_type *type =
|
||||
&mdpy_types[mdev_get_type_group_id(mdev)];
|
||||
container_of(mdev->type, struct mdpy_type, type);
|
||||
u32 fbsize;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
|
|
@ -655,8 +665,7 @@ static const struct attribute_group *mdev_dev_groups[] = {
|
|||
static ssize_t name_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
const struct mdpy_type *type =
|
||||
&mdpy_types[mtype_get_type_group_id(mtype)];
|
||||
struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
|
||||
|
||||
return sprintf(buf, "%s\n", type->name);
|
||||
}
|
||||
|
|
@ -665,8 +674,7 @@ static MDEV_TYPE_ATTR_RO(name);
|
|||
static ssize_t description_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
const struct mdpy_type *type =
|
||||
&mdpy_types[mtype_get_type_group_id(mtype)];
|
||||
struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
|
||||
|
||||
return sprintf(buf, "virtual display, %dx%d framebuffer\n",
|
||||
type->width, type->height);
|
||||
|
|
@ -688,7 +696,7 @@ static ssize_t device_api_show(struct mdev_type *mtype,
|
|||
}
|
||||
static MDEV_TYPE_ATTR_RO(device_api);
|
||||
|
||||
static struct attribute *mdev_types_attrs[] = {
|
||||
static const struct attribute *mdev_types_attrs[] = {
|
||||
&mdev_type_attr_name.attr,
|
||||
&mdev_type_attr_description.attr,
|
||||
&mdev_type_attr_device_api.attr,
|
||||
|
|
@ -696,28 +704,6 @@ static struct attribute *mdev_types_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group1 = {
|
||||
.name = MDPY_TYPE_1,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group2 = {
|
||||
.name = MDPY_TYPE_2,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group3 = {
|
||||
.name = MDPY_TYPE_3,
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group *mdev_type_groups[] = {
|
||||
&mdev_type_group1,
|
||||
&mdev_type_group2,
|
||||
&mdev_type_group3,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct vfio_device_ops mdpy_dev_ops = {
|
||||
.init = mdpy_init_dev,
|
||||
.release = mdpy_release_dev,
|
||||
|
|
@ -736,7 +722,7 @@ static struct mdev_driver mdpy_driver = {
|
|||
},
|
||||
.probe = mdpy_probe,
|
||||
.remove = mdpy_remove,
|
||||
.supported_type_groups = mdev_type_groups,
|
||||
.types_attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static const struct file_operations vd_fops = {
|
||||
|
|
@ -779,7 +765,9 @@ static int __init mdpy_dev_init(void)
|
|||
if (ret)
|
||||
goto err_class;
|
||||
|
||||
ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver);
|
||||
ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver,
|
||||
mdpy_mdev_types,
|
||||
ARRAY_SIZE(mdpy_mdev_types));
|
||||
if (ret)
|
||||
goto err_device;
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,20 @@ struct mdev_state {
|
|||
int nr_ports;
|
||||
};
|
||||
|
||||
static struct mtty_type {
|
||||
struct mdev_type type;
|
||||
int nr_ports;
|
||||
const char *name;
|
||||
} mtty_types[2] = {
|
||||
{ .nr_ports = 1, .type.sysfs_name = "1", .name = "Single port serial" },
|
||||
{ .nr_ports = 2, .type.sysfs_name = "2", .name = "Dual port serial" },
|
||||
};
|
||||
|
||||
static struct mdev_type *mtty_mdev_types[] = {
|
||||
&mtty_types[0].type,
|
||||
&mtty_types[1].type,
|
||||
};
|
||||
|
||||
static atomic_t mdev_avail_ports = ATOMIC_INIT(MAX_MTTYS);
|
||||
|
||||
static const struct file_operations vd_fops = {
|
||||
|
|
@ -707,17 +721,19 @@ static int mtty_init_dev(struct vfio_device *vdev)
|
|||
struct mdev_state *mdev_state =
|
||||
container_of(vdev, struct mdev_state, vdev);
|
||||
struct mdev_device *mdev = to_mdev_device(vdev->dev);
|
||||
int nr_ports = mdev_get_type_group_id(mdev) + 1;
|
||||
struct mtty_type *type =
|
||||
container_of(mdev->type, struct mtty_type, type);
|
||||
int avail_ports = atomic_read(&mdev_avail_ports);
|
||||
int ret;
|
||||
|
||||
do {
|
||||
if (avail_ports < nr_ports)
|
||||
if (avail_ports < type->nr_ports)
|
||||
return -ENOSPC;
|
||||
} while (!atomic_try_cmpxchg(&mdev_avail_ports,
|
||||
&avail_ports, avail_ports - nr_ports));
|
||||
&avail_ports,
|
||||
avail_ports - type->nr_ports));
|
||||
|
||||
mdev_state->nr_ports = nr_ports;
|
||||
mdev_state->nr_ports = type->nr_ports;
|
||||
mdev_state->irq_index = -1;
|
||||
mdev_state->s[0].max_fifo_size = MAX_FIFO_SIZE;
|
||||
mdev_state->s[1].max_fifo_size = MAX_FIFO_SIZE;
|
||||
|
|
@ -735,7 +751,7 @@ static int mtty_init_dev(struct vfio_device *vdev)
|
|||
return 0;
|
||||
|
||||
err_nr_ports:
|
||||
atomic_add(nr_ports, &mdev_avail_ports);
|
||||
atomic_add(type->nr_ports, &mdev_avail_ports);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1242,11 +1258,9 @@ static const struct attribute_group *mdev_dev_groups[] = {
|
|||
static ssize_t name_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
static const char *name_str[2] = { "Single port serial",
|
||||
"Dual port serial" };
|
||||
struct mtty_type *type = container_of(mtype, struct mtty_type, type);
|
||||
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
name_str[mtype_get_type_group_id(mtype)]);
|
||||
return sysfs_emit(buf, "%s\n", type->name);
|
||||
}
|
||||
|
||||
static MDEV_TYPE_ATTR_RO(name);
|
||||
|
|
@ -1255,9 +1269,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
|
|||
struct mdev_type_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
unsigned int ports = mtype_get_type_group_id(mtype) + 1;
|
||||
struct mtty_type *type = container_of(mtype, struct mtty_type, type);
|
||||
|
||||
return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) / ports);
|
||||
return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) /
|
||||
type->nr_ports);
|
||||
}
|
||||
|
||||
static MDEV_TYPE_ATTR_RO(available_instances);
|
||||
|
|
@ -1270,29 +1285,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
|
|||
|
||||
static MDEV_TYPE_ATTR_RO(device_api);
|
||||
|
||||
static struct attribute *mdev_types_attrs[] = {
|
||||
static const struct attribute *mdev_types_attrs[] = {
|
||||
&mdev_type_attr_name.attr,
|
||||
&mdev_type_attr_device_api.attr,
|
||||
&mdev_type_attr_available_instances.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group1 = {
|
||||
.name = "1",
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group mdev_type_group2 = {
|
||||
.name = "2",
|
||||
.attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static struct attribute_group *mdev_type_groups[] = {
|
||||
&mdev_type_group1,
|
||||
&mdev_type_group2,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct vfio_device_ops mtty_dev_ops = {
|
||||
.name = "vfio-mtty",
|
||||
.init = mtty_init_dev,
|
||||
|
|
@ -1311,7 +1310,7 @@ static struct mdev_driver mtty_driver = {
|
|||
},
|
||||
.probe = mtty_probe,
|
||||
.remove = mtty_remove,
|
||||
.supported_type_groups = mdev_type_groups,
|
||||
.types_attrs = mdev_types_attrs,
|
||||
};
|
||||
|
||||
static void mtty_device_release(struct device *dev)
|
||||
|
|
@ -1363,7 +1362,8 @@ static int __init mtty_dev_init(void)
|
|||
goto err_class;
|
||||
|
||||
ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
|
||||
&mtty_driver);
|
||||
&mtty_driver, mtty_mdev_types,
|
||||
ARRAY_SIZE(mtty_mdev_types));
|
||||
if (ret)
|
||||
goto err_device;
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue