vfio/mdev: consolidate all the description sysfs into the core code

Every driver just emits a string, simply add a method to the mdev_driver
to return it and provide a standard sysfs show function.

Remove the now unused types_attrs field in struct mdev_driver and the
support code for it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
Link: https://lore.kernel.org/r/20220923092652.100656-14-hch@lst.de
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Christoph Hellwig 2022-09-23 11:26:51 +02:00 коммит произвёл Alex Williamson
Родитель f2fbc72e6d
Коммит 685a1537f4
7 изменённых файлов: 46 добавлений и 59 удалений

Просмотреть файл

@ -104,7 +104,7 @@ structure to represent a mediated device's driver::
int (*probe) (struct mdev_device *dev); int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev); void (*remove) (struct mdev_device *dev);
unsigned int (*get_available)(struct mdev_type *mtype); unsigned int (*get_available)(struct mdev_type *mtype);
const struct attribute * const *types_attrs; ssize_t (*show_description)(struct mdev_type *mtype, char *buf);
struct device_driver driver; struct device_driver driver;
}; };
@ -222,7 +222,7 @@ Directories and files under the sysfs for Each Physical Device
* description * description
This attribute should show brief features/description of the type. This is This attribute can show brief features/description of the type. This is an
optional attribute. optional attribute.
Directories and Files Under the sysfs for Each mdev Device Directories and Files Under the sysfs for Each mdev Device

Просмотреть файл

@ -113,8 +113,7 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
struct kvm_memory_slot *slot, struct kvm_memory_slot *slot,
struct kvm_page_track_notifier_node *node); struct kvm_page_track_notifier_node *node);
static ssize_t description_show(struct mdev_type *mtype, static ssize_t intel_vgpu_show_description(struct mdev_type *mtype, char *buf)
struct mdev_type_attribute *attr, char *buf)
{ {
struct intel_vgpu_type *type = struct intel_vgpu_type *type =
container_of(mtype, struct intel_vgpu_type, type); container_of(mtype, struct intel_vgpu_type, type);
@ -128,13 +127,6 @@ static ssize_t description_show(struct mdev_type *mtype,
type->conf->weight); type->conf->weight);
} }
static MDEV_TYPE_ATTR_RO(description);
static const struct attribute *gvt_type_attrs[] = {
&mdev_type_attr_description.attr,
NULL,
};
static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn, static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size) unsigned long size)
{ {
@ -1549,10 +1541,10 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.dev_groups = intel_vgpu_groups, .dev_groups = intel_vgpu_groups,
}, },
.probe = intel_vgpu_probe, .probe = intel_vgpu_probe,
.remove = intel_vgpu_remove, .remove = intel_vgpu_remove,
.get_available = intel_vgpu_get_available, .get_available = intel_vgpu_get_available,
.types_attrs = gvt_type_attrs, .show_description = intel_vgpu_show_description,
}; };
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn) int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)

Просмотреть файл

@ -55,7 +55,7 @@ struct bus_type mdev_bus_type = {
**/ **/
int mdev_register_driver(struct mdev_driver *drv) int mdev_register_driver(struct mdev_driver *drv)
{ {
if (!drv->types_attrs || !drv->device_api) if (!drv->device_api)
return -EINVAL; return -EINVAL;
/* initialize common driver fields */ /* initialize common driver fields */

Просмотреть файл

@ -14,7 +14,19 @@
#include "mdev_private.h" #include "mdev_private.h"
/* Static functions */ struct mdev_type_attribute {
struct attribute attr;
ssize_t (*show)(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf);
ssize_t (*store)(struct mdev_type *mtype,
struct mdev_type_attribute *attr, const char *buf,
size_t count);
};
#define MDEV_TYPE_ATTR_RO(_name) \
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RO(_name)
#define MDEV_TYPE_ATTR_WO(_name) \
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_WO(_name)
static ssize_t mdev_type_attr_show(struct kobject *kobj, static ssize_t mdev_type_attr_show(struct kobject *kobj,
struct attribute *__attr, char *buf) struct attribute *__attr, char *buf)
@ -100,16 +112,35 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
} }
static MDEV_TYPE_ATTR_RO(available_instances); static MDEV_TYPE_ATTR_RO(available_instances);
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
{
return mtype->parent->mdev_driver->show_description(mtype, buf);
}
static MDEV_TYPE_ATTR_RO(description);
static struct attribute *mdev_types_core_attrs[] = { static struct attribute *mdev_types_core_attrs[] = {
&mdev_type_attr_create.attr, &mdev_type_attr_create.attr,
&mdev_type_attr_device_api.attr, &mdev_type_attr_device_api.attr,
&mdev_type_attr_name.attr, &mdev_type_attr_name.attr,
&mdev_type_attr_available_instances.attr, &mdev_type_attr_available_instances.attr,
&mdev_type_attr_description.attr,
NULL, NULL,
}; };
static umode_t mdev_types_core_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
if (attr == &mdev_type_attr_description.attr &&
!to_mdev_type(kobj)->parent->mdev_driver->show_description)
return 0;
return attr->mode;
}
static struct attribute_group mdev_type_core_group = { static struct attribute_group mdev_type_core_group = {
.attrs = mdev_types_core_attrs, .attrs = mdev_types_core_attrs,
.is_visible = mdev_types_core_is_visible,
}; };
static const struct attribute_group *mdev_type_groups[] = { static const struct attribute_group *mdev_type_groups[] = {
@ -155,13 +186,8 @@ static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
goto attr_devices_failed; goto attr_devices_failed;
} }
ret = sysfs_create_files(&type->kobj, parent->mdev_driver->types_attrs);
if (ret)
goto attrs_failed;
return 0; return 0;
attrs_failed:
kobject_put(type->devices_kobj);
attr_devices_failed: attr_devices_failed:
kobject_del(&type->kobj); kobject_del(&type->kobj);
kobject_put(&type->kobj); kobject_put(&type->kobj);
@ -170,8 +196,6 @@ attr_devices_failed:
static void mdev_type_remove(struct mdev_type *type) static void mdev_type_remove(struct mdev_type *type)
{ {
sysfs_remove_files(&type->kobj, type->parent->mdev_driver->types_attrs);
kobject_put(type->devices_kobj); kobject_put(type->devices_kobj);
kobject_del(&type->kobj); kobject_del(&type->kobj);
kobject_put(&type->kobj); kobject_put(&type->kobj);

Просмотреть файл

@ -52,28 +52,13 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
return container_of(dev, struct mdev_device, dev); return container_of(dev, struct mdev_device, dev);
} }
/* interface for exporting mdev supported type attributes */
struct mdev_type_attribute {
struct attribute attr;
ssize_t (*show)(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf);
ssize_t (*store)(struct mdev_type *mtype,
struct mdev_type_attribute *attr, const char *buf,
size_t count);
};
#define MDEV_TYPE_ATTR_RO(_name) \
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RO(_name)
#define MDEV_TYPE_ATTR_WO(_name) \
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_WO(_name)
/** /**
* struct mdev_driver - Mediated device driver * struct mdev_driver - Mediated device driver
* @device_api: string to return for the device_api sysfs * @device_api: string to return for the device_api sysfs
* @probe: called when new device created * @probe: called when new device created
* @remove: called when device removed * @remove: called when device removed
* @get_available: Return the max number of instances that can be created * @get_available: Return the max number of instances that can be created
* @types_attrs: attributes to the type kobjects. * @show_description: Print a description of the mtype
* @driver: device driver structure * @driver: device driver structure
**/ **/
struct mdev_driver { struct mdev_driver {
@ -81,7 +66,7 @@ struct mdev_driver {
int (*probe)(struct mdev_device *dev); int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev); void (*remove)(struct mdev_device *dev);
unsigned int (*get_available)(struct mdev_type *mtype); unsigned int (*get_available)(struct mdev_type *mtype);
const struct attribute * const *types_attrs; ssize_t (*show_description)(struct mdev_type *mtype, char *buf);
struct device_driver driver; struct device_driver driver;
}; };

Просмотреть файл

@ -1350,8 +1350,7 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL, NULL,
}; };
static ssize_t description_show(struct mdev_type *mtype, static ssize_t mbochs_show_description(struct mdev_type *mtype, char *buf)
struct mdev_type_attribute *attr, char *buf)
{ {
struct mbochs_type *type = struct mbochs_type *type =
container_of(mtype, struct mbochs_type, type); container_of(mtype, struct mbochs_type, type);
@ -1359,7 +1358,6 @@ static ssize_t description_show(struct mdev_type *mtype,
return sprintf(buf, "virtual display, %d MB video memory\n", return sprintf(buf, "virtual display, %d MB video memory\n",
type ? type->mbytes : 0); type ? type->mbytes : 0);
} }
static MDEV_TYPE_ATTR_RO(description);
static unsigned int mbochs_get_available(struct mdev_type *mtype) static unsigned int mbochs_get_available(struct mdev_type *mtype)
{ {
@ -1369,11 +1367,6 @@ static unsigned int mbochs_get_available(struct mdev_type *mtype)
return atomic_read(&mbochs_avail_mbytes) / type->mbytes; return atomic_read(&mbochs_avail_mbytes) / type->mbytes;
} }
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_description.attr,
NULL,
};
static const struct vfio_device_ops mbochs_dev_ops = { static const struct vfio_device_ops mbochs_dev_ops = {
.close_device = mbochs_close_device, .close_device = mbochs_close_device,
.init = mbochs_init_dev, .init = mbochs_init_dev,
@ -1395,7 +1388,7 @@ static struct mdev_driver mbochs_driver = {
.probe = mbochs_probe, .probe = mbochs_probe,
.remove = mbochs_remove, .remove = mbochs_remove,
.get_available = mbochs_get_available, .get_available = mbochs_get_available,
.types_attrs = mdev_types_attrs, .show_description = mbochs_show_description,
}; };
static const struct file_operations vd_fops = { static const struct file_operations vd_fops = {

Просмотреть файл

@ -661,26 +661,19 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL, NULL,
}; };
static ssize_t description_show(struct mdev_type *mtype, static ssize_t mdpy_show_description(struct mdev_type *mtype, char *buf)
struct mdev_type_attribute *attr, char *buf)
{ {
struct mdpy_type *type = container_of(mtype, struct mdpy_type, type); struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
return sprintf(buf, "virtual display, %dx%d framebuffer\n", return sprintf(buf, "virtual display, %dx%d framebuffer\n",
type->width, type->height); type->width, type->height);
} }
static MDEV_TYPE_ATTR_RO(description);
static unsigned int mdpy_get_available(struct mdev_type *mtype) static unsigned int mdpy_get_available(struct mdev_type *mtype)
{ {
return max_devices - mdpy_count; return max_devices - mdpy_count;
} }
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_description.attr,
NULL,
};
static const struct vfio_device_ops mdpy_dev_ops = { static const struct vfio_device_ops mdpy_dev_ops = {
.init = mdpy_init_dev, .init = mdpy_init_dev,
.release = mdpy_release_dev, .release = mdpy_release_dev,
@ -701,7 +694,7 @@ static struct mdev_driver mdpy_driver = {
.probe = mdpy_probe, .probe = mdpy_probe,
.remove = mdpy_remove, .remove = mdpy_remove,
.get_available = mdpy_get_available, .get_available = mdpy_get_available,
.types_attrs = mdev_types_attrs, .show_description = mdpy_show_description,
}; };
static const struct file_operations vd_fops = { static const struct file_operations vd_fops = {