mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 07:08:21 -04:00
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:
committed by
Alex Williamson
parent
89345d5177
commit
da44c340c4
@@ -310,8 +310,8 @@ struct intel_vgpu_config {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define NR_MAX_INTEL_VGPU_TYPES 20
|
||||
struct intel_vgpu_type {
|
||||
struct mdev_type type;
|
||||
char name[16];
|
||||
const struct intel_vgpu_config *conf;
|
||||
unsigned int avail_instance;
|
||||
@@ -339,6 +339,7 @@ struct intel_gvt {
|
||||
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
|
||||
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
|
||||
struct mdev_parent parent;
|
||||
struct mdev_type **mdev_types;
|
||||
struct intel_vgpu_type *types;
|
||||
unsigned int num_types;
|
||||
struct intel_vgpu *idle_vgpu;
|
||||
|
||||
@@ -117,17 +117,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct intel_vgpu_type *type;
|
||||
unsigned int num = 0;
|
||||
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
|
||||
struct intel_vgpu_type *type =
|
||||
container_of(mtype, struct intel_vgpu_type, type);
|
||||
|
||||
type = &gvt->types[mtype_get_type_group_id(mtype)];
|
||||
if (!type)
|
||||
num = 0;
|
||||
else
|
||||
num = type->avail_instance;
|
||||
|
||||
return sprintf(buf, "%u\n", num);
|
||||
return sprintf(buf, "%u\n", type->avail_instance);
|
||||
}
|
||||
|
||||
static ssize_t device_api_show(struct mdev_type *mtype,
|
||||
@@ -139,12 +132,8 @@ static ssize_t device_api_show(struct mdev_type *mtype,
|
||||
static ssize_t description_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
struct intel_vgpu_type *type;
|
||||
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
|
||||
|
||||
type = &gvt->types[mtype_get_type_group_id(mtype)];
|
||||
if (!type)
|
||||
return 0;
|
||||
struct intel_vgpu_type *type =
|
||||
container_of(mtype, struct intel_vgpu_type, type);
|
||||
|
||||
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
|
||||
"fence: %d\nresolution: %s\n"
|
||||
@@ -158,14 +147,7 @@ static ssize_t description_show(struct mdev_type *mtype,
|
||||
static ssize_t name_show(struct mdev_type *mtype,
|
||||
struct mdev_type_attribute *attr, char *buf)
|
||||
{
|
||||
struct intel_vgpu_type *type;
|
||||
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
|
||||
|
||||
type = &gvt->types[mtype_get_type_group_id(mtype)];
|
||||
if (!type)
|
||||
return 0;
|
||||
|
||||
return sprintf(buf, "%s\n", type->name);
|
||||
return sprintf(buf, "%s\n", mtype->sysfs_name);
|
||||
}
|
||||
|
||||
static MDEV_TYPE_ATTR_RO(available_instances);
|
||||
@@ -173,7 +155,7 @@ static MDEV_TYPE_ATTR_RO(device_api);
|
||||
static MDEV_TYPE_ATTR_RO(description);
|
||||
static MDEV_TYPE_ATTR_RO(name);
|
||||
|
||||
static struct attribute *gvt_type_attrs[] = {
|
||||
static const struct attribute *gvt_type_attrs[] = {
|
||||
&mdev_type_attr_available_instances.attr,
|
||||
&mdev_type_attr_device_api.attr,
|
||||
&mdev_type_attr_description.attr,
|
||||
@@ -181,51 +163,6 @@ static struct attribute *gvt_type_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group *gvt_vgpu_type_groups[] = {
|
||||
[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
|
||||
};
|
||||
|
||||
static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
|
||||
{
|
||||
int i, j;
|
||||
struct intel_vgpu_type *type;
|
||||
struct attribute_group *group;
|
||||
|
||||
for (i = 0; i < gvt->num_types; i++) {
|
||||
type = &gvt->types[i];
|
||||
|
||||
group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
|
||||
if (!group)
|
||||
goto unwind;
|
||||
|
||||
group->name = type->name;
|
||||
group->attrs = gvt_type_attrs;
|
||||
gvt_vgpu_type_groups[i] = group;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
unwind:
|
||||
for (j = 0; j < i; j++) {
|
||||
group = gvt_vgpu_type_groups[j];
|
||||
kfree(group);
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
|
||||
{
|
||||
int i;
|
||||
struct attribute_group *group;
|
||||
|
||||
for (i = 0; i < gvt->num_types; i++) {
|
||||
group = gvt_vgpu_type_groups[i];
|
||||
gvt_vgpu_type_groups[i] = NULL;
|
||||
kfree(group);
|
||||
}
|
||||
}
|
||||
|
||||
static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
||||
unsigned long size)
|
||||
{
|
||||
@@ -1547,16 +1484,11 @@ static const struct attribute_group *intel_vgpu_groups[] = {
|
||||
static int intel_vgpu_init_dev(struct vfio_device *vfio_dev)
|
||||
{
|
||||
struct mdev_device *mdev = to_mdev_device(vfio_dev->dev);
|
||||
struct device *pdev = mdev_parent_dev(mdev);
|
||||
struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
|
||||
struct intel_vgpu_type *type;
|
||||
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
|
||||
struct intel_vgpu_type *type =
|
||||
container_of(mdev->type, struct intel_vgpu_type, type);
|
||||
|
||||
type = &gvt->types[mdev_get_type_group_id(mdev)];
|
||||
if (!type)
|
||||
return -EINVAL;
|
||||
|
||||
vgpu->gvt = gvt;
|
||||
vgpu->gvt = kdev_to_i915(mdev_parent_dev(mdev))->gvt;
|
||||
return intel_gvt_create_vgpu(vgpu, type->conf);
|
||||
}
|
||||
|
||||
@@ -1625,7 +1557,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
|
||||
},
|
||||
.probe = intel_vgpu_probe,
|
||||
.remove = intel_vgpu_remove,
|
||||
.supported_type_groups = gvt_vgpu_type_groups,
|
||||
.types_attrs = gvt_type_attrs,
|
||||
};
|
||||
|
||||
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
|
||||
@@ -1924,7 +1856,6 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
|
||||
return;
|
||||
|
||||
mdev_unregister_parent(&gvt->parent);
|
||||
intel_gvt_cleanup_vgpu_type_groups(gvt);
|
||||
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
|
||||
intel_gvt_clean_vgpu_types(gvt);
|
||||
|
||||
@@ -2024,20 +1955,15 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
|
||||
|
||||
intel_gvt_debugfs_init(gvt);
|
||||
|
||||
ret = intel_gvt_init_vgpu_type_groups(gvt);
|
||||
ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
|
||||
&intel_vgpu_mdev_driver,
|
||||
gvt->mdev_types, gvt->num_types);
|
||||
if (ret)
|
||||
goto out_destroy_idle_vgpu;
|
||||
|
||||
ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
|
||||
&intel_vgpu_mdev_driver);
|
||||
if (ret)
|
||||
goto out_cleanup_vgpu_type_groups;
|
||||
|
||||
gvt_dbg_core("gvt device initialization is done\n");
|
||||
return 0;
|
||||
|
||||
out_cleanup_vgpu_type_groups:
|
||||
intel_gvt_cleanup_vgpu_type_groups(gvt);
|
||||
out_destroy_idle_vgpu:
|
||||
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
|
||||
intel_gvt_debugfs_clean(gvt);
|
||||
|
||||
@@ -113,13 +113,18 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
|
||||
if (!gvt->types)
|
||||
return -ENOMEM;
|
||||
|
||||
gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types),
|
||||
GFP_KERNEL);
|
||||
if (!gvt->mdev_types)
|
||||
goto out_free_types;
|
||||
|
||||
for (i = 0; i < num_types; ++i) {
|
||||
const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
|
||||
|
||||
if (low_avail / conf->low_mm == 0)
|
||||
break;
|
||||
if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
|
||||
goto out_free_types;
|
||||
goto out_free_mdev_types;
|
||||
|
||||
sprintf(gvt->types[i].name, "GVTg_V%u_%s",
|
||||
GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
|
||||
@@ -131,11 +136,16 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
|
||||
i, gvt->types[i].name, gvt->types[i].avail_instance,
|
||||
conf->low_mm, conf->high_mm, conf->fence,
|
||||
conf->weight, vgpu_edid_str(conf->edid));
|
||||
|
||||
gvt->mdev_types[i] = &gvt->types[i].type;
|
||||
gvt->mdev_types[i]->sysfs_name = gvt->types[i].name;
|
||||
}
|
||||
|
||||
gvt->num_types = i;
|
||||
return 0;
|
||||
|
||||
out_free_mdev_types:
|
||||
kfree(gvt->mdev_types);
|
||||
out_free_types:
|
||||
kfree(gvt->types);
|
||||
return -EINVAL;
|
||||
@@ -143,6 +153,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
|
||||
|
||||
void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
|
||||
{
|
||||
kfree(gvt->mdev_types);
|
||||
kfree(gvt->types);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user