* [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 14:08 ` Jason Gunthorpe
2022-07-04 12:51 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
` (12 subsequent siblings)
13 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
gvt->types needs to be freed on error.
Reported-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
---
drivers/gpu/drm/i915/gvt/vgpu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 46da19b3225d2..5c828556cefd7 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -142,7 +142,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
if (vgpu_types[i].weight < 1 ||
vgpu_types[i].weight > VGPU_MAX_WEIGHT)
- return -EINVAL;
+ goto out_free_types;
gvt->types[i].weight = vgpu_types[i].weight;
gvt->types[i].resolution = vgpu_types[i].edid;
@@ -167,6 +167,10 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
gvt->num_types = i;
return 0;
+
+out_free_types:
+ kfree(gvt->types);
+ return -EINVAL;
}
void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types
2022-07-04 12:51 ` [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types Christoph Hellwig
@ 2022-07-04 14:08 ` Jason Gunthorpe
0 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2022-07-04 14:08 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, Jul 04, 2022 at 02:51:31PM +0200, Christoph Hellwig wrote:
> gvt->types needs to be freed on error.
>
> Reported-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
> ---
> drivers/gpu/drm/i915/gvt/vgpu.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Fixes line?
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
2022-07-04 12:51 ` [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 14:15 ` Jason Gunthorpe
2022-07-05 7:59 ` Zhenyu Wang
2022-07-04 12:51 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
` (11 subsequent siblings)
13 siblings, 2 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev
Instead of copying the information from the vgpu_types arrays into each
intel_vgpu_type structure, just reference this constant information
with a pointer to the already existing data structure, and pass it into
the low-level VGPU creation helpers intead of copying the data into yet
anothe params data structure.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/gpu/drm/i915/gvt/aperture_gm.c | 20 +--
drivers/gpu/drm/i915/gvt/gvt.h | 36 +++---
drivers/gpu/drm/i915/gvt/kvmgt.c | 10 +-
drivers/gpu/drm/i915/gvt/vgpu.c | 172 +++++++++----------------
4 files changed, 91 insertions(+), 147 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 557f3314291a8..7dd8163f8a569 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -240,13 +240,13 @@ static void free_resource(struct intel_vgpu *vgpu)
}
static int alloc_resource(struct intel_vgpu *vgpu,
- struct intel_vgpu_creation_params *param)
+ const struct intel_vgpu_config *conf)
{
struct intel_gvt *gvt = vgpu->gvt;
unsigned long request, avail, max, taken;
const char *item;
- if (!param->low_gm_sz || !param->high_gm_sz || !param->fence_sz) {
+ if (!conf->low_mm || !conf->high_mm || !conf->fence) {
gvt_vgpu_err("Invalid vGPU creation params\n");
return -EINVAL;
}
@@ -255,7 +255,7 @@ static int alloc_resource(struct intel_vgpu *vgpu,
max = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
taken = gvt->gm.vgpu_allocated_low_gm_size;
avail = max - taken;
- request = MB_TO_BYTES(param->low_gm_sz);
+ request = conf->low_mm;
if (request > avail)
goto no_enough_resource;
@@ -266,7 +266,7 @@ static int alloc_resource(struct intel_vgpu *vgpu,
max = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
taken = gvt->gm.vgpu_allocated_high_gm_size;
avail = max - taken;
- request = MB_TO_BYTES(param->high_gm_sz);
+ request = conf->high_mm;
if (request > avail)
goto no_enough_resource;
@@ -277,16 +277,16 @@ static int alloc_resource(struct intel_vgpu *vgpu,
max = gvt_fence_sz(gvt) - HOST_FENCE;
taken = gvt->fence.vgpu_allocated_fence_num;
avail = max - taken;
- request = param->fence_sz;
+ request = conf->fence;
if (request > avail)
goto no_enough_resource;
vgpu_fence_sz(vgpu) = request;
- gvt->gm.vgpu_allocated_low_gm_size += MB_TO_BYTES(param->low_gm_sz);
- gvt->gm.vgpu_allocated_high_gm_size += MB_TO_BYTES(param->high_gm_sz);
- gvt->fence.vgpu_allocated_fence_num += param->fence_sz;
+ gvt->gm.vgpu_allocated_low_gm_size += conf->low_mm;
+ gvt->gm.vgpu_allocated_high_gm_size += conf->high_mm;
+ gvt->fence.vgpu_allocated_fence_num += conf->fence;
return 0;
no_enough_resource:
@@ -340,11 +340,11 @@ void intel_vgpu_reset_resource(struct intel_vgpu *vgpu)
*
*/
int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu,
- struct intel_vgpu_creation_params *param)
+ const struct intel_vgpu_config *conf)
{
int ret;
- ret = alloc_resource(vgpu, param);
+ ret = alloc_resource(vgpu, conf);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index aee1a45da74bc..392c2ad49d376 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -295,15 +295,26 @@ struct intel_gvt_firmware {
bool firmware_loaded;
};
+struct intel_vgpu_config {
+ unsigned int low_mm;
+ unsigned int high_mm;
+ unsigned int fence;
+
+ /*
+ * A vGPU with a weight of 8 will get twice as much GPU as a vGPU with
+ * a weight of 4 on a contended host, different vGPU type has different
+ * weight set. Legal weights range from 1 to 16.
+ */
+ unsigned int weight;
+ enum intel_vgpu_edid edid;
+ const char *name;
+};
+
#define NR_MAX_INTEL_VGPU_TYPES 20
struct intel_vgpu_type {
char name[16];
+ const struct intel_vgpu_config *conf;
unsigned int avail_instance;
- unsigned int low_gm_size;
- unsigned int high_gm_size;
- unsigned int fence;
- unsigned int weight;
- enum intel_vgpu_edid resolution;
};
struct intel_gvt {
@@ -437,19 +448,8 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt);
/* ring context size i.e. the first 0x50 dwords*/
#define RING_CTX_SIZE 320
-struct intel_vgpu_creation_params {
- __u64 low_gm_sz; /* in MB */
- __u64 high_gm_sz; /* in MB */
- __u64 fence_sz;
- __u64 resolution;
- __s32 primary;
- __u64 vgpu_id;
-
- __u32 weight;
-};
-
int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu,
- struct intel_vgpu_creation_params *param);
+ const struct intel_vgpu_config *conf);
void intel_vgpu_reset_resource(struct intel_vgpu *vgpu);
void intel_vgpu_free_resource(struct intel_vgpu *vgpu);
void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
@@ -496,7 +496,7 @@ void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt);
struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt);
void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu);
struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
- struct intel_vgpu_type *type);
+ const struct intel_vgpu_config *conf);
void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_release_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index e2f6c56ab3420..7b060c0e66ae7 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -151,10 +151,10 @@ static ssize_t description_show(struct mdev_type *mtype,
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
"fence: %d\nresolution: %s\n"
"weight: %d\n",
- BYTES_TO_MB(type->low_gm_size),
- BYTES_TO_MB(type->high_gm_size),
- type->fence, vgpu_edid_str(type->resolution),
- type->weight);
+ BYTES_TO_MB(type->conf->low_mm),
+ BYTES_TO_MB(type->conf->high_mm),
+ type->conf->fence, vgpu_edid_str(type->conf->edid),
+ type->conf->weight);
}
static ssize_t name_show(struct mdev_type *mtype,
@@ -1624,7 +1624,7 @@ static int intel_vgpu_probe(struct mdev_device *mdev)
if (!type)
return -EINVAL;
- vgpu = intel_gvt_create_vgpu(gvt, type);
+ vgpu = intel_gvt_create_vgpu(gvt, type->conf);
if (IS_ERR(vgpu)) {
gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
return PTR_ERR(vgpu);
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 5c828556cefd7..8e136dcc70112 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -73,24 +73,21 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
drm_WARN_ON(&i915->drm, sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
}
+/*
+ * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU
+ * generation type (e.g V4 as BDW server, V5 as SKL server).
+ *
+ * Depening on the physical SKU resource, we might see vGPU types like
+ * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of
+ * vGPU on same physical GPU depending on available resource. Each vGPU
+ * type will have a different number of avail_instance to indicate how
+ * many vGPU instance can be created for this type.
+ */
#define VGPU_MAX_WEIGHT 16
#define VGPU_WEIGHT(vgpu_num) \
(VGPU_MAX_WEIGHT / (vgpu_num))
-static const struct {
- unsigned int low_mm;
- unsigned int high_mm;
- unsigned int fence;
-
- /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU
- * with a weight of 4 on a contended host, different vGPU type has
- * different weight set. Legal weights range from 1 to 16.
- */
- unsigned int weight;
- enum intel_vgpu_edid edid;
- const char *name;
-} vgpu_types[] = {
-/* Fixed vGPU type table */
+static const struct intel_vgpu_config intel_vgpu_configs[] = {
{ MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" },
{ MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" },
{ MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" },
@@ -106,63 +103,34 @@ static const struct {
*/
int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
{
- unsigned int num_types;
- unsigned int i, low_avail, high_avail;
- unsigned int min_low;
-
- /* vGPU type name is defined as GVTg_Vx_y which contains
- * physical GPU generation type (e.g V4 as BDW server, V5 as
- * SKL server).
- *
- * Depend on physical SKU resource, might see vGPU types like
- * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create
- * different types of vGPU on same physical GPU depending on
- * available resource. Each vGPU type will have "avail_instance"
- * to indicate how many vGPU instance can be created for this
- * type.
- *
- */
- low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
- high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
- num_types = ARRAY_SIZE(vgpu_types);
+ unsigned int low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
+ unsigned int high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
+ unsigned int num_types = ARRAY_SIZE(intel_vgpu_configs);
+ unsigned int i;
gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type),
GFP_KERNEL);
if (!gvt->types)
return -ENOMEM;
- min_low = MB_TO_BYTES(32);
for (i = 0; i < num_types; ++i) {
- if (low_avail / vgpu_types[i].low_mm == 0)
- break;
-
- gvt->types[i].low_gm_size = vgpu_types[i].low_mm;
- gvt->types[i].high_gm_size = vgpu_types[i].high_mm;
- gvt->types[i].fence = vgpu_types[i].fence;
+ const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
- if (vgpu_types[i].weight < 1 ||
- vgpu_types[i].weight > VGPU_MAX_WEIGHT)
+ if (low_avail / conf->low_mm == 0)
+ break;
+ if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
goto out_free_types;
- gvt->types[i].weight = vgpu_types[i].weight;
- gvt->types[i].resolution = vgpu_types[i].edid;
- gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm,
- high_avail / vgpu_types[i].high_mm);
-
- if (GRAPHICS_VER(gvt->gt->i915) == 8)
- sprintf(gvt->types[i].name, "GVTg_V4_%s",
- vgpu_types[i].name);
- else if (GRAPHICS_VER(gvt->gt->i915) == 9)
- sprintf(gvt->types[i].name, "GVTg_V5_%s",
- vgpu_types[i].name);
+ sprintf(gvt->types[i].name, "GVTg_V%u_%s",
+ GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
+ gvt->types->conf = conf;
+ gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
+ high_avail / conf->high_mm);
gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
- i, gvt->types[i].name,
- gvt->types[i].avail_instance,
- gvt->types[i].low_gm_size,
- gvt->types[i].high_gm_size, gvt->types[i].fence,
- gvt->types[i].weight,
- vgpu_edid_str(gvt->types[i].resolution));
+ 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->num_types = i;
@@ -195,16 +163,16 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
gvt->fence.vgpu_allocated_fence_num;
for (i = 0; i < gvt->num_types; i++) {
- low_gm_min = low_gm_avail / gvt->types[i].low_gm_size;
- high_gm_min = high_gm_avail / gvt->types[i].high_gm_size;
- fence_min = fence_avail / gvt->types[i].fence;
+ low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm;
+ high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm;
+ fence_min = fence_avail / gvt->types[i].conf->fence;
gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min),
fence_min);
gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
i, gvt->types[i].name,
- gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
- gvt->types[i].high_gm_size, gvt->types[i].fence);
+ gvt->types[i].avail_instance, gvt->types[i].conf->low_mm,
+ gvt->types[i].conf->high_mm, gvt->types[i].conf->fence);
}
}
@@ -367,42 +335,53 @@ void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu)
vfree(vgpu);
}
-static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
- struct intel_vgpu_creation_params *param)
+/**
+ * intel_gvt_create_vgpu - create a virtual GPU
+ * @gvt: GVT device
+ * @conf: type of the vGPU to create
+ *
+ * This function is called when user wants to create a virtual GPU.
+ *
+ * Returns:
+ * pointer to intel_vgpu, error pointer if failed.
+ */
+struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
+ const struct intel_vgpu_config *conf)
{
struct drm_i915_private *dev_priv = gvt->gt->i915;
struct intel_vgpu *vgpu;
int ret;
- gvt_dbg_core("low %llu MB high %llu MB fence %llu\n",
- param->low_gm_sz, param->high_gm_sz,
- param->fence_sz);
+ gvt_dbg_core("low %u MB high %u MB fence %u\n",
+ BYTES_TO_MB(conf->low_mm), BYTES_TO_MB(conf->high_mm),
+ conf->fence);
vgpu = vzalloc(sizeof(*vgpu));
if (!vgpu)
return ERR_PTR(-ENOMEM);
+ mutex_lock(&gvt->lock);
ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
GFP_KERNEL);
if (ret < 0)
- goto out_free_vgpu;
+ goto out_unlock;;
vgpu->id = ret;
vgpu->gvt = gvt;
- vgpu->sched_ctl.weight = param->weight;
+ vgpu->sched_ctl.weight = conf->weight;
mutex_init(&vgpu->vgpu_lock);
mutex_init(&vgpu->dmabuf_lock);
INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
idr_init_base(&vgpu->object_idr, 1);
- intel_vgpu_init_cfg_space(vgpu, param->primary);
+ intel_vgpu_init_cfg_space(vgpu, 1);
vgpu->d3_entered = false;
ret = intel_vgpu_init_mmio(vgpu);
if (ret)
goto out_clean_idr;
- ret = intel_vgpu_alloc_resource(vgpu, param);
+ ret = intel_vgpu_alloc_resource(vgpu, conf);
if (ret)
goto out_clean_vgpu_mmio;
@@ -416,7 +395,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret)
goto out_clean_gtt;
- ret = intel_vgpu_init_display(vgpu, param->resolution);
+ ret = intel_vgpu_init_display(vgpu, conf->edid);
if (ret)
goto out_clean_opregion;
@@ -441,6 +420,9 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret)
goto out_clean_sched_policy;
+ intel_gvt_update_vgpu_types(gvt);
+ intel_gvt_update_reg_whitelist(vgpu);
+ mutex_unlock(&gvt->lock);
return vgpu;
out_clean_sched_policy:
@@ -459,50 +441,12 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
intel_vgpu_clean_mmio(vgpu);
out_clean_idr:
idr_remove(&gvt->vgpu_idr, vgpu->id);
-out_free_vgpu:
+out_unlock:
+ mutex_unlock(&gvt->lock);
vfree(vgpu);
return ERR_PTR(ret);
}
-/**
- * intel_gvt_create_vgpu - create a virtual GPU
- * @gvt: GVT device
- * @type: type of the vGPU to create
- *
- * This function is called when user wants to create a virtual GPU.
- *
- * Returns:
- * pointer to intel_vgpu, error pointer if failed.
- */
-struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
- struct intel_vgpu_type *type)
-{
- struct intel_vgpu_creation_params param;
- struct intel_vgpu *vgpu;
-
- param.primary = 1;
- param.low_gm_sz = type->low_gm_size;
- param.high_gm_sz = type->high_gm_size;
- param.fence_sz = type->fence;
- param.weight = type->weight;
- param.resolution = type->resolution;
-
- /* XXX current param based on MB */
- param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz);
- param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz);
-
- mutex_lock(&gvt->lock);
- vgpu = __intel_gvt_create_vgpu(gvt, ¶m);
- if (!IS_ERR(vgpu)) {
- /* calculate left instance change for types */
- intel_gvt_update_vgpu_types(gvt);
- intel_gvt_update_reg_whitelist(vgpu);
- }
- mutex_unlock(&gvt->lock);
-
- return vgpu;
-}
-
/**
* intel_gvt_reset_vgpu_locked - reset a virtual GPU by DMLR or GT reset
* @vgpu: virtual GPU
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-04 12:51 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
@ 2022-07-04 14:15 ` Jason Gunthorpe
2022-07-05 8:02 ` Christoph Hellwig
2022-07-05 7:59 ` Zhenyu Wang
1 sibling, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2022-07-04 14:15 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev
On Mon, Jul 04, 2022 at 02:51:32PM +0200, Christoph Hellwig wrote:
> +/*
> + * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU
> + * generation type (e.g V4 as BDW server, V5 as SKL server).
> + *
> + * Depening on the physical SKU resource, we might see vGPU types like
> + * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of
> + * vGPU on same physical GPU depending on available resource. Each vGPU
> + * type will have a different number of avail_instance to indicate how
> + * many vGPU instance can be created for this type.
> + */
> #define VGPU_MAX_WEIGHT 16
> #define VGPU_WEIGHT(vgpu_num) \
> (VGPU_MAX_WEIGHT / (vgpu_num))
>
> -static const struct {
> - unsigned int low_mm;
> - unsigned int high_mm;
> - unsigned int fence;
> -
> - /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU
> - * with a weight of 4 on a contended host, different vGPU type has
> - * different weight set. Legal weights range from 1 to 16.
> - */
> - unsigned int weight;
> - enum intel_vgpu_edid edid;
> - const char *name;
> -} vgpu_types[] = {
> -/* Fixed vGPU type table */
> +static const struct intel_vgpu_config intel_vgpu_configs[] = {
> { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" },
> { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" },
> { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" },
> @@ -106,63 +103,34 @@ static const struct {
> */
[..]
> for (i = 0; i < num_types; ++i) {
> - if (low_avail / vgpu_types[i].low_mm == 0)
> - break;
> -
> - gvt->types[i].low_gm_size = vgpu_types[i].low_mm;
> - gvt->types[i].high_gm_size = vgpu_types[i].high_mm;
> - gvt->types[i].fence = vgpu_types[i].fence;
> + const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
>
> - if (vgpu_types[i].weight < 1 ||
> - vgpu_types[i].weight > VGPU_MAX_WEIGHT)
> + if (low_avail / conf->low_mm == 0)
> + break;
> + if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
> goto out_free_types;
This is now clearly impossible right? Maybe a BUILD_BUG_ON is all that
is needed:
#define VGPU_WEIGHT(vgpu_num) \
(VGPU_MAX_WEIGHT + BUILD_BUG_ON_ZERO((vgpu_num) > VGPU_MAX_WEIGHT) / (vgpu_num))
> + sprintf(gvt->types[i].name, "GVTg_V%u_%s",
> + GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
> + gvt->types->conf = conf;
> + gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
> + high_avail / conf->high_mm);
snprintf and check for failure?
Regardless, makes sense to me:
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-04 14:15 ` Jason Gunthorpe
@ 2022-07-05 8:02 ` Christoph Hellwig
0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-05 8:02 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev
On Mon, Jul 04, 2022 at 11:15:36AM -0300, Jason Gunthorpe wrote:
> > + if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
> > goto out_free_types;
>
> This is now clearly impossible right? Maybe a BUILD_BUG_ON is all that
> is needed:
It is not possible right now, but an incorrect addition to the array
can easily add the condition. A BUILD_BUG_ON would be nice, but my
gcc doesn't see the expressons as const enough for that to actually work.
>
> #define VGPU_WEIGHT(vgpu_num) \
> (VGPU_MAX_WEIGHT + BUILD_BUG_ON_ZERO((vgpu_num) > VGPU_MAX_WEIGHT) / (vgpu_num))
>
> > + sprintf(gvt->types[i].name, "GVTg_V%u_%s",
> > + GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
> > + gvt->types->conf = conf;
> > + gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
> > + high_avail / conf->high_mm);
>
> snprintf and check for failure?
I'd rather just leave it as-is. intead of messing with these unrelated
bit.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-04 12:51 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
2022-07-04 14:15 ` Jason Gunthorpe
@ 2022-07-05 7:59 ` Zhenyu Wang
2022-07-05 8:25 ` Christoph Hellwig
1 sibling, 1 reply; 27+ messages in thread
From: Zhenyu Wang @ 2022-07-05 7:59 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev
[-- Attachment #1: Type: text/plain, Size: 17492 bytes --]
On 2022.07.04 14:51:32 +0200, Christoph Hellwig wrote:
> Instead of copying the information from the vgpu_types arrays into each
> intel_vgpu_type structure, just reference this constant information
> with a pointer to the already existing data structure, and pass it into
> the low-level VGPU creation helpers intead of copying the data into yet
> anothe params data structure.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
Looks fine to me. We still carry some legacy codes like vgpu create param
originally used for other hypervisor. Thanks for cleaning this up!
Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
> drivers/gpu/drm/i915/gvt/aperture_gm.c | 20 +--
> drivers/gpu/drm/i915/gvt/gvt.h | 36 +++---
> drivers/gpu/drm/i915/gvt/kvmgt.c | 10 +-
> drivers/gpu/drm/i915/gvt/vgpu.c | 172 +++++++++----------------
> 4 files changed, 91 insertions(+), 147 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
> index 557f3314291a8..7dd8163f8a569 100644
> --- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
> +++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
> @@ -240,13 +240,13 @@ static void free_resource(struct intel_vgpu *vgpu)
> }
>
> static int alloc_resource(struct intel_vgpu *vgpu,
> - struct intel_vgpu_creation_params *param)
> + const struct intel_vgpu_config *conf)
> {
> struct intel_gvt *gvt = vgpu->gvt;
> unsigned long request, avail, max, taken;
> const char *item;
>
> - if (!param->low_gm_sz || !param->high_gm_sz || !param->fence_sz) {
> + if (!conf->low_mm || !conf->high_mm || !conf->fence) {
> gvt_vgpu_err("Invalid vGPU creation params\n");
> return -EINVAL;
> }
> @@ -255,7 +255,7 @@ static int alloc_resource(struct intel_vgpu *vgpu,
> max = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
> taken = gvt->gm.vgpu_allocated_low_gm_size;
> avail = max - taken;
> - request = MB_TO_BYTES(param->low_gm_sz);
> + request = conf->low_mm;
>
> if (request > avail)
> goto no_enough_resource;
> @@ -266,7 +266,7 @@ static int alloc_resource(struct intel_vgpu *vgpu,
> max = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
> taken = gvt->gm.vgpu_allocated_high_gm_size;
> avail = max - taken;
> - request = MB_TO_BYTES(param->high_gm_sz);
> + request = conf->high_mm;
>
> if (request > avail)
> goto no_enough_resource;
> @@ -277,16 +277,16 @@ static int alloc_resource(struct intel_vgpu *vgpu,
> max = gvt_fence_sz(gvt) - HOST_FENCE;
> taken = gvt->fence.vgpu_allocated_fence_num;
> avail = max - taken;
> - request = param->fence_sz;
> + request = conf->fence;
>
> if (request > avail)
> goto no_enough_resource;
>
> vgpu_fence_sz(vgpu) = request;
>
> - gvt->gm.vgpu_allocated_low_gm_size += MB_TO_BYTES(param->low_gm_sz);
> - gvt->gm.vgpu_allocated_high_gm_size += MB_TO_BYTES(param->high_gm_sz);
> - gvt->fence.vgpu_allocated_fence_num += param->fence_sz;
> + gvt->gm.vgpu_allocated_low_gm_size += conf->low_mm;
> + gvt->gm.vgpu_allocated_high_gm_size += conf->high_mm;
> + gvt->fence.vgpu_allocated_fence_num += conf->fence;
> return 0;
>
> no_enough_resource:
> @@ -340,11 +340,11 @@ void intel_vgpu_reset_resource(struct intel_vgpu *vgpu)
> *
> */
> int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu,
> - struct intel_vgpu_creation_params *param)
> + const struct intel_vgpu_config *conf)
> {
> int ret;
>
> - ret = alloc_resource(vgpu, param);
> + ret = alloc_resource(vgpu, conf);
> if (ret)
> return ret;
>
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> index aee1a45da74bc..392c2ad49d376 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.h
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -295,15 +295,26 @@ struct intel_gvt_firmware {
> bool firmware_loaded;
> };
>
> +struct intel_vgpu_config {
> + unsigned int low_mm;
> + unsigned int high_mm;
> + unsigned int fence;
> +
> + /*
> + * A vGPU with a weight of 8 will get twice as much GPU as a vGPU with
> + * a weight of 4 on a contended host, different vGPU type has different
> + * weight set. Legal weights range from 1 to 16.
> + */
> + unsigned int weight;
> + enum intel_vgpu_edid edid;
> + const char *name;
> +};
> +
> #define NR_MAX_INTEL_VGPU_TYPES 20
> struct intel_vgpu_type {
> char name[16];
> + const struct intel_vgpu_config *conf;
> unsigned int avail_instance;
> - unsigned int low_gm_size;
> - unsigned int high_gm_size;
> - unsigned int fence;
> - unsigned int weight;
> - enum intel_vgpu_edid resolution;
> };
>
> struct intel_gvt {
> @@ -437,19 +448,8 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt);
> /* ring context size i.e. the first 0x50 dwords*/
> #define RING_CTX_SIZE 320
>
> -struct intel_vgpu_creation_params {
> - __u64 low_gm_sz; /* in MB */
> - __u64 high_gm_sz; /* in MB */
> - __u64 fence_sz;
> - __u64 resolution;
> - __s32 primary;
> - __u64 vgpu_id;
> -
> - __u32 weight;
> -};
> -
> int intel_vgpu_alloc_resource(struct intel_vgpu *vgpu,
> - struct intel_vgpu_creation_params *param);
> + const struct intel_vgpu_config *conf);
> void intel_vgpu_reset_resource(struct intel_vgpu *vgpu);
> void intel_vgpu_free_resource(struct intel_vgpu *vgpu);
> void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
> @@ -496,7 +496,7 @@ void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt);
> struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt);
> void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu);
> struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
> - struct intel_vgpu_type *type);
> + const struct intel_vgpu_config *conf);
> void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
> void intel_gvt_release_vgpu(struct intel_vgpu *vgpu);
> void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index e2f6c56ab3420..7b060c0e66ae7 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -151,10 +151,10 @@ static ssize_t description_show(struct mdev_type *mtype,
> return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
> "fence: %d\nresolution: %s\n"
> "weight: %d\n",
> - BYTES_TO_MB(type->low_gm_size),
> - BYTES_TO_MB(type->high_gm_size),
> - type->fence, vgpu_edid_str(type->resolution),
> - type->weight);
> + BYTES_TO_MB(type->conf->low_mm),
> + BYTES_TO_MB(type->conf->high_mm),
> + type->conf->fence, vgpu_edid_str(type->conf->edid),
> + type->conf->weight);
> }
>
> static ssize_t name_show(struct mdev_type *mtype,
> @@ -1624,7 +1624,7 @@ static int intel_vgpu_probe(struct mdev_device *mdev)
> if (!type)
> return -EINVAL;
>
> - vgpu = intel_gvt_create_vgpu(gvt, type);
> + vgpu = intel_gvt_create_vgpu(gvt, type->conf);
> if (IS_ERR(vgpu)) {
> gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
> return PTR_ERR(vgpu);
> diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
> index 5c828556cefd7..8e136dcc70112 100644
> --- a/drivers/gpu/drm/i915/gvt/vgpu.c
> +++ b/drivers/gpu/drm/i915/gvt/vgpu.c
> @@ -73,24 +73,21 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
> drm_WARN_ON(&i915->drm, sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
> }
>
> +/*
> + * vGPU type name is defined as GVTg_Vx_y which contains the physical GPU
> + * generation type (e.g V4 as BDW server, V5 as SKL server).
> + *
> + * Depening on the physical SKU resource, we might see vGPU types like
> + * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create different types of
> + * vGPU on same physical GPU depending on available resource. Each vGPU
> + * type will have a different number of avail_instance to indicate how
> + * many vGPU instance can be created for this type.
> + */
> #define VGPU_MAX_WEIGHT 16
> #define VGPU_WEIGHT(vgpu_num) \
> (VGPU_MAX_WEIGHT / (vgpu_num))
>
> -static const struct {
> - unsigned int low_mm;
> - unsigned int high_mm;
> - unsigned int fence;
> -
> - /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU
> - * with a weight of 4 on a contended host, different vGPU type has
> - * different weight set. Legal weights range from 1 to 16.
> - */
> - unsigned int weight;
> - enum intel_vgpu_edid edid;
> - const char *name;
> -} vgpu_types[] = {
> -/* Fixed vGPU type table */
> +static const struct intel_vgpu_config intel_vgpu_configs[] = {
> { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" },
> { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" },
> { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" },
> @@ -106,63 +103,34 @@ static const struct {
> */
> int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
> {
> - unsigned int num_types;
> - unsigned int i, low_avail, high_avail;
> - unsigned int min_low;
> -
> - /* vGPU type name is defined as GVTg_Vx_y which contains
> - * physical GPU generation type (e.g V4 as BDW server, V5 as
> - * SKL server).
> - *
> - * Depend on physical SKU resource, might see vGPU types like
> - * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create
> - * different types of vGPU on same physical GPU depending on
> - * available resource. Each vGPU type will have "avail_instance"
> - * to indicate how many vGPU instance can be created for this
> - * type.
> - *
> - */
> - low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
> - high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
> - num_types = ARRAY_SIZE(vgpu_types);
> + unsigned int low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
> + unsigned int high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
> + unsigned int num_types = ARRAY_SIZE(intel_vgpu_configs);
> + unsigned int i;
>
> gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type),
> GFP_KERNEL);
> if (!gvt->types)
> return -ENOMEM;
>
> - min_low = MB_TO_BYTES(32);
> for (i = 0; i < num_types; ++i) {
> - if (low_avail / vgpu_types[i].low_mm == 0)
> - break;
> -
> - gvt->types[i].low_gm_size = vgpu_types[i].low_mm;
> - gvt->types[i].high_gm_size = vgpu_types[i].high_mm;
> - gvt->types[i].fence = vgpu_types[i].fence;
> + const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
>
> - if (vgpu_types[i].weight < 1 ||
> - vgpu_types[i].weight > VGPU_MAX_WEIGHT)
> + if (low_avail / conf->low_mm == 0)
> + break;
> + if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
> goto out_free_types;
>
> - gvt->types[i].weight = vgpu_types[i].weight;
> - gvt->types[i].resolution = vgpu_types[i].edid;
> - gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm,
> - high_avail / vgpu_types[i].high_mm);
> -
> - if (GRAPHICS_VER(gvt->gt->i915) == 8)
> - sprintf(gvt->types[i].name, "GVTg_V4_%s",
> - vgpu_types[i].name);
> - else if (GRAPHICS_VER(gvt->gt->i915) == 9)
> - sprintf(gvt->types[i].name, "GVTg_V5_%s",
> - vgpu_types[i].name);
> + sprintf(gvt->types[i].name, "GVTg_V%u_%s",
> + GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
> + gvt->types->conf = conf;
> + gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
> + high_avail / conf->high_mm);
>
> gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
> - i, gvt->types[i].name,
> - gvt->types[i].avail_instance,
> - gvt->types[i].low_gm_size,
> - gvt->types[i].high_gm_size, gvt->types[i].fence,
> - gvt->types[i].weight,
> - vgpu_edid_str(gvt->types[i].resolution));
> + 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->num_types = i;
> @@ -195,16 +163,16 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
> gvt->fence.vgpu_allocated_fence_num;
>
> for (i = 0; i < gvt->num_types; i++) {
> - low_gm_min = low_gm_avail / gvt->types[i].low_gm_size;
> - high_gm_min = high_gm_avail / gvt->types[i].high_gm_size;
> - fence_min = fence_avail / gvt->types[i].fence;
> + low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm;
> + high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm;
> + fence_min = fence_avail / gvt->types[i].conf->fence;
> gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min),
> fence_min);
>
> gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
> i, gvt->types[i].name,
> - gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
> - gvt->types[i].high_gm_size, gvt->types[i].fence);
> + gvt->types[i].avail_instance, gvt->types[i].conf->low_mm,
> + gvt->types[i].conf->high_mm, gvt->types[i].conf->fence);
> }
> }
>
> @@ -367,42 +335,53 @@ void intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu)
> vfree(vgpu);
> }
>
> -static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
> - struct intel_vgpu_creation_params *param)
> +/**
> + * intel_gvt_create_vgpu - create a virtual GPU
> + * @gvt: GVT device
> + * @conf: type of the vGPU to create
> + *
> + * This function is called when user wants to create a virtual GPU.
> + *
> + * Returns:
> + * pointer to intel_vgpu, error pointer if failed.
> + */
> +struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
> + const struct intel_vgpu_config *conf)
> {
> struct drm_i915_private *dev_priv = gvt->gt->i915;
> struct intel_vgpu *vgpu;
> int ret;
>
> - gvt_dbg_core("low %llu MB high %llu MB fence %llu\n",
> - param->low_gm_sz, param->high_gm_sz,
> - param->fence_sz);
> + gvt_dbg_core("low %u MB high %u MB fence %u\n",
> + BYTES_TO_MB(conf->low_mm), BYTES_TO_MB(conf->high_mm),
> + conf->fence);
>
> vgpu = vzalloc(sizeof(*vgpu));
> if (!vgpu)
> return ERR_PTR(-ENOMEM);
>
> + mutex_lock(&gvt->lock);
> ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
> GFP_KERNEL);
> if (ret < 0)
> - goto out_free_vgpu;
> + goto out_unlock;;
>
> vgpu->id = ret;
> vgpu->gvt = gvt;
> - vgpu->sched_ctl.weight = param->weight;
> + vgpu->sched_ctl.weight = conf->weight;
> mutex_init(&vgpu->vgpu_lock);
> mutex_init(&vgpu->dmabuf_lock);
> INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
> INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
> idr_init_base(&vgpu->object_idr, 1);
> - intel_vgpu_init_cfg_space(vgpu, param->primary);
> + intel_vgpu_init_cfg_space(vgpu, 1);
> vgpu->d3_entered = false;
>
> ret = intel_vgpu_init_mmio(vgpu);
> if (ret)
> goto out_clean_idr;
>
> - ret = intel_vgpu_alloc_resource(vgpu, param);
> + ret = intel_vgpu_alloc_resource(vgpu, conf);
> if (ret)
> goto out_clean_vgpu_mmio;
>
> @@ -416,7 +395,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
> if (ret)
> goto out_clean_gtt;
>
> - ret = intel_vgpu_init_display(vgpu, param->resolution);
> + ret = intel_vgpu_init_display(vgpu, conf->edid);
> if (ret)
> goto out_clean_opregion;
>
> @@ -441,6 +420,9 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
> if (ret)
> goto out_clean_sched_policy;
>
> + intel_gvt_update_vgpu_types(gvt);
> + intel_gvt_update_reg_whitelist(vgpu);
> + mutex_unlock(&gvt->lock);
> return vgpu;
>
> out_clean_sched_policy:
> @@ -459,50 +441,12 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
> intel_vgpu_clean_mmio(vgpu);
> out_clean_idr:
> idr_remove(&gvt->vgpu_idr, vgpu->id);
> -out_free_vgpu:
> +out_unlock:
> + mutex_unlock(&gvt->lock);
> vfree(vgpu);
> return ERR_PTR(ret);
> }
>
> -/**
> - * intel_gvt_create_vgpu - create a virtual GPU
> - * @gvt: GVT device
> - * @type: type of the vGPU to create
> - *
> - * This function is called when user wants to create a virtual GPU.
> - *
> - * Returns:
> - * pointer to intel_vgpu, error pointer if failed.
> - */
> -struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
> - struct intel_vgpu_type *type)
> -{
> - struct intel_vgpu_creation_params param;
> - struct intel_vgpu *vgpu;
> -
> - param.primary = 1;
> - param.low_gm_sz = type->low_gm_size;
> - param.high_gm_sz = type->high_gm_size;
> - param.fence_sz = type->fence;
> - param.weight = type->weight;
> - param.resolution = type->resolution;
> -
> - /* XXX current param based on MB */
> - param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz);
> - param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz);
> -
> - mutex_lock(&gvt->lock);
> - vgpu = __intel_gvt_create_vgpu(gvt, ¶m);
> - if (!IS_ERR(vgpu)) {
> - /* calculate left instance change for types */
> - intel_gvt_update_vgpu_types(gvt);
> - intel_gvt_update_reg_whitelist(vgpu);
> - }
> - mutex_unlock(&gvt->lock);
> -
> - return vgpu;
> -}
> -
> /**
> * intel_gvt_reset_vgpu_locked - reset a virtual GPU by DMLR or GT reset
> * @vgpu: virtual GPU
> --
> 2.30.2
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-05 7:59 ` Zhenyu Wang
@ 2022-07-05 8:25 ` Christoph Hellwig
2022-07-05 8:18 ` Zhenyu Wang
0 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-05 8:25 UTC (permalink / raw)
To: Zhenyu Wang
Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Eric Farman, Matthew Rosato, Zhi Wang,
Alex Williamson, Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev
On Tue, Jul 05, 2022 at 03:59:38PM +0800, Zhenyu Wang wrote:
> On 2022.07.04 14:51:32 +0200, Christoph Hellwig wrote:
> > Instead of copying the information from the vgpu_types arrays into each
> > intel_vgpu_type structure, just reference this constant information
> > with a pointer to the already existing data structure, and pass it into
> > the low-level VGPU creation helpers intead of copying the data into yet
> > anothe params data structure.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > ---
>
> Looks fine to me. We still carry some legacy codes like vgpu create param
> originally used for other hypervisor. Thanks for cleaning this up!
Note that even there I think this structure makes more sense:
The generic config structure that has not vfio-related bits as the
lowest layer. vfio/kvm specific structures then carry a pointer to
it can can pass it to lower layers.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-07-05 8:25 ` Christoph Hellwig
@ 2022-07-05 8:18 ` Zhenyu Wang
0 siblings, 0 replies; 27+ messages in thread
From: Zhenyu Wang @ 2022-07-05 8:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhi Wang, Alex Williamson,
Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev
[-- Attachment #1: Type: text/plain, Size: 1144 bytes --]
On 2022.07.05 10:25:59 +0200, Christoph Hellwig wrote:
> On Tue, Jul 05, 2022 at 03:59:38PM +0800, Zhenyu Wang wrote:
> > On 2022.07.04 14:51:32 +0200, Christoph Hellwig wrote:
> > > Instead of copying the information from the vgpu_types arrays into each
> > > intel_vgpu_type structure, just reference this constant information
> > > with a pointer to the already existing data structure, and pass it into
> > > the low-level VGPU creation helpers intead of copying the data into yet
> > > anothe params data structure.
> > >
> > > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > > ---
> >
> > Looks fine to me. We still carry some legacy codes like vgpu create param
> > originally used for other hypervisor. Thanks for cleaning this up!
>
> Note that even there I think this structure makes more sense:
>
> The generic config structure that has not vfio-related bits as the
> lowest layer. vfio/kvm specific structures then carry a pointer to
> it can can pass it to lower layers.
yes, I'm also fine with that part which makes it more straight forward
to link between mdev type and lower level info.
Thanks
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 03/14] vfio/mdev: make mdev.h standalone includable
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
2022-07-04 12:51 ` [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types Christoph Hellwig
2022-07-04 12:51 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
` (10 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Include <linux/device.h> and <linux/uuid.h> so that users of this headers
don't need to do that and remove those includes that aren't needed
any more.
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>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 2 --
drivers/s390/cio/vfio_ccw_drv.c | 2 --
drivers/s390/crypto/vfio_ap_private.h | 1 -
drivers/vfio/mdev/mdev_core.c | 2 --
drivers/vfio/mdev/mdev_driver.c | 1 -
drivers/vfio/mdev/mdev_sysfs.c | 2 --
include/linux/mdev.h | 3 +++
samples/vfio-mdev/mbochs.c | 1 -
samples/vfio-mdev/mdpy.c | 1 -
samples/vfio-mdev/mtty.c | 2 --
10 files changed, 3 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 7b060c0e66ae7..85e1393d8e55c 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -34,7 +34,6 @@
*/
#include <linux/init.h>
-#include <linux/device.h>
#include <linux/mm.h>
#include <linux/kthread.h>
#include <linux/sched/mm.h>
@@ -43,7 +42,6 @@
#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/eventfd.h>
-#include <linux/uuid.h>
#include <linux/mdev.h>
#include <linux/debugfs.h>
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index ee182cfb467d1..750d0315f1f5b 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -12,9 +12,7 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/uuid.h>
#include <linux/mdev.h>
#include <asm/isc.h>
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index a26efd804d0df..6616aa83347ad 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -13,7 +13,6 @@
#define _VFIO_AP_PRIVATE_H_
#include <linux/types.h>
-#include <linux/device.h>
#include <linux/mdev.h>
#include <linux/delay.h>
#include <linux/mutex.h>
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index b8b9e7911e559..2c32923fbad27 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -8,9 +8,7 @@
*/
#include <linux/module.h>
-#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/uuid.h>
#include <linux/sysfs.h>
#include <linux/mdev.h>
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 9c2af59809e2e..7bd4bb9850e81 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -7,7 +7,6 @@
* Kirti Wankhede <kwankhede@nvidia.com>
*/
-#include <linux/device.h>
#include <linux/iommu.h>
#include <linux/mdev.h>
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 0ccfeb3dda245..4bfbf49aaa66a 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -9,9 +9,7 @@
#include <linux/sysfs.h>
#include <linux/ctype.h>
-#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/uuid.h>
#include <linux/mdev.h>
#include "mdev_private.h"
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index bb539794f54a8..555c1d015b5f0 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -10,6 +10,9 @@
#ifndef MDEV_H
#define MDEV_H
+#include <linux/device.h>
+#include <linux/uuid.h>
+
struct mdev_type;
struct mdev_device {
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 344c2901a82bf..d0d1bb7747240 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -21,7 +21,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index e8c46eb2e2468..0c4ca1f4be7ed 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -17,7 +17,6 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index f42a59ed2e3fe..4f5a6f2d3629d 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/poll.h>
@@ -20,7 +19,6 @@
#include <linux/cdev.h>
#include <linux/sched.h>
#include <linux/wait.h>
-#include <linux/uuid.h>
#include <linux/vfio.h>
#include <linux/iommu.h>
#include <linux/sysfs.h>
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (2 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 15:56 ` Jason Gunthorpe
2022-07-04 12:51 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
` (9 subsequent siblings)
13 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Simplify mdev_{un}register_device by requiring the caller to pass in
a structure allocate as part of the parent device structure. This
removes the need for a list of parents and the separate mdev_parent
refcount as we can simplify rely on the reference to the parent device.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
.../driver-api/vfio-mediated-device.rst | 12 +-
Documentation/s390/vfio-ap.rst | 2 +-
Documentation/s390/vfio-ccw.rst | 2 +-
drivers/gpu/drm/i915/gvt/gvt.h | 2 +
drivers/gpu/drm/i915/gvt/kvmgt.c | 5 +-
drivers/s390/cio/cio.h | 2 +
drivers/s390/cio/vfio_ccw_ops.c | 6 +-
drivers/s390/crypto/vfio_ap_ops.c | 5 +-
drivers/s390/crypto/vfio_ap_private.h | 1 +
drivers/vfio/mdev/mdev_core.c | 120 ++++--------------
drivers/vfio/mdev/mdev_private.h | 23 ----
drivers/vfio/mdev/mdev_sysfs.c | 4 +-
include/linux/mdev.h | 15 ++-
samples/vfio-mdev/mbochs.c | 5 +-
samples/vfio-mdev/mdpy.c | 5 +-
samples/vfio-mdev/mtty.c | 6 +-
16 files changed, 69 insertions(+), 146 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 1c57815619fdf..62a82afce161b 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -60,19 +60,19 @@ devices as examples, as these devices are the first devices to use this module::
| MDEV CORE |
| MODULE |
| mdev.ko |
- | +-----------+ | mdev_register_device() +--------------+
+ | +-----------+ | mdev_register_parent() +--------------+
| | | +<------------------------+ |
| | | | | nvidia.ko |<-> physical
| | | +------------------------>+ | device
| | | | callbacks +--------------+
| | Physical | |
- | | device | | mdev_register_device() +--------------+
+ | | device | | mdev_register_parent() +--------------+
| | interface | |<------------------------+ |
| | | | | i915.ko |<-> physical
| | | +------------------------>+ | device
| | | | callbacks +--------------+
| | | |
- | | | | mdev_register_device() +--------------+
+ | | | | mdev_register_parent() +--------------+
| | | +<------------------------+ |
| | | | | ccw_device.ko|<-> physical
| | | +------------------------>+ | device
@@ -127,8 +127,8 @@ vfio_device_ops.
When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::
- int mdev_register_device(struct device *dev,
- struct mdev_driver *mdev_driver);
+ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+ struct mdev_driver *mdev_driver);
This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
@@ -136,7 +136,7 @@ attached to the specified driver.
When the driver needs to remove itself it calls::
- void mdev_unregister_device(struct device *dev);
+ void mdev_unregister_parent(struct mdev_parent *parent);
Which will unbind and destroy all the created mdevs and remove the sysfs files.
diff --git a/Documentation/s390/vfio-ap.rst b/Documentation/s390/vfio-ap.rst
index f57ae621f33e8..37e16158c7fbf 100644
--- a/Documentation/s390/vfio-ap.rst
+++ b/Documentation/s390/vfio-ap.rst
@@ -299,7 +299,7 @@ of the VFIO AP mediated matrix device driver::
| MDEV CORE |
| MODULE |
| mdev.ko |
- | +---------+ | mdev_register_device() +--------------+
+ | +---------+ | mdev_register_parent() +--------------+
| |Physical | +<-----------------------+ |
| | device | | | vfio_ap.ko |<-> matrix
| |interface| +----------------------->+ | device
diff --git a/Documentation/s390/vfio-ccw.rst b/Documentation/s390/vfio-ccw.rst
index 8aad08a8b8a50..ea928a3806f43 100644
--- a/Documentation/s390/vfio-ccw.rst
+++ b/Documentation/s390/vfio-ccw.rst
@@ -156,7 +156,7 @@ Below is a high Level block diagram::
| MDEV CORE |
| MODULE |
| mdev.ko |
- | +---------+ | mdev_register_device() +--------------+
+ | +---------+ | mdev_register_parent() +--------------+
| |Physical | +<-----------------------+ |
| | device | | | vfio_ccw.ko |<-> subchannel
| |interface| +----------------------->+ | device
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 392c2ad49d376..bbf0116671ecb 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -36,6 +36,7 @@
#include <uapi/linux/pci_regs.h>
#include <linux/kvm_host.h>
#include <linux/vfio.h>
+#include <linux/mdev.h>
#include "i915_drv.h"
#include "intel_gvt.h"
@@ -338,6 +339,7 @@ struct intel_gvt {
struct intel_gvt_workload_scheduler scheduler;
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
+ struct mdev_parent parent;
struct intel_vgpu_type *types;
unsigned int num_types;
struct intel_vgpu *idle_vgpu;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 85e1393d8e55c..e9dba4c0fe6b5 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1958,7 +1958,7 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
if (drm_WARN_ON(&i915->drm, !gvt))
return;
- mdev_unregister_device(i915->drm.dev);
+ 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);
@@ -2063,7 +2063,8 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
if (ret)
goto out_destroy_idle_vgpu;
- ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_driver);
+ ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
+ &intel_vgpu_mdev_driver);
if (ret)
goto out_cleanup_vgpu_type_groups;
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index fa8df50bb49e3..22be5ac7d23c1 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -5,6 +5,7 @@
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+#include <linux/mdev.h>
#include <asm/chpid.h>
#include <asm/cio.h>
#include <asm/fcx.h>
@@ -108,6 +109,7 @@ struct subchannel {
* frees it. Use driver_set_override() to set or clear it.
*/
const char *driver_override;
+ struct mdev_parent parent;
} __attribute__ ((aligned(8)));
DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index b49e2e9db2dc6..9192a21085ce4 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -11,7 +11,6 @@
*/
#include <linux/vfio.h>
-#include <linux/mdev.h>
#include <linux/nospec.h>
#include <linux/slab.h>
@@ -660,10 +659,11 @@ struct mdev_driver vfio_ccw_mdev_driver = {
int vfio_ccw_mdev_reg(struct subchannel *sch)
{
- return mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
+ return mdev_register_parent(&sch->parent, &sch->dev,
+ &vfio_ccw_mdev_driver);
}
void vfio_ccw_mdev_unreg(struct subchannel *sch)
{
- mdev_unregister_device(&sch->dev);
+ mdev_unregister_parent(&sch->parent);
}
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index a7d2a95796d36..834945150dc9f 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1485,7 +1485,8 @@ int vfio_ap_mdev_register(void)
if (ret)
return ret;
- ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_driver);
+ ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
+ &vfio_ap_matrix_driver);
if (ret)
goto err_driver;
return 0;
@@ -1497,6 +1498,6 @@ int vfio_ap_mdev_register(void)
void vfio_ap_mdev_unregister(void)
{
- mdev_unregister_device(&matrix_dev->device);
+ mdev_unregister_parent(&matrix_dev->parent);
mdev_unregister_driver(&vfio_ap_matrix_driver);
}
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 6616aa83347ad..0191f6bc973a4 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -45,6 +45,7 @@ struct ap_matrix_dev {
struct list_head mdev_list;
struct mutex lock;
struct ap_driver *vfio_ap_drv;
+ struct mdev_parent parent;
};
extern struct ap_matrix_dev *matrix_dev;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 2c32923fbad27..fa05ac3396950 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -18,8 +18,6 @@
#define DRIVER_AUTHOR "NVIDIA Corporation"
#define DRIVER_DESC "Mediated device Core Driver"
-static LIST_HEAD(parent_list);
-static DEFINE_MUTEX(parent_list_lock);
static struct class_compat *mdev_bus_compat_class;
static LIST_HEAD(mdev_list);
@@ -61,28 +59,6 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype)
}
EXPORT_SYMBOL(mtype_get_parent_dev);
-/* Should be called holding parent_list_lock */
-static struct mdev_parent *__find_parent_device(struct device *dev)
-{
- struct mdev_parent *parent;
-
- list_for_each_entry(parent, &parent_list, next) {
- if (parent->dev == dev)
- return parent;
- }
- return NULL;
-}
-
-void mdev_release_parent(struct kref *kref)
-{
- struct mdev_parent *parent = container_of(kref, struct mdev_parent,
- ref);
- struct device *dev = parent->dev;
-
- kfree(parent);
- put_device(dev);
-}
-
/* Caller must hold parent unreg_sem read or write lock */
static void mdev_device_remove_common(struct mdev_device *mdev)
{
@@ -105,125 +81,73 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
}
/*
- * mdev_register_device : Register a device
+ * mdev_register_parent: Register a device as parent for mdevs
+ * @parent: parent structure registered
* @dev: device structure representing parent device.
* @mdev_driver: Device driver to bind to the newly created mdev
*
- * Add device to list of registered parent devices.
+ * Registers the @parent stucture as a parent for mdev types and thus mdev
+ * devices. The caller needs to hold a reference on @dev that must not be
+ * released until after the call to mdev_unregister_parent().
+ *
* Returns a negative value on error, otherwise 0.
*/
-int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver)
+int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+ struct mdev_driver *mdev_driver)
{
- int ret;
- struct mdev_parent *parent;
char *env_string = "MDEV_STATE=registered";
char *envp[] = { env_string, NULL };
+ int ret;
/* check for mandatory ops */
if (!mdev_driver->supported_type_groups)
return -EINVAL;
- dev = get_device(dev);
- if (!dev)
- return -EINVAL;
-
- mutex_lock(&parent_list_lock);
-
- /* Check for duplicate */
- parent = __find_parent_device(dev);
- if (parent) {
- parent = NULL;
- ret = -EEXIST;
- goto add_dev_err;
- }
-
- parent = kzalloc(sizeof(*parent), GFP_KERNEL);
- if (!parent) {
- ret = -ENOMEM;
- goto add_dev_err;
- }
-
- kref_init(&parent->ref);
+ memset(parent, 0, sizeof(*parent));
init_rwsem(&parent->unreg_sem);
-
parent->dev = dev;
parent->mdev_driver = mdev_driver;
if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
- if (!mdev_bus_compat_class) {
- ret = -ENOMEM;
- goto add_dev_err;
- }
+ if (!mdev_bus_compat_class)
+ return -ENOMEM;
}
ret = parent_create_sysfs_files(parent);
if (ret)
- goto add_dev_err;
+ return ret;
ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
if (ret)
dev_warn(dev, "Failed to create compatibility class link\n");
- list_add(&parent->next, &parent_list);
- mutex_unlock(&parent_list_lock);
-
dev_info(dev, "MDEV: Registered\n");
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
-
return 0;
-
-add_dev_err:
- mutex_unlock(&parent_list_lock);
- if (parent)
- mdev_put_parent(parent);
- else
- put_device(dev);
- return ret;
}
-EXPORT_SYMBOL(mdev_register_device);
+EXPORT_SYMBOL(mdev_register_parent);
/*
- * mdev_unregister_device : Unregister a parent device
- * @dev: device structure representing parent device.
- *
- * Remove device from list of registered parent devices. Give a chance to free
- * existing mediated devices for given device.
+ * mdev_unregister_parent : Unregister a parent device
+ * @parent: parent structure to unregister
*/
-
-void mdev_unregister_device(struct device *dev)
+void mdev_unregister_parent(struct mdev_parent *parent)
{
- struct mdev_parent *parent;
char *env_string = "MDEV_STATE=unregistered";
char *envp[] = { env_string, NULL };
- mutex_lock(&parent_list_lock);
- parent = __find_parent_device(dev);
-
- if (!parent) {
- mutex_unlock(&parent_list_lock);
- return;
- }
- dev_info(dev, "MDEV: Unregistering\n");
-
- list_del(&parent->next);
- mutex_unlock(&parent_list_lock);
+ dev_info(parent->dev, "MDEV: Unregistering\n");
down_write(&parent->unreg_sem);
-
- class_compat_remove_link(mdev_bus_compat_class, dev, NULL);
-
- device_for_each_child(dev, NULL, mdev_device_remove_cb);
-
+ class_compat_remove_link(mdev_bus_compat_class, parent->dev, NULL);
+ device_for_each_child(parent->dev, NULL, mdev_device_remove_cb);
parent_remove_sysfs_files(parent);
up_write(&parent->unreg_sem);
- mdev_put_parent(parent);
-
- /* We still have the caller's reference to use for the uevent */
- kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+ kobject_uevent_env(&parent->dev->kobj, KOBJ_CHANGE, envp);
}
-EXPORT_SYMBOL(mdev_unregister_device);
+EXPORT_SYMBOL(mdev_unregister_parent);
static void mdev_device_release(struct device *dev)
{
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index 7c9fc79f3d838..297f911fdc890 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -13,17 +13,6 @@
int mdev_bus_register(void);
void mdev_bus_unregister(void);
-struct mdev_parent {
- struct device *dev;
- struct mdev_driver *mdev_driver;
- struct kref ref;
- struct list_head next;
- struct kset *mdev_types_kset;
- struct list_head type_list;
- /* Synchronize device creation/removal with parent unregistration */
- struct rw_semaphore unreg_sem;
-};
-
struct mdev_type {
struct kobject kobj;
struct kobject *devices_kobj;
@@ -48,16 +37,4 @@ void mdev_remove_sysfs_files(struct mdev_device *mdev);
int mdev_device_create(struct mdev_type *kobj, const guid_t *uuid);
int mdev_device_remove(struct mdev_device *dev);
-void mdev_release_parent(struct kref *kref);
-
-static inline void mdev_get_parent(struct mdev_parent *parent)
-{
- kref_get(&parent->ref);
-}
-
-static inline void mdev_put_parent(struct mdev_parent *parent)
-{
- kref_put(&parent->ref, mdev_release_parent);
-}
-
#endif /* MDEV_PRIVATE_H */
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 4bfbf49aaa66a..b71ffc5594870 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -81,7 +81,7 @@ static void mdev_type_release(struct kobject *kobj)
pr_debug("Releasing group %s\n", kobj->name);
/* Pairs with the get in add_mdev_supported_type() */
- mdev_put_parent(type->parent);
+ put_device(type->parent->dev);
kfree(type);
}
@@ -110,7 +110,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
type->kobj.kset = parent->mdev_types_kset;
type->parent = parent;
/* Pairs with the put in mdev_type_release() */
- mdev_get_parent(parent);
+ get_device(parent->dev);
type->type_group_id = type_group_id;
ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL,
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 555c1d015b5f0..327ce3e5c6b5f 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -23,6 +23,16 @@ struct mdev_device {
bool active;
};
+/* embedded into the struct device that the mdev devices hang off */
+struct mdev_parent {
+ struct device *dev;
+ struct mdev_driver *mdev_driver;
+ struct kset *mdev_types_kset;
+ struct list_head type_list;
+ /* Synchronize device creation/removal with parent unregistration */
+ struct rw_semaphore unreg_sem;
+};
+
static inline struct mdev_device *to_mdev_device(struct device *dev)
{
return container_of(dev, struct mdev_device, dev);
@@ -75,8 +85,9 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
extern struct bus_type mdev_bus_type;
-int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver);
-void mdev_unregister_device(struct device *dev);
+int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+ struct mdev_driver *mdev_driver);
+void mdev_unregister_parent(struct mdev_parent *parent);
int mdev_register_driver(struct mdev_driver *drv);
void mdev_unregister_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index d0d1bb7747240..30b3643b3b389 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -128,6 +128,7 @@ static dev_t mbochs_devt;
static struct class *mbochs_class;
static struct cdev mbochs_cdev;
static struct device mbochs_dev;
+static struct mdev_parent mbochs_parent;
static atomic_t mbochs_avail_mbytes;
static const struct vfio_device_ops mbochs_dev_ops;
@@ -1456,7 +1457,7 @@ static int __init mbochs_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mbochs_dev, &mbochs_driver);
+ ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
if (ret)
goto err_device;
@@ -1477,7 +1478,7 @@ static int __init mbochs_dev_init(void)
static void __exit mbochs_dev_exit(void)
{
mbochs_dev.bus = NULL;
- mdev_unregister_device(&mbochs_dev);
+ mdev_unregister_parent(&mbochs_parent);
device_unregister(&mbochs_dev);
mdev_unregister_driver(&mbochs_driver);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 0c4ca1f4be7ed..132bb055628a6 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -83,6 +83,7 @@ static dev_t mdpy_devt;
static struct class *mdpy_class;
static struct cdev mdpy_cdev;
static struct device mdpy_dev;
+static struct mdev_parent mdpy_parent;
static u32 mdpy_count;
static const struct vfio_device_ops mdpy_dev_ops;
@@ -765,7 +766,7 @@ static int __init mdpy_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mdpy_dev, &mdpy_driver);
+ ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver);
if (ret)
goto err_device;
@@ -786,7 +787,7 @@ static int __init mdpy_dev_init(void)
static void __exit mdpy_dev_exit(void)
{
mdpy_dev.bus = NULL;
- mdev_unregister_device(&mdpy_dev);
+ mdev_unregister_parent(&mdpy_parent);
device_unregister(&mdpy_dev);
mdev_unregister_driver(&mdpy_driver);
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 4f5a6f2d3629d..8ba5f6084a093 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -72,6 +72,7 @@ static struct mtty_dev {
struct cdev vd_cdev;
struct idr vd_idr;
struct device dev;
+ struct mdev_parent parent;
} mtty_dev;
struct mdev_region_info {
@@ -1350,7 +1351,8 @@ static int __init mtty_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mtty_dev.dev, &mtty_driver);
+ ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
+ &mtty_driver);
if (ret)
goto err_device;
return 0;
@@ -1370,7 +1372,7 @@ static int __init mtty_dev_init(void)
static void __exit mtty_dev_exit(void)
{
mtty_dev.dev.bus = NULL;
- mdev_unregister_device(&mtty_dev.dev);
+ mdev_unregister_parent(&mtty_dev.parent);
device_unregister(&mtty_dev.dev);
idr_destroy(&mtty_dev.vd_idr);
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure
2022-07-04 12:51 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-07-04 15:56 ` Jason Gunthorpe
0 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2022-07-04 15:56 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, Jul 04, 2022 at 02:51:34PM +0200, Christoph Hellwig wrote:
> Simplify mdev_{un}register_device by requiring the caller to pass in
> a structure allocate as part of the parent device structure. This
> removes the need for a list of parents and the separate mdev_parent
> refcount as we can simplify rely on the reference to the parent device.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> ---
> .../driver-api/vfio-mediated-device.rst | 12 +-
> Documentation/s390/vfio-ap.rst | 2 +-
> Documentation/s390/vfio-ccw.rst | 2 +-
> drivers/gpu/drm/i915/gvt/gvt.h | 2 +
> drivers/gpu/drm/i915/gvt/kvmgt.c | 5 +-
> drivers/s390/cio/cio.h | 2 +
> drivers/s390/cio/vfio_ccw_ops.c | 6 +-
> drivers/s390/crypto/vfio_ap_ops.c | 5 +-
> drivers/s390/crypto/vfio_ap_private.h | 1 +
> drivers/vfio/mdev/mdev_core.c | 120 ++++--------------
> drivers/vfio/mdev/mdev_private.h | 23 ----
> drivers/vfio/mdev/mdev_sysfs.c | 4 +-
> include/linux/mdev.h | 15 ++-
> samples/vfio-mdev/mbochs.c | 5 +-
> samples/vfio-mdev/mdpy.c | 5 +-
> samples/vfio-mdev/mtty.c | 6 +-
> 16 files changed, 69 insertions(+), 146 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 05/14] vfio/mdev: simplify mdev_type handling
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (3 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 06/14] vfio/mdev: remove mdev_from_dev Christoph Hellwig
` (8 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
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: Kevin Tian <kevin.tian@intel.com>
---
.../driver-api/vfio-mediated-device.rst | 2 +-
drivers/gpu/drm/i915/gvt/gvt.h | 3 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 98 +++----------------
drivers/gpu/drm/i915/gvt/vgpu.c | 13 ++-
drivers/s390/cio/cio.h | 2 +
drivers/s390/cio/vfio_ccw_ops.c | 19 ++--
drivers/s390/crypto/vfio_ap_ops.c | 19 ++--
drivers/s390/crypto/vfio_ap_private.h | 2 +
drivers/vfio/mdev/mdev_core.c | 31 ++----
drivers/vfio/mdev/mdev_driver.c | 5 +-
drivers/vfio/mdev/mdev_private.h | 8 --
drivers/vfio/mdev/mdev_sysfs.c | 90 +++++------------
include/linux/mdev.h | 26 +++--
samples/vfio-mdev/mbochs.c | 57 +++++------
samples/vfio-mdev/mdpy.c | 50 ++++------
samples/vfio-mdev/mtty.c | 62 ++++++------
16 files changed, 165 insertions(+), 322 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 62a82afce161b..82a4007bd7207 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -105,7 +105,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;
};
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index bbf0116671ecb..f9690dca0a857 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -311,8 +311,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;
@@ -340,6 +340,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;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index e9dba4c0fe6b5..ead56e4d30650 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -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)
{
@@ -1614,14 +1551,11 @@ static int intel_vgpu_probe(struct mdev_device *mdev)
{
struct device *pdev = mdev_parent_dev(mdev);
struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
- struct intel_vgpu_type *type;
+ struct intel_vgpu_type *type =
+ container_of(mdev->type, struct intel_vgpu_type, type);
struct intel_vgpu *vgpu;
int ret;
- type = &gvt->types[mdev_get_type_group_id(mdev)];
- if (!type)
- return -EINVAL;
-
vgpu = intel_gvt_create_vgpu(gvt, type->conf);
if (IS_ERR(vgpu)) {
gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
@@ -1660,7 +1594,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)
@@ -1959,7 +1893,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);
@@ -2059,20 +1992,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);
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 8e136dcc70112..ff240503d4125 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -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);
}
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 22be5ac7d23c1..1da45307a1862 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -110,6 +110,8 @@ struct subchannel {
*/
const char *driver_override;
struct mdev_parent parent;
+ struct mdev_type mdev_type;
+ struct mdev_type *mdev_types[1];
} __attribute__ ((aligned(8)));
DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 9192a21085ce4..1bb30313a630c 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -95,23 +95,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_probe(struct mdev_device *mdev)
{
struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
@@ -654,13 +644,16 @@ 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,
};
int vfio_ccw_mdev_reg(struct subchannel *sch)
{
+ sch->mdev_type.sysfs_name = "io";
+ sch->mdev_types[0] = &sch->mdev_type;
return mdev_register_parent(&sch->parent, &sch->dev,
- &vfio_ccw_mdev_driver);
+ &vfio_ccw_mdev_driver, sch->mdev_types,
+ 1);
}
void vfio_ccw_mdev_unreg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 834945150dc9f..41e8ecb7f56b9 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -537,23 +537,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,
-};
-
struct vfio_ap_queue_reserved {
unsigned long *apid;
unsigned long *apqi;
@@ -1472,7 +1462,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)
@@ -1485,8 +1475,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;
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 0191f6bc973a4..5dc5050d03791 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -46,6 +46,8 @@ struct ap_matrix_dev {
struct mutex lock;
struct ap_driver *vfio_ap_drv;
struct mdev_parent parent;
+ struct mdev_type mdev_type;
+ struct mdev_type *mdev_types[];
};
extern struct ap_matrix_dev *matrix_dev;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index fa05ac3396950..2d95a497fd3b2 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -29,26 +29,6 @@ struct device *mdev_parent_dev(struct mdev_device *mdev)
}
EXPORT_SYMBOL(mdev_parent_dev);
-/*
- * Return the index in supported_type_groups that this mdev_device was created
- * from.
- */
-unsigned int mdev_get_type_group_id(struct mdev_device *mdev)
-{
- return mdev->type->type_group_id;
-}
-EXPORT_SYMBOL(mdev_get_type_group_id);
-
-/*
- * Used in mdev_type_attribute sysfs functions to return the index in the
- * supported_type_groups that the sysfs is called from.
- */
-unsigned int mtype_get_type_group_id(struct mdev_type *mtype)
-{
- return mtype->type_group_id;
-}
-EXPORT_SYMBOL(mtype_get_type_group_id);
-
/*
* Used in mdev_type_attribute sysfs functions to return the parent struct
* device
@@ -85,6 +65,8 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
* @parent: parent structure registered
* @dev: device structure representing parent device.
* @mdev_driver: Device driver to bind to the newly created mdev
+ * @types: Array of supported mdev types
+ * @nr_types: Number of entries in @types
*
* Registers the @parent stucture as a parent for mdev types and thus mdev
* devices. The caller needs to hold a reference on @dev that must not be
@@ -93,20 +75,19 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
* Returns a negative value on error, otherwise 0.
*/
int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
- struct mdev_driver *mdev_driver)
+ struct mdev_driver *mdev_driver, struct mdev_type **types,
+ unsigned int nr_types)
{
char *env_string = "MDEV_STATE=registered";
char *envp[] = { env_string, NULL };
int ret;
- /* check for mandatory ops */
- if (!mdev_driver->supported_type_groups)
- return -EINVAL;
-
memset(parent, 0, sizeof(*parent));
init_rwsem(&parent->unreg_sem);
parent->dev = dev;
parent->mdev_driver = mdev_driver;
+ parent->types = types;
+ parent->nr_types = nr_types;
if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 7bd4bb9850e81..1da1ecf76a0d5 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -56,10 +56,9 @@ EXPORT_SYMBOL_GPL(mdev_bus_type);
**/
int mdev_register_driver(struct mdev_driver *drv)
{
- /* initialize common driver fields */
+ if (!drv->types_attrs)
+ return -EINVAL;
drv->driver.bus = &mdev_bus_type;
-
- /* register with core */
return driver_register(&drv->driver);
}
EXPORT_SYMBOL(mdev_register_driver);
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index 297f911fdc890..ba1b2dbddc0bc 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -13,14 +13,6 @@
int mdev_bus_register(void);
void mdev_bus_unregister(void);
-struct mdev_type {
- struct kobject kobj;
- struct kobject *devices_kobj;
- struct mdev_parent *parent;
- struct list_head next;
- unsigned int type_group_id;
-};
-
extern const struct attribute_group *mdev_device_groups[];
#define to_mdev_type_attr(_attr) \
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index b71ffc5594870..80b2d546a3d98 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -90,35 +90,21 @@ static struct kobj_type mdev_type_ktype = {
.release = mdev_type_release,
};
-static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
- unsigned int type_group_id)
+static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
{
- struct mdev_type *type;
- struct attribute_group *group =
- parent->mdev_driver->supported_type_groups[type_group_id];
int ret;
- if (!group->name) {
- pr_err("%s: Type name empty!\n", __func__);
- return ERR_PTR(-EINVAL);
- }
-
- type = kzalloc(sizeof(*type), GFP_KERNEL);
- if (!type)
- return ERR_PTR(-ENOMEM);
-
type->kobj.kset = parent->mdev_types_kset;
type->parent = parent;
/* Pairs with the put in mdev_type_release() */
get_device(parent->dev);
- type->type_group_id = type_group_id;
ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL,
"%s-%s", dev_driver_string(parent->dev),
- group->name);
+ type->sysfs_name);
if (ret) {
kobject_put(&type->kobj);
- return ERR_PTR(ret);
+ return ret;
}
ret = sysfs_create_file(&type->kobj, &mdev_type_attr_create.attr);
@@ -131,13 +117,10 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
goto attr_devices_failed;
}
- ret = sysfs_create_files(&type->kobj,
- (const struct attribute **)group->attrs);
- if (ret) {
- ret = -ENOMEM;
+ ret = sysfs_create_files(&type->kobj, parent->mdev_driver->types_attrs);
+ if (ret)
goto attrs_failed;
- }
- return type;
+ return 0;
attrs_failed:
kobject_put(type->devices_kobj);
@@ -146,78 +129,49 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
attr_create_failed:
kobject_del(&type->kobj);
kobject_put(&type->kobj);
- return ERR_PTR(ret);
+ return ret;
}
-static void remove_mdev_supported_type(struct mdev_type *type)
+static void mdev_type_remove(struct mdev_type *type)
{
- struct attribute_group *group =
- type->parent->mdev_driver->supported_type_groups[type->type_group_id];
+ sysfs_remove_files(&type->kobj, type->parent->mdev_driver->types_attrs);
- sysfs_remove_files(&type->kobj,
- (const struct attribute **)group->attrs);
kobject_put(type->devices_kobj);
sysfs_remove_file(&type->kobj, &mdev_type_attr_create.attr);
kobject_del(&type->kobj);
kobject_put(&type->kobj);
}
-static int add_mdev_supported_type_groups(struct mdev_parent *parent)
-{
- int i;
-
- for (i = 0; parent->mdev_driver->supported_type_groups[i]; i++) {
- struct mdev_type *type;
-
- type = add_mdev_supported_type(parent, i);
- if (IS_ERR(type)) {
- struct mdev_type *ltype, *tmp;
-
- list_for_each_entry_safe(ltype, tmp, &parent->type_list,
- next) {
- list_del(<ype->next);
- remove_mdev_supported_type(ltype);
- }
- return PTR_ERR(type);
- }
- list_add(&type->next, &parent->type_list);
- }
- return 0;
-}
-
/* mdev sysfs functions */
void parent_remove_sysfs_files(struct mdev_parent *parent)
{
- struct mdev_type *type, *tmp;
-
- list_for_each_entry_safe(type, tmp, &parent->type_list, next) {
- list_del(&type->next);
- remove_mdev_supported_type(type);
- }
+ int i;
+ for (i = 0; i < parent->nr_types; i++)
+ mdev_type_remove(parent->types[i]);
kset_unregister(parent->mdev_types_kset);
}
int parent_create_sysfs_files(struct mdev_parent *parent)
{
- int ret;
+ int ret, i;
parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
NULL, &parent->dev->kobj);
-
if (!parent->mdev_types_kset)
return -ENOMEM;
- INIT_LIST_HEAD(&parent->type_list);
-
- ret = add_mdev_supported_type_groups(parent);
- if (ret)
- goto create_err;
+ for (i = 0; i < parent->nr_types; i++) {
+ ret = mdev_type_add(parent, parent->types[i]);
+ if (ret)
+ goto out_err;
+ }
return 0;
-create_err:
- kset_unregister(parent->mdev_types_kset);
- return ret;
+out_err:
+ while (--i >= 0)
+ mdev_type_remove(parent->types[i]);
+ return 0;
}
static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 327ce3e5c6b5f..cc70cc1e25d91 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -23,14 +23,27 @@ struct mdev_device {
bool active;
};
+struct mdev_type {
+ /* set by the driver before calling mdev_register parent: */
+ const char *sysfs_name;
+
+ /* set by the core, can be used drivers */
+ struct mdev_parent *parent;
+
+ /* internal only */
+ struct kobject kobj;
+ struct kobject *devices_kobj;
+};
+
/* embedded into the struct device that the mdev devices hang off */
struct mdev_parent {
struct device *dev;
struct mdev_driver *mdev_driver;
struct kset *mdev_types_kset;
- struct list_head type_list;
/* Synchronize device creation/removal with parent unregistration */
struct rw_semaphore unreg_sem;
+ struct mdev_type **types;
+ unsigned int nr_types;
};
static inline struct mdev_device *to_mdev_device(struct device *dev)
@@ -38,8 +51,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
return container_of(dev, struct mdev_device, dev);
}
-unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
-unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
struct device *mtype_get_parent_dev(struct mdev_type *mtype);
/* interface for exporting mdev supported type attributes */
@@ -66,15 +77,13 @@ struct mdev_type_attribute mdev_type_attr_##_name = \
* struct mdev_driver - Mediated device driver
* @probe: called when new device created
* @remove: called when device removed
- * @supported_type_groups: Attributes to define supported types. It is mandatory
- * to provide supported types.
+ * @types_attrs: attributes to the type kobjects.
* @driver: device driver structure
- *
**/
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;
};
@@ -86,7 +95,8 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
extern struct bus_type mdev_bus_type;
int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
- struct mdev_driver *mdev_driver);
+ struct mdev_driver *mdev_driver, struct mdev_type **types,
+ unsigned int nr_types);
void mdev_unregister_parent(struct mdev_parent *parent);
int mdev_register_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 30b3643b3b389..1069f561cb012 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -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;
@@ -508,8 +517,8 @@ static int mbochs_reset(struct mdev_state *mdev_state)
static int mbochs_probe(struct mdev_device *mdev)
{
int avail_mbytes = atomic_read(&mbochs_avail_mbytes);
- 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);
struct device *dev = mdev_dev(mdev);
struct mdev_state *mdev_state;
int ret = -ENOMEM;
@@ -1328,8 +1337,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);
}
@@ -1338,8 +1347,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);
@@ -1350,8 +1359,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);
@@ -1365,7 +1374,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,
@@ -1373,28 +1382,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,
.read = mbochs_read,
@@ -1412,7 +1399,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 = {
@@ -1457,7 +1444,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;
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 132bb055628a6..2052cc27b1c6d 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -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;
@@ -219,7 +229,7 @@ static int mdpy_reset(struct mdev_state *mdev_state)
static int mdpy_probe(struct mdev_device *mdev)
{
const struct mdpy_type *type =
- &mdpy_types[mdev_get_type_group_id(mdev)];
+ container_of(mdev->type, struct mdpy_type, type);
struct device *dev = mdev_dev(mdev);
struct mdev_state *mdev_state;
u32 fbsize;
@@ -644,8 +654,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);
}
@@ -654,8 +663,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);
@@ -677,7 +685,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,
@@ -685,28 +693,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 = {
.read = mdpy_read,
.write = mdpy_write,
@@ -723,7 +709,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 = {
@@ -766,7 +752,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;
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 8ba5f6084a093..029a19ef8ce7b 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -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 = {
@@ -704,16 +718,18 @@ static ssize_t mdev_access(struct mdev_state *mdev_state, u8 *buf, size_t count,
static int mtty_probe(struct mdev_device *mdev)
{
+ struct mtty_type *type =
+ container_of(mdev->type, struct mtty_type, type);
struct mdev_state *mdev_state;
- int nr_ports = mdev_get_type_group_id(mdev) + 1;
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 = kzalloc(sizeof(struct mdev_state), GFP_KERNEL);
if (mdev_state == NULL) {
@@ -723,13 +739,13 @@ static int mtty_probe(struct mdev_device *mdev)
vfio_init_group_dev(&mdev_state->vdev, &mdev->dev, &mtty_dev_ops);
- 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;
mutex_init(&mdev_state->rxtx_lock);
- mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL);
+ mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL);
if (mdev_state->vconfig == NULL) {
ret = -ENOMEM;
goto err_state;
@@ -752,7 +768,7 @@ static int mtty_probe(struct mdev_device *mdev)
vfio_uninit_group_dev(&mdev_state->vdev);
kfree(mdev_state);
err_nr_ports:
- atomic_add(nr_ports, &mdev_avail_ports);
+ atomic_add(type->nr_ports, &mdev_avail_ports);
return ret;
}
@@ -1233,11 +1249,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);
@@ -1246,9 +1260,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);
@@ -1261,29 +1276,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",
.read = mtty_read,
@@ -1300,7 +1299,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)
@@ -1352,7 +1351,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;
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/14] vfio/mdev: remove mdev_from_dev
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (4 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 07/14] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
` (7 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Just open code it in the only caller.
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>
---
drivers/vfio/mdev/mdev_core.c | 6 ++----
include/linux/mdev.h | 4 ----
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 2d95a497fd3b2..bde7ce620dae0 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -53,10 +53,8 @@ static void mdev_device_remove_common(struct mdev_device *mdev)
static int mdev_device_remove_cb(struct device *dev, void *data)
{
- struct mdev_device *mdev = mdev_from_dev(dev);
-
- if (mdev)
- mdev_device_remove_common(mdev);
+ if (dev->bus == &mdev_bus_type)
+ mdev_device_remove_common(to_mdev_device(dev));
return 0;
}
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index cc70cc1e25d91..411b655c36ab2 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -107,9 +107,5 @@ static inline struct device *mdev_dev(struct mdev_device *mdev)
{
return &mdev->dev;
}
-static inline struct mdev_device *mdev_from_dev(struct device *dev)
-{
- return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL;
-}
#endif /* MDEV_H */
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 07/14] vfio/mdev: unexport mdev_bus_type
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (5 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 06/14] vfio/mdev: remove mdev_from_dev Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 08/14] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
` (6 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
mdev_bus_type is only used in mdev.ko now, so unexport 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>
---
drivers/vfio/mdev/mdev_driver.c | 1 -
drivers/vfio/mdev/mdev_private.h | 1 +
include/linux/mdev.h | 2 --
3 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 1da1ecf76a0d5..5b3c94f4fb13d 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -46,7 +46,6 @@ struct bus_type mdev_bus_type = {
.remove = mdev_remove,
.match = mdev_match,
};
-EXPORT_SYMBOL_GPL(mdev_bus_type);
/**
* mdev_register_driver - register a new MDEV driver
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index ba1b2dbddc0bc..af457b27f6074 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -13,6 +13,7 @@
int mdev_bus_register(void);
void mdev_bus_unregister(void);
+extern struct bus_type mdev_bus_type;
extern const struct attribute_group *mdev_device_groups[];
#define to_mdev_type_attr(_attr) \
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 411b655c36ab2..2ca85b6072b9e 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -92,8 +92,6 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
return &mdev->uuid;
}
-extern struct bus_type mdev_bus_type;
-
int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
struct mdev_driver *mdev_driver, struct mdev_type **types,
unsigned int nr_types);
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/14] vfio/mdev: remove mdev_parent_dev
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (6 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 07/14] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
` (5 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Just open code the dereferences in the only user.
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>
---
Documentation/driver-api/vfio-mediated-device.rst | 3 ---
drivers/gpu/drm/i915/gvt/kvmgt.c | 2 +-
drivers/vfio/mdev/mdev_core.c | 6 ------
include/linux/mdev.h | 1 -
4 files changed, 1 insertion(+), 11 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 82a4007bd7207..a4c3a4a168ec6 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -202,9 +202,6 @@ Directories and files under the sysfs for Each Physical Device
sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
- (or using mdev_parent_dev(mdev) to arrive at the parent device outside
- of the core mdev code)
-
* device_api
This attribute should show which device API is being created, for example,
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index ead56e4d30650..3473d4bafd61e 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1549,7 +1549,7 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
static int intel_vgpu_probe(struct mdev_device *mdev)
{
- struct device *pdev = mdev_parent_dev(mdev);
+ struct device *pdev = mdev->type->parent->dev;
struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
struct intel_vgpu_type *type =
container_of(mdev->type, struct intel_vgpu_type, type);
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index bde7ce620dae0..75628759a3bf0 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -23,12 +23,6 @@ static struct class_compat *mdev_bus_compat_class;
static LIST_HEAD(mdev_list);
static DEFINE_MUTEX(mdev_list_lock);
-struct device *mdev_parent_dev(struct mdev_device *mdev)
-{
- return mdev->type->parent->dev;
-}
-EXPORT_SYMBOL(mdev_parent_dev);
-
/*
* Used in mdev_type_attribute sysfs functions to return the parent struct
* device
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 2ca85b6072b9e..186e5c866871e 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -100,7 +100,6 @@ void mdev_unregister_parent(struct mdev_parent *parent);
int mdev_register_driver(struct mdev_driver *drv);
void mdev_unregister_driver(struct mdev_driver *drv);
-struct device *mdev_parent_dev(struct mdev_device *mdev);
static inline struct device *mdev_dev(struct mdev_device *mdev)
{
return &mdev->dev;
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (7 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 08/14] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
` (4 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Just open code the dereferences in the only user.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
---
drivers/s390/cio/vfio_ccw_ops.c | 3 +--
drivers/vfio/mdev/mdev_core.c | 10 ----------
include/linux/mdev.h | 2 --
3 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 1bb30313a630c..fb62049471ee2 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -88,8 +88,7 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
{
- struct vfio_ccw_private *private =
- dev_get_drvdata(mtype_get_parent_dev(mtype));
+ struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
return sprintf(buf, "%d\n", atomic_read(&private->avail));
}
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 75628759a3bf0..93f8caf2e5f77 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -23,16 +23,6 @@ static struct class_compat *mdev_bus_compat_class;
static LIST_HEAD(mdev_list);
static DEFINE_MUTEX(mdev_list_lock);
-/*
- * Used in mdev_type_attribute sysfs functions to return the parent struct
- * device
- */
-struct device *mtype_get_parent_dev(struct mdev_type *mtype)
-{
- return mtype->parent->dev;
-}
-EXPORT_SYMBOL(mtype_get_parent_dev);
-
/* Caller must hold parent unreg_sem read or write lock */
static void mdev_device_remove_common(struct mdev_device *mdev)
{
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 186e5c866871e..29fc1c853dacc 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -51,8 +51,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
return container_of(dev, struct mdev_device, dev);
}
-struct device *mtype_get_parent_dev(struct mdev_type *mtype);
-
/* interface for exporting mdev supported type attributes */
struct mdev_type_attribute {
struct attribute attr;
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (8 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 11/14] vfio/mdev: consolidate all the name " Christoph Hellwig
` (3 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Every driver just emits a static string, simply feed it through the ops
and provide a standard sysfs show function.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
---
.../driver-api/vfio-mediated-device.rst | 2 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 9 +----
drivers/s390/cio/vfio_ccw_ops.c | 9 +----
drivers/s390/crypto/vfio_ap_ops.c | 10 +-----
drivers/vfio/mdev/mdev_driver.c | 4 ++-
drivers/vfio/mdev/mdev_sysfs.c | 35 +++++++++++++------
include/linux/mdev.h | 7 ++--
samples/vfio-mdev/mbochs.c | 9 +----
samples/vfio-mdev/mdpy.c | 9 +----
samples/vfio-mdev/mtty.c | 10 +-----
10 files changed, 37 insertions(+), 67 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index a4c3a4a168ec6..c30cb1092bdfb 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -204,7 +204,7 @@ Directories and files under the sysfs for Each Physical Device
* device_api
- This attribute should show which device API is being created, for example,
+ This attribute shows which device API is being created, for example,
"vfio-pci" for a PCI device.
* available_instances
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 3473d4bafd61e..a70610929fed2 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -123,12 +123,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
return sprintf(buf, "%u\n", type->avail_instance);
}
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
@@ -151,13 +145,11 @@ static ssize_t name_show(struct mdev_type *mtype,
}
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 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,
@@ -1587,6 +1579,7 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
}
static struct mdev_driver intel_vgpu_mdev_driver = {
+ .device_api = VFIO_DEVICE_API_PCI_STRING,
.driver = {
.name = "intel_vgpu_mdev",
.owner = THIS_MODULE,
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index fb62049471ee2..74ff2d9719d02 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -77,13 +77,6 @@ static ssize_t name_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(name);
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
-}
-static MDEV_TYPE_ATTR_RO(device_api);
-
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -96,7 +89,6 @@ static MDEV_TYPE_ATTR_RO(available_instances);
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,
};
@@ -636,6 +628,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
};
struct mdev_driver vfio_ccw_mdev_driver = {
+ .device_api = VFIO_DEVICE_API_CCW_STRING,
.driver = {
.name = "vfio_ccw_mdev",
.owner = THIS_MODULE,
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 41e8ecb7f56b9..023b659c812c9 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -529,17 +529,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_AP_STRING);
-}
-
-static MDEV_TYPE_ATTR_RO(device_api);
-
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,
};
@@ -1454,6 +1445,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
};
static struct mdev_driver vfio_ap_matrix_driver = {
+ .device_api = VFIO_DEVICE_API_AP_STRING,
.driver = {
.name = "vfio_ap_mdev",
.owner = THIS_MODULE,
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 5b3c94f4fb13d..60e8b9f6474e8 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -55,8 +55,10 @@ struct bus_type mdev_bus_type = {
**/
int mdev_register_driver(struct mdev_driver *drv)
{
- if (!drv->types_attrs)
+ if (!drv->types_attrs || !drv->device_api)
return -EINVAL;
+
+ /* initialize common driver fields */
drv->driver.bus = &mdev_bus_type;
return driver_register(&drv->driver);
}
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 80b2d546a3d98..89637bc85462a 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -72,9 +72,30 @@ static ssize_t create_store(struct mdev_type *mtype,
return count;
}
-
static MDEV_TYPE_ATTR_WO(create);
+static ssize_t device_api_show(struct mdev_type *mtype,
+ struct mdev_type_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%s\n", mtype->parent->mdev_driver->device_api);
+}
+static MDEV_TYPE_ATTR_RO(device_api);
+
+static struct attribute *mdev_types_core_attrs[] = {
+ &mdev_type_attr_create.attr,
+ &mdev_type_attr_device_api.attr,
+ NULL,
+};
+
+static struct attribute_group mdev_type_core_group = {
+ .attrs = mdev_types_core_attrs,
+};
+
+static const struct attribute_group *mdev_type_groups[] = {
+ &mdev_type_core_group,
+ NULL,
+};
+
static void mdev_type_release(struct kobject *kobj)
{
struct mdev_type *type = to_mdev_type(kobj);
@@ -86,8 +107,9 @@ static void mdev_type_release(struct kobject *kobj)
}
static struct kobj_type mdev_type_ktype = {
- .sysfs_ops = &mdev_type_sysfs_ops,
- .release = mdev_type_release,
+ .sysfs_ops = &mdev_type_sysfs_ops,
+ .release = mdev_type_release,
+ .default_groups = mdev_type_groups,
};
static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
@@ -107,10 +129,6 @@ static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
return ret;
}
- ret = sysfs_create_file(&type->kobj, &mdev_type_attr_create.attr);
- if (ret)
- goto attr_create_failed;
-
type->devices_kobj = kobject_create_and_add("devices", &type->kobj);
if (!type->devices_kobj) {
ret = -ENOMEM;
@@ -125,8 +143,6 @@ static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
attrs_failed:
kobject_put(type->devices_kobj);
attr_devices_failed:
- sysfs_remove_file(&type->kobj, &mdev_type_attr_create.attr);
-attr_create_failed:
kobject_del(&type->kobj);
kobject_put(&type->kobj);
return ret;
@@ -137,7 +153,6 @@ 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);
- sysfs_remove_file(&type->kobj, &mdev_type_attr_create.attr);
kobject_del(&type->kobj);
kobject_put(&type->kobj);
}
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 29fc1c853dacc..51a6f2ddcf9c6 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -61,11 +61,6 @@ struct mdev_type_attribute {
size_t count);
};
-#define MDEV_TYPE_ATTR(_name, _mode, _show, _store) \
-struct mdev_type_attribute mdev_type_attr_##_name = \
- __ATTR(_name, _mode, _show, _store)
-#define MDEV_TYPE_ATTR_RW(_name) \
- struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RW(_name)
#define MDEV_TYPE_ATTR_RO(_name) \
struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RO(_name)
#define MDEV_TYPE_ATTR_WO(_name) \
@@ -73,12 +68,14 @@ struct mdev_type_attribute mdev_type_attr_##_name = \
/**
* struct mdev_driver - Mediated device driver
+ * @device_api: string to return for the device_api sysfs
* @probe: called when new device created
* @remove: called when device removed
* @types_attrs: attributes to the type kobjects.
* @driver: device driver structure
**/
struct mdev_driver {
+ const char *device_api;
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
const struct attribute * const *types_attrs;
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 1069f561cb012..199846f01de92 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1367,17 +1367,9 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(available_instances);
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-static MDEV_TYPE_ATTR_RO(device_api);
-
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_name.attr,
&mdev_type_attr_description.attr,
- &mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
@@ -1391,6 +1383,7 @@ static const struct vfio_device_ops mbochs_dev_ops = {
};
static struct mdev_driver mbochs_driver = {
+ .device_api = VFIO_DEVICE_API_PCI_STRING,
.driver = {
.name = "mbochs",
.owner = THIS_MODULE,
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 2052cc27b1c6d..b8d6eeff2033d 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -678,17 +678,9 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(available_instances);
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-static MDEV_TYPE_ATTR_RO(device_api);
-
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_name.attr,
&mdev_type_attr_description.attr,
- &mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
@@ -701,6 +693,7 @@ static const struct vfio_device_ops mdpy_dev_ops = {
};
static struct mdev_driver mdpy_driver = {
+ .device_api = VFIO_DEVICE_API_PCI_STRING,
.driver = {
.name = "mdpy",
.owner = THIS_MODULE,
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 029a19ef8ce7b..2a470424628af 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -1268,17 +1268,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
-static ssize_t device_api_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-
-static MDEV_TYPE_ATTR_RO(device_api);
-
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,
};
@@ -1291,6 +1282,7 @@ static const struct vfio_device_ops mtty_dev_ops = {
};
static struct mdev_driver mtty_driver = {
+ .device_api = VFIO_DEVICE_API_PCI_STRING,
.driver = {
.name = "mtty",
.owner = THIS_MODULE,
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/14] vfio/mdev: consolidate all the name sysfs into the core code
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (9 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 12/14] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
` (2 subsequent siblings)
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Every driver just emits a static string, simply add a field to the
mdev_type for the driver to fill out or fall back to the sysfs name and
provide a standard sysfs show function.
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>
---
.../driver-api/vfio-mediated-device.rst | 2 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 8 -------
drivers/s390/cio/vfio_ccw_ops.c | 9 +-------
drivers/s390/crypto/vfio_ap_ops.c | 9 --------
drivers/vfio/mdev/mdev_sysfs.c | 10 +++++++++
include/linux/mdev.h | 1 +
samples/vfio-mdev/mbochs.c | 20 ++++--------------
samples/vfio-mdev/mdpy.c | 21 +++++--------------
samples/vfio-mdev/mtty.c | 18 ++++------------
9 files changed, 26 insertions(+), 72 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index c30cb1092bdfb..334e649360353 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -219,7 +219,7 @@ Directories and files under the sysfs for Each Physical Device
* name
- This attribute should show human readable name. This is optional attribute.
+ This attribute shows a human readable name.
* description
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index a70610929fed2..b1b9af88e0fa6 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -138,20 +138,12 @@ static ssize_t description_show(struct mdev_type *mtype,
type->conf->weight);
}
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", mtype->sysfs_name);
-}
-
static MDEV_TYPE_ATTR_RO(available_instances);
static MDEV_TYPE_ATTR_RO(description);
-static MDEV_TYPE_ATTR_RO(name);
static const struct attribute *gvt_type_attrs[] = {
&mdev_type_attr_available_instances.attr,
&mdev_type_attr_description.attr,
- &mdev_type_attr_name.attr,
NULL,
};
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 74ff2d9719d02..9cc7b68c72f38 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,13 +70,6 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
-}
-static MDEV_TYPE_ATTR_RO(name);
-
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -88,7 +81,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_name.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
@@ -642,6 +634,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
int vfio_ccw_mdev_reg(struct subchannel *sch)
{
sch->mdev_type.sysfs_name = "io";
+ sch->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
sch->mdev_types[0] = &sch->mdev_type;
return mdev_register_parent(&sch->parent, &sch->dev,
&vfio_ccw_mdev_driver, sch->mdev_types,
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 023b659c812c9..ed8d0c660e78b 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -511,14 +511,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
atomic_inc(&matrix_dev->available_instances);
}
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s\n", VFIO_AP_MDEV_NAME_HWVIRT);
-}
-
-static MDEV_TYPE_ATTR_RO(name);
-
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -530,7 +522,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *vfio_ap_mdev_type_attrs[] = {
- &mdev_type_attr_name.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 89637bc85462a..0f3d0bbf36f75 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -81,9 +81,19 @@ static ssize_t device_api_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(device_api);
+static ssize_t name_show(struct mdev_type *mtype,
+ struct mdev_type_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n",
+ mtype->pretty_name ? mtype->pretty_name : mtype->sysfs_name);
+}
+
+static MDEV_TYPE_ATTR_RO(name);
+
static struct attribute *mdev_types_core_attrs[] = {
&mdev_type_attr_create.attr,
&mdev_type_attr_device_api.attr,
+ &mdev_type_attr_name.attr,
NULL,
};
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 51a6f2ddcf9c6..5e6936bc7fa1b 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -26,6 +26,7 @@ struct mdev_device {
struct mdev_type {
/* set by the driver before calling mdev_register parent: */
const char *sysfs_name;
+ const char *pretty_name;
/* set by the core, can be used drivers */
struct mdev_parent *parent;
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 199846f01de92..c8271168a96ad 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -101,26 +101,25 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
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,
+ .type.pretty_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,
+ .type.pretty_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,
+ .type.pretty_name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
.mbytes = 64,
.max_x = 0,
.max_y = 0,
@@ -547,7 +546,7 @@ static int mbochs_probe(struct mdev_device *mdev)
goto err_mem;
dev_info(dev, "%s: %s, %d MB, %ld pages\n", __func__,
- type->name, type->mbytes, mdev_state->pagecount);
+ type->type.pretty_name, type->mbytes, mdev_state->pagecount);
mutex_init(&mdev_state->ops_lock);
mdev_state->mdev = mdev;
@@ -1334,16 +1333,6 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- struct mbochs_type *type =
- container_of(mtype, struct mbochs_type, type);
-
- return sprintf(buf, "%s\n", type->name);
-}
-static MDEV_TYPE_ATTR_RO(name);
-
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
@@ -1368,7 +1357,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_name.attr,
&mdev_type_attr_description.attr,
&mdev_type_attr_available_instances.attr,
NULL,
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index b8d6eeff2033d..6091c642ee102 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -53,7 +53,6 @@ MODULE_PARM_DESC(count, "number of " MDPY_NAME " devices");
static struct mdpy_type {
struct mdev_type type;
- const char *name;
u32 format;
u32 bytepp;
u32 width;
@@ -61,21 +60,21 @@ static struct mdpy_type {
} mdpy_types[] = {
{
.type.sysfs_name = MDPY_TYPE_1,
- .name = MDPY_CLASS_NAME "-" MDPY_TYPE_1,
+ .type.pretty_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,
+ .type.pretty_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,
+ .type.pretty_name = MDPY_CLASS_NAME "-" MDPY_TYPE_3,
.format = DRM_FORMAT_XRGB8888,
.bytepp = 4,
.width = 1920,
@@ -256,8 +255,8 @@ static int mdpy_probe(struct mdev_device *mdev)
ret = -ENOMEM;
goto err_vconfig;
}
- dev_info(dev, "%s: %s (%dx%d)\n", __func__, type->name, type->width,
- type->height);
+ dev_info(dev, "%s: %s (%dx%d)\n", __func__, type->type.pretty_name,
+ type->width, type->height);
mutex_init(&mdev_state->ops_lock);
mdev_state->mdev = mdev;
@@ -651,15 +650,6 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
-
- return sprintf(buf, "%s\n", type->name);
-}
-static MDEV_TYPE_ATTR_RO(name);
-
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
@@ -679,7 +669,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_name.attr,
&mdev_type_attr_description.attr,
&mdev_type_attr_available_instances.attr,
NULL,
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 2a470424628af..b95a4491265c5 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -146,10 +146,11 @@ struct mdev_state {
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" },
+ { .nr_ports = 1, .type.sysfs_name = "1",
+ .type.pretty_name = "Single port serial" },
+ { .nr_ports = 2, .type.sysfs_name = "2",
+ .type.pretty_name = "Dual port serial" },
};
static struct mdev_type *mtty_mdev_types[] = {
@@ -1246,16 +1247,6 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t name_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
-{
- struct mtty_type *type = container_of(mtype, struct mtty_type, type);
-
- return sysfs_emit(buf, "%s\n", type->name);
-}
-
-static MDEV_TYPE_ATTR_RO(name);
-
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -1269,7 +1260,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_name.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 12/14] vfio/mdev: consolidate all the available_instance sysfs into the core code
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (10 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 11/14] vfio/mdev: consolidate all the name " Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 13/14] vfio/mdev: consolidate all the description " Christoph Hellwig
2022-07-04 12:51 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Every driver just print a number, simply add a method to the mdev_driver
to return it and provide a standard sysfs show function.
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>
---
.../driver-api/vfio-mediated-device.rst | 3 +-
drivers/gpu/drm/i915/gvt/gvt.h | 1 -
drivers/gpu/drm/i915/gvt/kvmgt.c | 34 +++++++++------
drivers/gpu/drm/i915/gvt/vgpu.c | 41 ++-----------------
drivers/s390/cio/vfio_ccw_ops.c | 14 ++-----
drivers/s390/crypto/vfio_ap_ops.c | 16 ++------
drivers/vfio/mdev/mdev_sysfs.c | 11 +++++
include/linux/mdev.h | 2 +
samples/vfio-mdev/mbochs.c | 10 ++---
samples/vfio-mdev/mdpy.c | 9 ++--
samples/vfio-mdev/mtty.c | 16 ++------
11 files changed, 55 insertions(+), 102 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 334e649360353..1e19ba588a34f 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
+ unsigned int (*get_available)(struct mdev_type *mtype);
const struct attribute * const *types_attrs;
struct device_driver driver;
};
@@ -209,7 +210,7 @@ Directories and files under the sysfs for Each Physical Device
* available_instances
- This attribute should show the number of devices of type <type-id> that can be
+ This attribute shows the number of devices of type <type-id> that can be
created.
* [device]
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index f9690dca0a857..994ec48526126 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -315,7 +315,6 @@ struct intel_vgpu_type {
struct mdev_type type;
char name[16];
const struct intel_vgpu_config *conf;
- unsigned int avail_instance;
};
struct intel_gvt {
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index b1b9af88e0fa6..b523daf048e1f 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -113,16 +113,6 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
struct kvm_memory_slot *slot,
struct kvm_page_track_notifier_node *node);
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
-{
- struct intel_vgpu_type *type =
- container_of(mtype, struct intel_vgpu_type, type);
-
- return sprintf(buf, "%u\n", type->avail_instance);
-}
-
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
@@ -138,11 +128,9 @@ static ssize_t description_show(struct mdev_type *mtype,
type->conf->weight);
}
-static MDEV_TYPE_ATTR_RO(available_instances);
static MDEV_TYPE_ATTR_RO(description);
static const struct attribute *gvt_type_attrs[] = {
- &mdev_type_attr_available_instances.attr,
&mdev_type_attr_description.attr,
NULL,
};
@@ -1570,6 +1558,27 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
intel_gvt_destroy_vgpu(vgpu);
}
+static unsigned int intel_vgpu_get_available(struct mdev_type *mtype)
+{
+ struct intel_vgpu_type *type =
+ container_of(mtype, struct intel_vgpu_type, type);
+ struct intel_gvt *gvt = kdev_to_i915(mtype->parent->dev)->gvt;
+ unsigned int low_gm_avail, high_gm_avail, fence_avail;
+
+ mutex_lock(&gvt->lock);
+ low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE -
+ gvt->gm.vgpu_allocated_low_gm_size;
+ high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE -
+ gvt->gm.vgpu_allocated_high_gm_size;
+ fence_avail = gvt_fence_sz(gvt) - HOST_FENCE -
+ gvt->fence.vgpu_allocated_fence_num;
+ mutex_unlock(&gvt->lock);
+
+ return min3(low_gm_avail / type->conf->low_mm,
+ high_gm_avail / type->conf->high_mm,
+ fence_avail / type->conf->fence);
+}
+
static struct mdev_driver intel_vgpu_mdev_driver = {
.device_api = VFIO_DEVICE_API_PCI_STRING,
.driver = {
@@ -1579,6 +1588,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
},
.probe = intel_vgpu_probe,
.remove = intel_vgpu_remove,
+ .get_available = intel_vgpu_get_available,
.types_attrs = gvt_type_attrs,
};
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index ff240503d4125..0723bbee7176f 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -129,11 +129,11 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
sprintf(gvt->types[i].name, "GVTg_V%u_%s",
GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
gvt->types->conf = conf;
- gvt->types[i].avail_instance = min(low_avail / conf->low_mm,
- high_avail / conf->high_mm);
gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
- i, gvt->types[i].name, gvt->types[i].avail_instance,
+ i, gvt->types[i].name,
+ min(low_avail / conf->low_mm,
+ high_avail / conf->high_mm),
conf->low_mm, conf->high_mm, conf->fence,
conf->weight, vgpu_edid_str(conf->edid));
@@ -157,36 +157,6 @@ void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
kfree(gvt->types);
}
-static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
-{
- int i;
- unsigned int low_gm_avail, high_gm_avail, fence_avail;
- unsigned int low_gm_min, high_gm_min, fence_min;
-
- /* Need to depend on maxium hw resource size but keep on
- * static config for now.
- */
- low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE -
- gvt->gm.vgpu_allocated_low_gm_size;
- high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE -
- gvt->gm.vgpu_allocated_high_gm_size;
- fence_avail = gvt_fence_sz(gvt) - HOST_FENCE -
- gvt->fence.vgpu_allocated_fence_num;
-
- for (i = 0; i < gvt->num_types; i++) {
- low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm;
- high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm;
- fence_min = fence_avail / gvt->types[i].conf->fence;
- gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min),
- fence_min);
-
- gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
- i, gvt->types[i].name,
- gvt->types[i].avail_instance, gvt->types[i].conf->low_mm,
- gvt->types[i].conf->high_mm, gvt->types[i].conf->fence);
- }
-}
-
/**
* intel_gvt_active_vgpu - activate a virtual GPU
* @vgpu: virtual GPU
@@ -282,10 +252,6 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
intel_vgpu_dmabuf_cleanup(vgpu);
mutex_unlock(&vgpu->vgpu_lock);
- mutex_lock(&gvt->lock);
- intel_gvt_update_vgpu_types(gvt);
- mutex_unlock(&gvt->lock);
-
vfree(vgpu);
}
@@ -431,7 +397,6 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret)
goto out_clean_sched_policy;
- intel_gvt_update_vgpu_types(gvt);
intel_gvt_update_reg_whitelist(vgpu);
mutex_unlock(&gvt->lock);
return vgpu;
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 9cc7b68c72f38..6f6a0f2695059 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,20 +70,12 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
+static unsigned int vfio_ccw_get_available(struct mdev_type *mtype)
{
struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
- return sprintf(buf, "%d\n", atomic_read(&private->avail));
+ return atomic_read(&private->avail);
}
-static MDEV_TYPE_ATTR_RO(available_instances);
-
-static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_available_instances.attr,
- NULL,
-};
static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
{
@@ -628,7 +620,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
- .types_attrs = mdev_types_attrs,
+ .get_available = vfio_ccw_get_available,
};
int vfio_ccw_mdev_reg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index ed8d0c660e78b..edeec11c56560 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -511,21 +511,11 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
atomic_inc(&matrix_dev->available_instances);
}
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
+static unsigned int vfio_ap_mdev_get_available(struct mdev_type *mtype)
{
- return sprintf(buf, "%d\n",
- atomic_read(&matrix_dev->available_instances));
+ return atomic_read(&matrix_dev->available_instances);
}
-static MDEV_TYPE_ATTR_RO(available_instances);
-
-static const struct attribute *vfio_ap_mdev_type_attrs[] = {
- &mdev_type_attr_available_instances.attr,
- NULL,
-};
-
struct vfio_ap_queue_reserved {
unsigned long *apid;
unsigned long *apqi;
@@ -1445,7 +1435,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
},
.probe = vfio_ap_mdev_probe,
.remove = vfio_ap_mdev_remove,
- .types_attrs = vfio_ap_mdev_type_attrs,
+ .get_available = vfio_ap_mdev_get_available,
};
int vfio_ap_mdev_register(void)
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 0f3d0bbf36f75..9238d92738d5b 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -90,10 +90,21 @@ static ssize_t name_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(name);
+static ssize_t available_instances_show(struct mdev_type *mtype,
+ struct mdev_type_attribute *attr,
+ char *buf)
+{
+ struct mdev_driver *drv = mtype->parent->mdev_driver;
+
+ return sysfs_emit(buf, "%u\n", drv->get_available(mtype));
+}
+static MDEV_TYPE_ATTR_RO(available_instances);
+
static struct attribute *mdev_types_core_attrs[] = {
&mdev_type_attr_create.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_name.attr,
+ &mdev_type_attr_available_instances.attr,
NULL,
};
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 5e6936bc7fa1b..68b4a132b1523 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -72,6 +72,7 @@ struct mdev_type_attribute {
* @device_api: string to return for the device_api sysfs
* @probe: called when new device created
* @remove: called when device removed
+ * @get_available: Return the max number of instances that can be created
* @types_attrs: attributes to the type kobjects.
* @driver: device driver structure
**/
@@ -79,6 +80,7 @@ struct mdev_driver {
const char *device_api;
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
+ unsigned int (*get_available)(struct mdev_type *mtype);
const struct attribute * const *types_attrs;
struct device_driver driver;
};
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index c8271168a96ad..e61be7f8a9863 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1344,21 +1344,16 @@ static ssize_t description_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(description);
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
+static unsigned int mbochs_get_available(struct mdev_type *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);
+ return atomic_read(&mbochs_avail_mbytes) / type->mbytes;
}
-static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_description.attr,
- &mdev_type_attr_available_instances.attr,
NULL,
};
@@ -1380,6 +1375,7 @@ static struct mdev_driver mbochs_driver = {
},
.probe = mbochs_probe,
.remove = mbochs_remove,
+ .get_available = mbochs_get_available,
.types_attrs = mdev_types_attrs,
};
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 6091c642ee102..2f59078909c9d 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -660,17 +660,13 @@ static ssize_t description_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(description);
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
+static unsigned int mdpy_get_available(struct mdev_type *mtype)
{
- return sprintf(buf, "%d\n", max_devices - mdpy_count);
+ return max_devices - mdpy_count;
}
-static MDEV_TYPE_ATTR_RO(available_instances);
static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_description.attr,
- &mdev_type_attr_available_instances.attr,
NULL,
};
@@ -691,6 +687,7 @@ static struct mdev_driver mdpy_driver = {
},
.probe = mdpy_probe,
.remove = mdpy_remove,
+ .get_available = mdpy_get_available,
.types_attrs = mdev_types_attrs,
};
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index b95a4491265c5..f6e8ec8240066 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -1247,23 +1247,13 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t available_instances_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr,
- char *buf)
+static unsigned int mtty_get_available(struct mdev_type *mtype)
{
struct mtty_type *type = container_of(mtype, struct mtty_type, type);
- return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) /
- type->nr_ports);
+ return atomic_read(&mdev_avail_ports) / type->nr_ports;
}
-static MDEV_TYPE_ATTR_RO(available_instances);
-
-static const struct attribute *mdev_types_attrs[] = {
- &mdev_type_attr_available_instances.attr,
- NULL,
-};
-
static const struct vfio_device_ops mtty_dev_ops = {
.name = "vfio-mtty",
.read = mtty_read,
@@ -1281,7 +1271,7 @@ static struct mdev_driver mtty_driver = {
},
.probe = mtty_probe,
.remove = mtty_remove,
- .types_attrs = mdev_types_attrs,
+ .get_available = mtty_get_available,
};
static void mtty_device_release(struct device *dev)
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/14] vfio/mdev: consolidate all the description sysfs into the core code
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (11 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 12/14] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 12:51 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
13 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
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>
---
.../driver-api/vfio-mediated-device.rst | 4 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 18 +++------
drivers/vfio/mdev/mdev_driver.c | 2 +-
drivers/vfio/mdev/mdev_sysfs.c | 40 +++++++++++++++----
include/linux/mdev.h | 19 +--------
samples/vfio-mdev/mbochs.c | 11 +----
samples/vfio-mdev/mdpy.c | 11 +----
7 files changed, 46 insertions(+), 59 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 1e19ba588a34f..4f1b9ec6e0ccb 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -106,7 +106,7 @@ structure to represent a mediated device's driver::
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
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;
};
@@ -224,7 +224,7 @@ Directories and files under the sysfs for Each Physical Device
* 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.
Directories and Files Under the sysfs for Each mdev Device
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index b523daf048e1f..992a34ec51960 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -113,8 +113,7 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
struct kvm_memory_slot *slot,
struct kvm_page_track_notifier_node *node);
-static ssize_t description_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
+static ssize_t intel_vgpu_show_description(struct mdev_type *mtype, char *buf)
{
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);
}
-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,
unsigned long size)
{
@@ -1586,10 +1578,10 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
.owner = THIS_MODULE,
.dev_groups = intel_vgpu_groups,
},
- .probe = intel_vgpu_probe,
- .remove = intel_vgpu_remove,
- .get_available = intel_vgpu_get_available,
- .types_attrs = gvt_type_attrs,
+ .probe = intel_vgpu_probe,
+ .remove = intel_vgpu_remove,
+ .get_available = intel_vgpu_get_available,
+ .show_description = intel_vgpu_show_description,
};
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 60e8b9f6474e8..7825d83a55f8c 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -55,7 +55,7 @@ struct bus_type mdev_bus_type = {
**/
int mdev_register_driver(struct mdev_driver *drv)
{
- if (!drv->types_attrs || !drv->device_api)
+ if (!drv->device_api)
return -EINVAL;
/* initialize common driver fields */
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 9238d92738d5b..c5cd035d591d0 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -14,7 +14,19 @@
#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,
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 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[] = {
&mdev_type_attr_create.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_name.attr,
&mdev_type_attr_available_instances.attr,
+ &mdev_type_attr_description.attr,
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 = {
.attrs = mdev_types_core_attrs,
+ .is_visible = mdev_types_core_is_visible,
};
static const struct attribute_group *mdev_type_groups[] = {
@@ -156,13 +187,8 @@ static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
goto attr_devices_failed;
}
- ret = sysfs_create_files(&type->kobj, parent->mdev_driver->types_attrs);
- if (ret)
- goto attrs_failed;
return 0;
-attrs_failed:
- kobject_put(type->devices_kobj);
attr_devices_failed:
kobject_del(&type->kobj);
kobject_put(&type->kobj);
@@ -171,8 +197,6 @@ static int mdev_type_add(struct mdev_parent *parent, 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_del(&type->kobj);
kobject_put(&type->kobj);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 68b4a132b1523..dc38ad2b07883 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -52,28 +52,13 @@ static inline struct mdev_device *to_mdev_device(struct 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
* @device_api: string to return for the device_api sysfs
* @probe: called when new device created
* @remove: called when device removed
* @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
**/
struct mdev_driver {
@@ -81,7 +66,7 @@ struct mdev_driver {
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
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;
};
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index e61be7f8a9863..0f9b9cf46f05b 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1333,8 +1333,7 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t description_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
+static ssize_t mbochs_show_description(struct mdev_type *mtype, char *buf)
{
struct mbochs_type *type =
container_of(mtype, struct mbochs_type, type);
@@ -1342,7 +1341,6 @@ static ssize_t description_show(struct mdev_type *mtype,
return sprintf(buf, "virtual display, %d MB video memory\n",
type ? type->mbytes : 0);
}
-static MDEV_TYPE_ATTR_RO(description);
static unsigned int mbochs_get_available(struct mdev_type *mtype)
{
@@ -1352,11 +1350,6 @@ static unsigned int mbochs_get_available(struct mdev_type *mtype)
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 = {
.close_device = mbochs_close_device,
.read = mbochs_read,
@@ -1376,7 +1369,7 @@ static struct mdev_driver mbochs_driver = {
.probe = mbochs_probe,
.remove = mbochs_remove,
.get_available = mbochs_get_available,
- .types_attrs = mdev_types_attrs,
+ .show_description = mbochs_show_description,
};
static const struct file_operations vd_fops = {
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 2f59078909c9d..250b7ea2df2e4 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -650,26 +650,19 @@ static const struct attribute_group *mdev_dev_groups[] = {
NULL,
};
-static ssize_t description_show(struct mdev_type *mtype,
- struct mdev_type_attribute *attr, char *buf)
+static ssize_t mdpy_show_description(struct mdev_type *mtype, char *buf)
{
struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
return sprintf(buf, "virtual display, %dx%d framebuffer\n",
type->width, type->height);
}
-static MDEV_TYPE_ATTR_RO(description);
static unsigned int mdpy_get_available(struct mdev_type *mtype)
{
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 = {
.read = mdpy_read,
.write = mdpy_write,
@@ -688,7 +681,7 @@ static struct mdev_driver mdpy_driver = {
.probe = mdpy_probe,
.remove = mdpy_remove,
.get_available = mdpy_get_available,
- .types_attrs = mdev_types_attrs,
+ .show_description = mdpy_show_description,
};
static const struct file_operations vd_fops = {
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core
2022-07-04 12:51 simplify the mdev interface v4 Christoph Hellwig
` (12 preceding siblings ...)
2022-07-04 12:51 ` [PATCH 13/14] vfio/mdev: consolidate all the description " Christoph Hellwig
@ 2022-07-04 12:51 ` Christoph Hellwig
2022-07-04 15:07 ` Jason Gunthorpe
13 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-04 12:51 UTC (permalink / raw)
To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
Many of the mdev drivers use a simple counter for keeping track of the
available instances. Move this code to the core code and store the counter
in the mdev_parent. Implement it using correct locking, fixing mdpy.
Drivers just provide the value in the mdev_driver at registration time
and the core code takes care of maintaining it and exposing the value in
sysfs.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[count instances per-parent instead of per-type]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
drivers/s390/cio/vfio_ccw_drv.c | 1 -
drivers/s390/cio/vfio_ccw_ops.c | 14 +-------------
drivers/s390/cio/vfio_ccw_private.h | 2 --
drivers/s390/crypto/vfio_ap_ops.c | 21 +++------------------
drivers/s390/crypto/vfio_ap_private.h | 2 --
drivers/vfio/mdev/mdev_core.c | 12 ++++++++++++
include/linux/mdev.h | 3 +++
samples/vfio-mdev/mdpy.c | 23 ++++-------------------
8 files changed, 23 insertions(+), 55 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 750d0315f1f5b..449c76b29a3b5 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -149,7 +149,6 @@ static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
INIT_LIST_HEAD(&private->crw);
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
- atomic_set(&private->avail, 1);
private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
GFP_KERNEL);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 6f6a0f2695059..c05d80add7be2 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,13 +70,6 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static unsigned int vfio_ccw_get_available(struct mdev_type *mtype)
-{
- struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
-
- return atomic_read(&private->avail);
-}
-
static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
{
struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
@@ -85,9 +78,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
if (private->state == VFIO_CCW_STATE_NOT_OPER)
return -ENODEV;
- if (atomic_dec_if_positive(&private->avail) < 0)
- return -EPERM;
-
memset(&private->vdev, 0, sizeof(private->vdev));
vfio_init_group_dev(&private->vdev, &mdev->dev,
&vfio_ccw_dev_ops);
@@ -108,7 +98,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
err_atomic:
vfio_uninit_group_dev(&private->vdev);
- atomic_inc(&private->avail);
private->mdev = NULL;
private->state = VFIO_CCW_STATE_IDLE;
return ret;
@@ -135,7 +124,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
vfio_uninit_group_dev(&private->vdev);
cp_free(&private->cp);
private->mdev = NULL;
- atomic_inc(&private->avail);
}
static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
@@ -613,6 +601,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
struct mdev_driver vfio_ccw_mdev_driver = {
.device_api = VFIO_DEVICE_API_CCW_STRING,
+ .max_instances = 1,
.driver = {
.name = "vfio_ccw_mdev",
.owner = THIS_MODULE,
@@ -620,7 +609,6 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
- .get_available = vfio_ccw_get_available,
};
int vfio_ccw_mdev_reg(struct subchannel *sch)
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index b7163bac8cc75..9be5baed0cb7f 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -72,7 +72,6 @@ struct vfio_ccw_crw {
* @sch: pointer to the subchannel
* @state: internal state of the device
* @completion: synchronization helper of the I/O completion
- * @avail: available for creating a mediated device
* @mdev: pointer to the mediated device
* @nb: notifier for vfio events
* @io_region: MMIO region to input/output I/O arguments/results
@@ -96,7 +95,6 @@ struct vfio_ccw_private {
struct subchannel *sch;
int state;
struct completion *completion;
- atomic_t avail;
struct mdev_device *mdev;
struct notifier_block nb;
struct ccw_io_region *io_region;
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index edeec11c56560..69ed88fdaf383 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -461,14 +461,9 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
struct ap_matrix_mdev *matrix_mdev;
int ret;
- if ((atomic_dec_if_positive(&matrix_dev->available_instances) < 0))
- return -EPERM;
-
matrix_mdev = kzalloc(sizeof(*matrix_mdev), GFP_KERNEL);
- if (!matrix_mdev) {
- ret = -ENOMEM;
- goto err_dec_available;
- }
+ if (!matrix_mdev)
+ return -ENOMEM;
vfio_init_group_dev(&matrix_mdev->vdev, &mdev->dev,
&vfio_ap_matrix_dev_ops);
@@ -491,8 +486,6 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
mutex_unlock(&matrix_dev->lock);
vfio_uninit_group_dev(&matrix_mdev->vdev);
kfree(matrix_mdev);
-err_dec_available:
- atomic_inc(&matrix_dev->available_instances);
return ret;
}
@@ -508,12 +501,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
mutex_unlock(&matrix_dev->lock);
vfio_uninit_group_dev(&matrix_mdev->vdev);
kfree(matrix_mdev);
- atomic_inc(&matrix_dev->available_instances);
-}
-
-static unsigned int vfio_ap_mdev_get_available(struct mdev_type *mtype)
-{
- return atomic_read(&matrix_dev->available_instances);
}
struct vfio_ap_queue_reserved {
@@ -1427,6 +1414,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
static struct mdev_driver vfio_ap_matrix_driver = {
.device_api = VFIO_DEVICE_API_AP_STRING,
+ .max_instances = MAX_ZDEV_ENTRIES_EXT,
.driver = {
.name = "vfio_ap_mdev",
.owner = THIS_MODULE,
@@ -1435,15 +1423,12 @@ static struct mdev_driver vfio_ap_matrix_driver = {
},
.probe = vfio_ap_mdev_probe,
.remove = vfio_ap_mdev_remove,
- .get_available = vfio_ap_mdev_get_available,
};
int vfio_ap_mdev_register(void)
{
int ret;
- atomic_set(&matrix_dev->available_instances, MAX_ZDEV_ENTRIES_EXT);
-
ret = mdev_register_driver(&vfio_ap_matrix_driver);
if (ret)
return ret;
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 5dc5050d03791..b808b343b771f 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -28,7 +28,6 @@
* struct ap_matrix_dev - Contains the data for the matrix device.
*
* @device: generic device structure associated with the AP matrix device
- * @available_instances: number of mediated matrix devices that can be created
* @info: the struct containing the output from the PQAP(QCI) instruction
* @mdev_list: the list of mediated matrix devices created
* @lock: mutex for locking the AP matrix device. This lock will be
@@ -40,7 +39,6 @@
*/
struct ap_matrix_dev {
struct device device;
- atomic_t available_instances;
struct ap_config_info info;
struct list_head mdev_list;
struct mutex lock;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 93f8caf2e5f77..775efbfed1f35 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -70,6 +70,7 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
parent->mdev_driver = mdev_driver;
parent->types = types;
parent->nr_types = nr_types;
+ parent->available_instances = mdev_driver->max_instances;
if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
@@ -115,12 +116,15 @@ EXPORT_SYMBOL(mdev_unregister_parent);
static void mdev_device_release(struct device *dev)
{
struct mdev_device *mdev = to_mdev_device(dev);
+ struct mdev_parent *parent = mdev->type->parent;
/* Pairs with the get in mdev_device_create() */
kobject_put(&mdev->type->kobj);
mutex_lock(&mdev_list_lock);
list_del(&mdev->next);
+ if (!parent->mdev_driver->get_available)
+ parent->available_instances++;
mutex_unlock(&mdev_list_lock);
dev_dbg(&mdev->dev, "MDEV: destroying\n");
@@ -144,6 +148,14 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
}
}
+ if (!drv->get_available) {
+ if (!parent->available_instances) {
+ mutex_unlock(&mdev_list_lock);
+ return -EUSERS;
+ }
+ parent->available_instances--;
+ }
+
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev) {
mutex_unlock(&mdev_list_lock);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index dc38ad2b07883..641ed18a61247 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -45,6 +45,7 @@ struct mdev_parent {
struct rw_semaphore unreg_sem;
struct mdev_type **types;
unsigned int nr_types;
+ unsigned int available_instances;
};
static inline struct mdev_device *to_mdev_device(struct device *dev)
@@ -55,6 +56,7 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
/**
* struct mdev_driver - Mediated device driver
* @device_api: string to return for the device_api sysfs
+ * @max_instances: maximum number of instances supported (optional)
* @probe: called when new device created
* @remove: called when device removed
* @get_available: Return the max number of instances that can be created
@@ -63,6 +65,7 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
**/
struct mdev_driver {
const char *device_api;
+ unsigned int max_instances;
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
unsigned int (*get_available)(struct mdev_type *mtype);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 250b7ea2df2e4..7f7ac5491407e 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -42,11 +42,6 @@
MODULE_LICENSE("GPL v2");
-static int max_devices = 4;
-module_param_named(count, max_devices, int, 0444);
-MODULE_PARM_DESC(count, "number of " MDPY_NAME " devices");
-
-
#define MDPY_TYPE_1 "vga"
#define MDPY_TYPE_2 "xga"
#define MDPY_TYPE_3 "hd"
@@ -93,7 +88,6 @@ static struct class *mdpy_class;
static struct cdev mdpy_cdev;
static struct device mdpy_dev;
static struct mdev_parent mdpy_parent;
-static u32 mdpy_count;
static const struct vfio_device_ops mdpy_dev_ops;
/* State of each mdev device */
@@ -234,9 +228,6 @@ static int mdpy_probe(struct mdev_device *mdev)
u32 fbsize;
int ret;
- if (mdpy_count >= max_devices)
- return -ENOMEM;
-
mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL);
if (mdev_state == NULL)
return -ENOMEM;
@@ -265,8 +256,6 @@ static int mdpy_probe(struct mdev_device *mdev)
mdpy_create_config_space(mdev_state);
mdpy_reset(mdev_state);
- mdpy_count++;
-
ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev);
if (ret)
goto err_mem;
@@ -293,8 +282,6 @@ static void mdpy_remove(struct mdev_device *mdev)
kfree(mdev_state->vconfig);
vfio_uninit_group_dev(&mdev_state->vdev);
kfree(mdev_state);
-
- mdpy_count--;
}
static ssize_t mdpy_read(struct vfio_device *vdev, char __user *buf,
@@ -658,11 +645,6 @@ static ssize_t mdpy_show_description(struct mdev_type *mtype, char *buf)
type->width, type->height);
}
-static unsigned int mdpy_get_available(struct mdev_type *mtype)
-{
- return max_devices - mdpy_count;
-}
-
static const struct vfio_device_ops mdpy_dev_ops = {
.read = mdpy_read,
.write = mdpy_write,
@@ -672,6 +654,7 @@ static const struct vfio_device_ops mdpy_dev_ops = {
static struct mdev_driver mdpy_driver = {
.device_api = VFIO_DEVICE_API_PCI_STRING,
+ .max_instances = 4,
.driver = {
.name = "mdpy",
.owner = THIS_MODULE,
@@ -680,7 +663,6 @@ static struct mdev_driver mdpy_driver = {
},
.probe = mdpy_probe,
.remove = mdpy_remove,
- .get_available = mdpy_get_available,
.show_description = mdpy_show_description,
};
@@ -757,5 +739,8 @@ static void __exit mdpy_dev_exit(void)
mdpy_class = NULL;
}
+module_param_named(count, mdpy_driver.max_instances, int, 0444);
+MODULE_PARM_DESC(count, "number of " MDPY_NAME " devices");
+
module_init(mdpy_dev_init)
module_exit(mdpy_dev_exit)
--
2.30.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core
2022-07-04 12:51 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
@ 2022-07-04 15:07 ` Jason Gunthorpe
2022-07-05 8:05 ` Christoph Hellwig
0 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2022-07-04 15:07 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, Jul 04, 2022 at 02:51:44PM +0200, Christoph Hellwig wrote:
> @@ -115,12 +116,15 @@ EXPORT_SYMBOL(mdev_unregister_parent);
> static void mdev_device_release(struct device *dev)
> {
> struct mdev_device *mdev = to_mdev_device(dev);
> + struct mdev_parent *parent = mdev->type->parent;
>
> /* Pairs with the get in mdev_device_create() */
> kobject_put(&mdev->type->kobj);
>
> mutex_lock(&mdev_list_lock);
> list_del(&mdev->next);
> + if (!parent->mdev_driver->get_available)
> + parent->available_instances++;
> mutex_unlock(&mdev_list_lock);
I think the kobject_put() needs to be after this reference to parent
because mdev_type_release() will:
put_device(type->parent->dev);
Which is potentially the last reference holding dev, and thus parent,
at this moment.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core
2022-07-04 15:07 ` Jason Gunthorpe
@ 2022-07-05 8:05 ` Christoph Hellwig
0 siblings, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2022-07-05 8:05 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, Jul 04, 2022 at 12:07:36PM -0300, Jason Gunthorpe wrote:
> I think the kobject_put() needs to be after this reference to parent
> because mdev_type_release() will:
>
> put_device(type->parent->dev);
>
> Which is potentially the last reference holding dev, and thus parent,
> at this moment.
Yes, I've moved it.
^ permalink raw reply [flat|nested] 27+ messages in thread