Commit da44c340 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Alex Williamson
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarTony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarKirti Wankhede <kwankhede@nvidia.com>
Reviewed-by: default avatarEric Farman <farman@linux.ibm.com>
Link: https://lore.kernel.org/r/20220923092652.100656-6-hch@lst.de


Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 89345d51
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
     };

+2 −1
Original line number Diff line number Diff line
@@ -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;
+14 −88
Original line number Diff line number Diff line
@@ -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);
	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);
+12 −1
Original line number Diff line number Diff line
@@ -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);
}

+4 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;

Loading