Skip to content

Commit

Permalink
vfio/mdev: simplify mdev_type handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and awilliam committed Oct 4, 2022
1 parent 89345d5 commit da44c34
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 326 deletions.
2 changes: 1 addition & 1 deletion Documentation/driver-api/vfio-mediated-device.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
struct attribute_group **supported_type_groups;
const struct attribute * const *types_attrs;
struct device_driver driver;
};

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gvt/gvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
102 changes: 14 additions & 88 deletions drivers/gpu/drm/i915/gvt/kvmgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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"
Expand All @@ -158,74 +147,22 @@ 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);
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,
&mdev_type_attr_name.attr,
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)
{
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
if (ret)
goto out_destroy_idle_vgpu;

ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
&intel_vgpu_mdev_driver);
&intel_vgpu_mdev_driver,
gvt->mdev_types, gvt->num_types);
if (ret)
goto out_cleanup_vgpu_type_groups;
goto out_destroy_idle_vgpu;

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);
Expand Down
13 changes: 12 additions & 1 deletion drivers/gpu/drm/i915/gvt/vgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -131,18 +136,24 @@ 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;
}

void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
{
kfree(gvt->mdev_types);
kfree(gvt->types);
}

Expand Down
6 changes: 4 additions & 2 deletions drivers/s390/cio/vfio_ccw_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private)
mutex_destroy(&private->io_mutex);
kfree(private);
}

static int vfio_ccw_sch_probe(struct subchannel *sch)
{
struct pmcw *pmcw = &sch->schib.pmcw;
Expand All @@ -221,8 +220,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)

dev_set_drvdata(&sch->dev, private);

private->mdev_type.sysfs_name = "io";
private->mdev_types[0] = &private->mdev_type;
ret = mdev_register_parent(&private->parent, &sch->dev,
&vfio_ccw_mdev_driver);
&vfio_ccw_mdev_driver,
private->mdev_types, 1);
if (ret)
goto out_free;

Expand Down
14 changes: 2 additions & 12 deletions drivers/s390/cio/vfio_ccw_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(available_instances);

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_group = {
.name = "io",
.attrs = mdev_types_attrs,
};

static struct attribute_group *mdev_type_groups[] = {
&mdev_type_group,
NULL,
};

static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)
{
struct vfio_ccw_private *private =
Expand Down Expand Up @@ -646,5 +636,5 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
.supported_type_groups = mdev_type_groups,
.types_attrs = mdev_types_attrs,
};
2 changes: 2 additions & 0 deletions drivers/s390/cio/vfio_ccw_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ struct vfio_ccw_private {
struct completion release_comp;

struct mdev_parent parent;
struct mdev_type mdev_type;
struct mdev_type *mdev_types[1];
} __aligned(8);

int vfio_ccw_sch_quiesce(struct subchannel *sch);
Expand Down
19 changes: 6 additions & 13 deletions drivers/s390/crypto/vfio_ap_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,23 +816,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,

static MDEV_TYPE_ATTR_RO(device_api);

static struct attribute *vfio_ap_mdev_type_attrs[] = {
static const struct attribute *vfio_ap_mdev_type_attrs[] = {
&mdev_type_attr_name.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};

static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
.name = VFIO_AP_MDEV_TYPE_HWVIRT,
.attrs = vfio_ap_mdev_type_attrs,
};

static struct attribute_group *vfio_ap_mdev_type_groups[] = {
&vfio_ap_mdev_hwvirt_type_group,
NULL,
};

#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
"already assigned to %s"

Expand Down Expand Up @@ -1817,7 +1807,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
},
.probe = vfio_ap_mdev_probe,
.remove = vfio_ap_mdev_remove,
.supported_type_groups = vfio_ap_mdev_type_groups,
.types_attrs = vfio_ap_mdev_type_attrs,
};

int vfio_ap_mdev_register(void)
Expand All @@ -1830,8 +1820,11 @@ int vfio_ap_mdev_register(void)
if (ret)
return ret;

matrix_dev->mdev_type.sysfs_name = VFIO_AP_MDEV_TYPE_HWVIRT;
matrix_dev->mdev_types[0] = &matrix_dev->mdev_type;
ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
&vfio_ap_matrix_driver);
&vfio_ap_matrix_driver,
matrix_dev->mdev_types, 1);
if (ret)
goto err_driver;
return 0;
Expand Down
2 changes: 2 additions & 0 deletions drivers/s390/crypto/vfio_ap_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ struct ap_matrix_dev {
struct ap_driver *vfio_ap_drv;
struct mutex guests_lock; /* serializes access to each KVM guest */
struct mdev_parent parent;
struct mdev_type mdev_type;
struct mdev_type *mdev_types[];
};

extern struct ap_matrix_dev *matrix_dev;
Expand Down
Loading

0 comments on commit da44c34

Please sign in to comment.