* [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
@ 2022-08-22 6:21 ` Christoph Hellwig
2022-08-22 6:21 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
` (12 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:21 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.
Fixes: c90d097ae144 ("drm/i915/gvt: define weight according to vGPU type")
Reported-by: Kevin Tian <kevin.tian@intel.com>
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: 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] 33+ messages in thread
* [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
2022-08-22 6:21 ` [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types Christoph Hellwig
@ 2022-08-22 6:21 ` Christoph Hellwig
2022-08-22 6:21 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
` (11 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:21 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>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
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 705689e640119..f848c0386d8b9 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -294,15 +294,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 {
@@ -436,19 +447,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,
@@ -495,7 +495,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 e3cd589464777..91ba675a2fb8c 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,
@@ -1568,7 +1568,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] 33+ messages in thread
* [PATCH 03/14] vfio/mdev: make mdev.h standalone includable
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
2022-08-22 6:21 ` [PATCH 01/14] drm/i915/gvt: fix a memory leak in intel_gvt_init_vgpu_types Christoph Hellwig
2022-08-22 6:21 ` [PATCH 02/14] drm/i915/gvt: simplify vgpu configuration management Christoph Hellwig
@ 2022-08-22 6:21 ` Christoph Hellwig
2022-08-23 15:15 ` Anthony Krowiak
2022-08-23 18:02 ` Eric Farman
2022-08-22 6:21 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
` (10 subsequent siblings)
13 siblings, 2 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:21 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 | 1 -
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(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 91ba675a2fb8c..92bb9e7548b12 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 86d9e428357b0..e9985c63dc6bf 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/device.h>
#include <linux/slab.h>
#include <linux/mdev.h>
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index d782cf463eaba..163eeaaf24cee 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 47ad3b104d9e7..a5d8ae6132a20 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] 33+ messages in thread
* Re: [PATCH 03/14] vfio/mdev: make mdev.h standalone includable
2022-08-22 6:21 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
@ 2022-08-23 15:15 ` Anthony Krowiak
2022-08-23 18:02 ` Eric Farman
1 sibling, 0 replies; 33+ messages in thread
From: Anthony Krowiak @ 2022-08-23 15:15 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, 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
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
On 8/22/22 2:21 AM, Christoph Hellwig wrote:
> 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 | 1 -
> 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(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 91ba675a2fb8c..92bb9e7548b12 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 86d9e428357b0..e9985c63dc6bf 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
> @@ -12,7 +12,6 @@
>
> #include <linux/module.h>
> #include <linux/init.h>
> -#include <linux/device.h>
> #include <linux/slab.h>
> #include <linux/mdev.h>
>
> diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
> index d782cf463eaba..163eeaaf24cee 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 47ad3b104d9e7..a5d8ae6132a20 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>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 03/14] vfio/mdev: make mdev.h standalone includable
2022-08-22 6:21 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
2022-08-23 15:15 ` Anthony Krowiak
@ 2022-08-23 18:02 ` Eric Farman
1 sibling, 0 replies; 33+ messages in thread
From: Eric Farman @ 2022-08-23 18:02 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, 2022-08-22 at 08:21 +0200, Christoph Hellwig wrote:
> 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>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
> ---
> drivers/gpu/drm/i915/gvt/kvmgt.c | 2 --
> drivers/s390/cio/vfio_ccw_drv.c | 1 -
> 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(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c
> b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 91ba675a2fb8c..92bb9e7548b12 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 86d9e428357b0..e9985c63dc6bf 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
> @@ -12,7 +12,6 @@
>
> #include <linux/module.h>
> #include <linux/init.h>
> -#include <linux/device.h>
> #include <linux/slab.h>
> #include <linux/mdev.h>
>
> diff --git a/drivers/s390/crypto/vfio_ap_private.h
> b/drivers/s390/crypto/vfio_ap_private.h
> index d782cf463eaba..163eeaaf24cee 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 47ad3b104d9e7..a5d8ae6132a20 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>
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (2 preceding siblings ...)
2022-08-22 6:21 ` [PATCH 03/14] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
@ 2022-08-22 6:21 ` Christoph Hellwig
2022-08-23 15:47 ` Anthony Krowiak
2022-08-23 18:06 ` Eric Farman
2022-08-22 6:21 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
` (9 subsequent siblings)
13 siblings, 2 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:21 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: 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 | 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 | 1 +
drivers/s390/cio/vfio_ccw_drv.c | 5 +-
drivers/s390/cio/vfio_ccw_ops.c | 1 -
drivers/s390/cio/vfio_ccw_private.h | 2 +
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 +-
18 files changed, 70 insertions(+), 146 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index f47dca6645aae..cd1667608ab5d 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -58,19 +58,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
@@ -125,8 +125,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
@@ -134,7 +134,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 61a0a3c6c7b4b..00f4a04f6d4c6 100644
--- a/Documentation/s390/vfio-ap.rst
+++ b/Documentation/s390/vfio-ap.rst
@@ -297,7 +297,7 @@ of the VFIO AP mediated 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 f848c0386d8b9..6b0929f89d3b5 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"
@@ -337,6 +338,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 92bb9e7548b12..45c588c0a96a7 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1902,7 +1902,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);
@@ -2007,7 +2007,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..2ad8833653e99 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>
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index e9985c63dc6bf..7d105915bd149 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -221,7 +221,8 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
dev_set_drvdata(&sch->dev, private);
- ret = mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
+ ret = mdev_register_parent(&private->parent, &sch->dev,
+ &vfio_ccw_mdev_driver);
if (ret)
goto out_free;
@@ -240,7 +241,7 @@ static void vfio_ccw_sch_remove(struct subchannel *sch)
{
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
- mdev_unregister_device(&sch->dev);
+ mdev_unregister_parent(&private->parent);
dev_set_drvdata(&sch->dev, NULL);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 4a806a2273b54..c57ca085bd6bb 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>
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index cd24b7fada91c..cf9d159ebf7d9 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -113,6 +113,8 @@ struct vfio_ccw_private {
struct eventfd_ctx *req_trigger;
struct work_struct io_work;
struct work_struct crw_work;
+
+ struct mdev_parent parent;
} __aligned(8);
int vfio_ccw_sch_quiesce(struct subchannel *sch);
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 6c8c41fac4e14..929510633af80 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1822,7 +1822,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;
@@ -1834,7 +1835,7 @@ 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 163eeaaf24cee..35165730f5174 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -52,6 +52,7 @@ struct ap_matrix_dev {
struct mutex mdevs_lock; /* serializes access to each ap_matrix_mdev */
struct ap_driver *vfio_ap_drv;
struct mutex guests_lock; /* serializes access to each KVM guest */
+ 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 a5d8ae6132a20..262512c2a8ffc 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);
@@ -70,8 +80,9 @@ struct mdev_driver {
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] 33+ messages in thread
* Re: [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure
2022-08-22 6:21 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-08-23 15:47 ` Anthony Krowiak
2022-08-23 18:06 ` Eric Farman
1 sibling, 0 replies; 33+ messages in thread
From: Anthony Krowiak @ 2022-08-23 15:47 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, 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
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
On 8/22/22 2:21 AM, 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: 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 | 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 | 1 +
> drivers/s390/cio/vfio_ccw_drv.c | 5 +-
> drivers/s390/cio/vfio_ccw_ops.c | 1 -
> drivers/s390/cio/vfio_ccw_private.h | 2 +
> 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 +-
> 18 files changed, 70 insertions(+), 146 deletions(-)
>
> diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
> index f47dca6645aae..cd1667608ab5d 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -58,19 +58,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
> @@ -125,8 +125,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
> @@ -134,7 +134,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 61a0a3c6c7b4b..00f4a04f6d4c6 100644
> --- a/Documentation/s390/vfio-ap.rst
> +++ b/Documentation/s390/vfio-ap.rst
> @@ -297,7 +297,7 @@ of the VFIO AP mediated 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 f848c0386d8b9..6b0929f89d3b5 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"
> @@ -337,6 +338,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 92bb9e7548b12..45c588c0a96a7 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -1902,7 +1902,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);
> @@ -2007,7 +2007,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..2ad8833653e99 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>
> diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
> index e9985c63dc6bf..7d105915bd149 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
> @@ -221,7 +221,8 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
>
> dev_set_drvdata(&sch->dev, private);
>
> - ret = mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
> + ret = mdev_register_parent(&private->parent, &sch->dev,
> + &vfio_ccw_mdev_driver);
> if (ret)
> goto out_free;
>
> @@ -240,7 +241,7 @@ static void vfio_ccw_sch_remove(struct subchannel *sch)
> {
> struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
>
> - mdev_unregister_device(&sch->dev);
> + mdev_unregister_parent(&private->parent);
>
> dev_set_drvdata(&sch->dev, NULL);
>
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index 4a806a2273b54..c57ca085bd6bb 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>
>
> diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
> index cd24b7fada91c..cf9d159ebf7d9 100644
> --- a/drivers/s390/cio/vfio_ccw_private.h
> +++ b/drivers/s390/cio/vfio_ccw_private.h
> @@ -113,6 +113,8 @@ struct vfio_ccw_private {
> struct eventfd_ctx *req_trigger;
> struct work_struct io_work;
> struct work_struct crw_work;
> +
> + struct mdev_parent parent;
> } __aligned(8);
>
> int vfio_ccw_sch_quiesce(struct subchannel *sch);
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 6c8c41fac4e14..929510633af80 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -1822,7 +1822,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;
> @@ -1834,7 +1835,7 @@ 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 163eeaaf24cee..35165730f5174 100644
> --- a/drivers/s390/crypto/vfio_ap_private.h
> +++ b/drivers/s390/crypto/vfio_ap_private.h
> @@ -52,6 +52,7 @@ struct ap_matrix_dev {
> struct mutex mdevs_lock; /* serializes access to each ap_matrix_mdev */
> struct ap_driver *vfio_ap_drv;
> struct mutex guests_lock; /* serializes access to each KVM guest */
> + 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 a5d8ae6132a20..262512c2a8ffc 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);
> @@ -70,8 +80,9 @@ struct mdev_driver {
>
> 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);
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure
2022-08-22 6:21 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
2022-08-23 15:47 ` Anthony Krowiak
@ 2022-08-23 18:06 ` Eric Farman
1 sibling, 0 replies; 33+ messages in thread
From: Eric Farman @ 2022-08-23 18:06 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, 2022-08-22 at 08:21 +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: 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 | 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 | 1 +
> drivers/s390/cio/vfio_ccw_drv.c | 5 +-
> drivers/s390/cio/vfio_ccw_ops.c | 1 -
> drivers/s390/cio/vfio_ccw_private.h | 2 +
>
>
> ...snip...
>
> --- 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>
Since the mdev_type/mdev_parent stuff isn't in struct subchannel, this
should be in vfio_ccw_private.h instead.
Thanks,
Eric
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 05/14] vfio/mdev: simplify mdev_type handling
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (3 preceding siblings ...)
2022-08-22 6:21 ` [PATCH 04/14] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-08-22 6:21 ` Christoph Hellwig
2022-08-23 5:53 ` Zeng, Xin
2022-08-24 14:26 ` Anthony Krowiak
2022-08-22 6:22 ` [PATCH 06/14] vfio/mdev: remove mdev_from_dev Christoph Hellwig
` (8 subsequent siblings)
13 siblings, 2 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:21 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>
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.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/vfio_ccw_drv.c | 6 +-
drivers/s390/cio/vfio_ccw_ops.c | 14 +--
drivers/s390/cio/vfio_ccw_private.h | 2 +
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 ++++++------
17 files changed, 165 insertions(+), 323 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index cd1667608ab5d..ff7342d2e332d 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -103,7 +103,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
- struct attribute_group **supported_type_groups;
+ const struct attribute * const *types_attrs;
struct device_driver driver;
};
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 6b0929f89d3b5..00a2b2173a96f 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -310,8 +310,8 @@ struct intel_vgpu_config {
const char *name;
};
-#define NR_MAX_INTEL_VGPU_TYPES 20
struct intel_vgpu_type {
+ struct mdev_type type;
char name[16];
const struct intel_vgpu_config *conf;
unsigned int avail_instance;
@@ -339,6 +339,7 @@ struct intel_gvt {
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
struct mdev_parent parent;
+ struct mdev_type **mdev_types;
struct intel_vgpu_type *types;
unsigned int num_types;
struct intel_vgpu *idle_vgpu;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 45c588c0a96a7..2dc7615bb4f7f 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)
{
@@ -1558,14 +1495,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));
@@ -1604,7 +1538,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)
@@ -1903,7 +1837,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);
@@ -2003,20 +1936,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/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 7d105915bd149..25a5de08b3902 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -202,7 +202,6 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private)
mutex_destroy(&private->io_mutex);
kfree(private);
}
-
static int vfio_ccw_sch_probe(struct subchannel *sch)
{
struct pmcw *pmcw = &sch->schib.pmcw;
@@ -221,8 +220,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
dev_set_drvdata(&sch->dev, private);
+ private->mdev_type.sysfs_name = "io";
+ private->mdev_types[0] = &private->mdev_type;
ret = mdev_register_parent(&private->parent, &sch->dev,
- &vfio_ccw_mdev_driver);
+ &vfio_ccw_mdev_driver,
+ private->mdev_types, 1);
if (ret)
goto out_free;
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index c57ca085bd6bb..4136e1c100c8a 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -69,23 +69,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
}
static MDEV_TYPE_ATTR_RO(available_instances);
-static struct attribute *mdev_types_attrs[] = {
+static const struct attribute *mdev_types_attrs[] = {
&mdev_type_attr_name.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
-static struct attribute_group mdev_type_group = {
- .name = "io",
- .attrs = mdev_types_attrs,
-};
-
-static struct attribute_group *mdev_type_groups[] = {
- &mdev_type_group,
- NULL,
-};
-
static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
{
struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
@@ -608,5 +598,5 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
- .supported_type_groups = mdev_type_groups,
+ .types_attrs = mdev_types_attrs,
};
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index cf9d159ebf7d9..7abe5a798e002 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -115,6 +115,8 @@ struct vfio_ccw_private {
struct work_struct crw_work;
struct mdev_parent parent;
+ struct mdev_type mdev_type;
+ struct mdev_type *mdev_types[1];
} __aligned(8);
int vfio_ccw_sch_quiesce(struct subchannel *sch);
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 929510633af80..e74f34589329d 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -810,23 +810,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
static MDEV_TYPE_ATTR_RO(device_api);
-static struct attribute *vfio_ap_mdev_type_attrs[] = {
+static const struct attribute *vfio_ap_mdev_type_attrs[] = {
&mdev_type_attr_name.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_available_instances.attr,
NULL,
};
-static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
- .name = VFIO_AP_MDEV_TYPE_HWVIRT,
- .attrs = vfio_ap_mdev_type_attrs,
-};
-
-static struct attribute_group *vfio_ap_mdev_type_groups[] = {
- &vfio_ap_mdev_hwvirt_type_group,
- NULL,
-};
-
#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
"already assigned to %s"
@@ -1809,7 +1799,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)
@@ -1822,8 +1812,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 35165730f5174..441dc8dda380b 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -53,6 +53,8 @@ struct ap_matrix_dev {
struct ap_driver *vfio_ap_drv;
struct mutex guests_lock; /* serializes access to each KVM guest */
struct mdev_parent parent;
+ struct mdev_type mdev_type;
+ struct mdev_type *mdev_types[];
};
extern struct ap_matrix_dev *matrix_dev;
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 262512c2a8ffc..19bc93c10e8c7 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,22 +77,21 @@ 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;
};
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] 33+ messages in thread
* RE: [PATCH 05/14] vfio/mdev: simplify mdev_type handling
2022-08-22 6:21 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
@ 2022-08-23 5:53 ` Zeng, Xin
2022-08-23 18:07 ` Eric Farman
2022-08-24 14:26 ` Anthony Krowiak
1 sibling, 1 reply; 33+ messages in thread
From: Zeng, Xin @ 2022-08-23 5:53 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Wang,
Zhi A, Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Tian, Kevin
On Monday, August 22, 2022 2:22 PM, Christoph Hellwig <hch@lst.de> wrote:
> /*
> * 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;
This would potentially introduce a bug. Types is passed from the parent and memory reserved for it is
managed by the parent driver, while if you are doing so, it will be freed when types->kobj is released in
mdev module, i.e. in mdev_type_release, types will be freed as a chunk of memory in heap.
This will lead to unpredictable behavior and require a fix, either in here or in mdev_type_release.
Thanks,
Xin
> + parent->nr_types = nr_types;
>
> if (!mdev_bus_compat_class) {
> mdev_bus_compat_class =
> class_compat_register("mdev_bus");
> +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);
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 05/14] vfio/mdev: simplify mdev_type handling
2022-08-23 5:53 ` Zeng, Xin
@ 2022-08-23 18:07 ` Eric Farman
0 siblings, 0 replies; 33+ messages in thread
From: Eric Farman @ 2022-08-23 18:07 UTC (permalink / raw)
To: Zeng, Xin, Christoph Hellwig, Kirti Wankhede, Tony Krowiak,
Halil Pasic, Jason Herne, Matthew Rosato, Zhenyu Wang, Wang,
Zhi A, Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Tian, Kevin
On Tue, 2022-08-23 at 05:53 +0000, Zeng, Xin wrote:
> On Monday, August 22, 2022 2:22 PM, Christoph Hellwig <hch@lst.de>
> wrote:
>
> > /*
> > * 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;
>
> This would potentially introduce a bug. Types is passed from the
> parent and memory reserved for it is
> managed by the parent driver, while if you are doing so, it will be
> freed when types->kobj is released in
> mdev module, i.e. in mdev_type_release, types will be freed as a
> chunk of memory in heap.
> This will lead to unpredictable behavior and require a fix, either
> in here or in mdev_type_release.
I can confirm that this is still broken.
https://lore.kernel.org/r/65746aea193d4a814f895eca4b00b72cf29ac8f9.camel@linux.ibm.com/
Thanks,
Eric
>
> Thanks,
> Xin
>
> > + parent->nr_types = nr_types;
> >
> > if (!mdev_bus_compat_class) {
> > mdev_bus_compat_class =
> > class_compat_register("mdev_bus");
> > +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);
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 05/14] vfio/mdev: simplify mdev_type handling
2022-08-22 6:21 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
2022-08-23 5:53 ` Zeng, Xin
@ 2022-08-24 14:26 ` Anthony Krowiak
1 sibling, 0 replies; 33+ messages in thread
From: Anthony Krowiak @ 2022-08-24 14:26 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, 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
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
On 8/22/22 2:21 AM, Christoph Hellwig wrote:
> 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>
> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.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/vfio_ccw_drv.c | 6 +-
> drivers/s390/cio/vfio_ccw_ops.c | 14 +--
> drivers/s390/cio/vfio_ccw_private.h | 2 +
> 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 ++++++------
> 17 files changed, 165 insertions(+), 323 deletions(-)
>
> diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
> index cd1667608ab5d..ff7342d2e332d 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -103,7 +103,7 @@ structure to represent a mediated device's driver::
> struct mdev_driver {
> int (*probe) (struct mdev_device *dev);
> void (*remove) (struct mdev_device *dev);
> - struct attribute_group **supported_type_groups;
> + const struct attribute * const *types_attrs;
> struct device_driver driver;
> };
>
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> index 6b0929f89d3b5..00a2b2173a96f 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.h
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -310,8 +310,8 @@ struct intel_vgpu_config {
> const char *name;
> };
>
> -#define NR_MAX_INTEL_VGPU_TYPES 20
> struct intel_vgpu_type {
> + struct mdev_type type;
> char name[16];
> const struct intel_vgpu_config *conf;
> unsigned int avail_instance;
> @@ -339,6 +339,7 @@ struct intel_gvt {
> struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
> DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
> struct mdev_parent parent;
> + struct mdev_type **mdev_types;
> struct intel_vgpu_type *types;
> unsigned int num_types;
> struct intel_vgpu *idle_vgpu;
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 45c588c0a96a7..2dc7615bb4f7f 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)
> {
> @@ -1558,14 +1495,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));
> @@ -1604,7 +1538,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)
> @@ -1903,7 +1837,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);
>
> @@ -2003,20 +1936,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/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
> index 7d105915bd149..25a5de08b3902 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
> @@ -202,7 +202,6 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private)
> mutex_destroy(&private->io_mutex);
> kfree(private);
> }
> -
> static int vfio_ccw_sch_probe(struct subchannel *sch)
> {
> struct pmcw *pmcw = &sch->schib.pmcw;
> @@ -221,8 +220,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
>
> dev_set_drvdata(&sch->dev, private);
>
> + private->mdev_type.sysfs_name = "io";
> + private->mdev_types[0] = &private->mdev_type;
> ret = mdev_register_parent(&private->parent, &sch->dev,
> - &vfio_ccw_mdev_driver);
> + &vfio_ccw_mdev_driver,
> + private->mdev_types, 1);
> if (ret)
> goto out_free;
>
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index c57ca085bd6bb..4136e1c100c8a 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -69,23 +69,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
> }
> static MDEV_TYPE_ATTR_RO(available_instances);
>
> -static struct attribute *mdev_types_attrs[] = {
> +static const struct attribute *mdev_types_attrs[] = {
> &mdev_type_attr_name.attr,
> &mdev_type_attr_device_api.attr,
> &mdev_type_attr_available_instances.attr,
> NULL,
> };
>
> -static struct attribute_group mdev_type_group = {
> - .name = "io",
> - .attrs = mdev_types_attrs,
> -};
> -
> -static struct attribute_group *mdev_type_groups[] = {
> - &mdev_type_group,
> - NULL,
> -};
> -
> static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
> {
> struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
> @@ -608,5 +598,5 @@ struct mdev_driver vfio_ccw_mdev_driver = {
> },
> .probe = vfio_ccw_mdev_probe,
> .remove = vfio_ccw_mdev_remove,
> - .supported_type_groups = mdev_type_groups,
> + .types_attrs = mdev_types_attrs,
> };
> diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
> index cf9d159ebf7d9..7abe5a798e002 100644
> --- a/drivers/s390/cio/vfio_ccw_private.h
> +++ b/drivers/s390/cio/vfio_ccw_private.h
> @@ -115,6 +115,8 @@ struct vfio_ccw_private {
> struct work_struct crw_work;
>
> struct mdev_parent parent;
> + struct mdev_type mdev_type;
> + struct mdev_type *mdev_types[1];
> } __aligned(8);
>
> int vfio_ccw_sch_quiesce(struct subchannel *sch);
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 929510633af80..e74f34589329d 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -810,23 +810,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
>
> static MDEV_TYPE_ATTR_RO(device_api);
>
> -static struct attribute *vfio_ap_mdev_type_attrs[] = {
> +static const struct attribute *vfio_ap_mdev_type_attrs[] = {
> &mdev_type_attr_name.attr,
> &mdev_type_attr_device_api.attr,
> &mdev_type_attr_available_instances.attr,
> NULL,
> };
>
> -static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
> - .name = VFIO_AP_MDEV_TYPE_HWVIRT,
> - .attrs = vfio_ap_mdev_type_attrs,
> -};
> -
> -static struct attribute_group *vfio_ap_mdev_type_groups[] = {
> - &vfio_ap_mdev_hwvirt_type_group,
> - NULL,
> -};
> -
> #define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
> "already assigned to %s"
>
> @@ -1809,7 +1799,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)
> @@ -1822,8 +1812,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 35165730f5174..441dc8dda380b 100644
> --- a/drivers/s390/crypto/vfio_ap_private.h
> +++ b/drivers/s390/crypto/vfio_ap_private.h
> @@ -53,6 +53,8 @@ struct ap_matrix_dev {
> struct ap_driver *vfio_ap_drv;
> struct mutex guests_lock; /* serializes access to each KVM guest */
> struct mdev_parent parent;
> + struct mdev_type mdev_type;
> + struct mdev_type *mdev_types[];
> };
>
> extern struct ap_matrix_dev *matrix_dev;
> 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 262512c2a8ffc..19bc93c10e8c7 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,22 +77,21 @@ 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;
> };
>
> 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;
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 06/14] vfio/mdev: remove mdev_from_dev
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (4 preceding siblings ...)
2022-08-22 6:21 ` [PATCH 05/14] vfio/mdev: simplify mdev_type handling Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 07/14] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
` (7 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 19bc93c10e8c7..4f558de52fd94 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -102,9 +102,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] 33+ messages in thread
* [PATCH 07/14] vfio/mdev: unexport mdev_bus_type
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (5 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 06/14] vfio/mdev: remove mdev_from_dev Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 08/14] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
` (6 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 4f558de52fd94..6c179d2b89274 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -87,8 +87,6 @@ struct mdev_driver {
struct device_driver driver;
};
-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] 33+ messages in thread
* [PATCH 08/14] vfio/mdev: remove mdev_parent_dev
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (6 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 07/14] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
` (5 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 ff7342d2e332d..7b660f3fa2c92 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -200,9 +200,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 2dc7615bb4f7f..ef9d114349c3a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1493,7 +1493,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 6c179d2b89274..bbedffcb38d48 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -95,7 +95,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] 33+ messages in thread
* [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (7 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 08/14] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
` (4 subsequent siblings)
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 4136e1c100c8a..0ec0e310c91ea 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -62,8 +62,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 bbedffcb38d48..e445f809ceca3 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] 33+ messages in thread
* [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (8 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 09/14] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-23 15:59 ` Anthony Krowiak
2022-08-22 6:22 ` [PATCH 11/14] vfio/mdev: consolidate all the name " Christoph Hellwig
` (3 subsequent siblings)
13 siblings, 1 reply; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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
From: Jason Gunthorpe <jgg@nvidia.com>
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 7b660f3fa2c92..b0c29e37f61b4 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -202,7 +202,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 ef9d114349c3a..1ed99091165a4 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,
@@ -1531,6 +1523,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 0ec0e310c91ea..9ced2063720e6 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -51,13 +51,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)
@@ -70,7 +63,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,
};
@@ -590,6 +582,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 e74f34589329d..728a0ada4928f 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -802,17 +802,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,
};
@@ -1791,6 +1782,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 e445f809ceca3..af1ff0165b8d3 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] 33+ messages in thread
* Re: [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code
2022-08-22 6:22 ` [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
@ 2022-08-23 15:59 ` Anthony Krowiak
0 siblings, 0 replies; 33+ messages in thread
From: Anthony Krowiak @ 2022-08-23 15:59 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, 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
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
On 8/22/22 2:22 AM, Christoph Hellwig wrote:
> From: Jason Gunthorpe <jgg@nvidia.com>
>
> 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 7b660f3fa2c92..b0c29e37f61b4 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -202,7 +202,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 ef9d114349c3a..1ed99091165a4 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,
> @@ -1531,6 +1523,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 0ec0e310c91ea..9ced2063720e6 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -51,13 +51,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)
> @@ -70,7 +63,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,
> };
> @@ -590,6 +582,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 e74f34589329d..728a0ada4928f 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -802,17 +802,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,
> };
> @@ -1791,6 +1782,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 e445f809ceca3..af1ff0165b8d3 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,
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 11/14] vfio/mdev: consolidate all the name sysfs into the core code
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (9 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 10/14] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-23 16:23 ` Anthony Krowiak
2022-08-22 6:22 ` [PATCH 12/14] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
` (2 subsequent siblings)
13 siblings, 1 reply; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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_drv.c | 1 +
drivers/s390/cio/vfio_ccw_ops.c | 8 -------
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 ++++------------
10 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 b0c29e37f61b4..dcd1231a6fa84 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -217,7 +217,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 1ed99091165a4..e24e72527c9aa 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_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 25a5de08b3902..e5f21c725326b 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -221,6 +221,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
dev_set_drvdata(&sch->dev, private);
private->mdev_type.sysfs_name = "io";
+ private->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
private->mdev_types[0] = &private->mdev_type;
ret = mdev_register_parent(&private->parent, &sch->dev,
&vfio_ccw_mdev_driver,
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 9ced2063720e6..854e0aaefc022 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -44,13 +44,6 @@ static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
vfio_ccw_mdev_reset(private);
}
-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)
@@ -62,7 +55,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,
};
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 728a0ada4928f..9dedb0db8ee84 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -784,14 +784,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)
@@ -803,7 +795,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 af1ff0165b8d3..4bb8a58b577b3 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] 33+ messages in thread
* Re: [PATCH 11/14] vfio/mdev: consolidate all the name sysfs into the core code
2022-08-22 6:22 ` [PATCH 11/14] vfio/mdev: consolidate all the name " Christoph Hellwig
@ 2022-08-23 16:23 ` Anthony Krowiak
0 siblings, 0 replies; 33+ messages in thread
From: Anthony Krowiak @ 2022-08-23 16:23 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, 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
On 8/22/22 2:22 AM, Christoph Hellwig wrote:
> 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.
What am I missing? I can not find where the the driver sets the
mdev_type.pretty_name field by the vfio_ap device driver.
>
> 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_drv.c | 1 +
> drivers/s390/cio/vfio_ccw_ops.c | 8 -------
> 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 ++++------------
> 10 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 b0c29e37f61b4..dcd1231a6fa84 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -217,7 +217,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 1ed99091165a4..e24e72527c9aa 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_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
> index 25a5de08b3902..e5f21c725326b 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
> @@ -221,6 +221,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
> dev_set_drvdata(&sch->dev, private);
>
> private->mdev_type.sysfs_name = "io";
> + private->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
> private->mdev_types[0] = &private->mdev_type;
> ret = mdev_register_parent(&private->parent, &sch->dev,
> &vfio_ccw_mdev_driver,
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index 9ced2063720e6..854e0aaefc022 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -44,13 +44,6 @@ static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
> vfio_ccw_mdev_reset(private);
> }
>
> -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)
> @@ -62,7 +55,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,
> };
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 728a0ada4928f..9dedb0db8ee84 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -784,14 +784,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)
> @@ -803,7 +795,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 af1ff0165b8d3..4bb8a58b577b3 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,
> };
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 12/14] vfio/mdev: consolidate all the available_instance sysfs into the core code
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (10 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 11/14] vfio/mdev: consolidate all the name " Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 13/14] vfio/mdev: consolidate all the description " Christoph Hellwig
2022-08-22 6:22 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 dcd1231a6fa84..558bd7ebced86 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -103,6 +103,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
+ unsigned int (*get_available)(struct mdev_type *mtype);
const struct attribute * const *types_attrs;
struct device_driver driver;
};
@@ -207,7 +208,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 00a2b2173a96f..529134fa71880 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -314,7 +314,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 e24e72527c9aa..7f46e2109af80 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,
};
@@ -1514,6 +1502,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 = {
@@ -1523,6 +1532,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 854e0aaefc022..ffbfd1794d83e 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -44,20 +44,12 @@ static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
vfio_ccw_mdev_reset(private);
}
-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)
{
@@ -582,5 +574,5 @@ 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,
};
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 9dedb0db8ee84..7d27ddfe55ae8 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -784,21 +784,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,
-};
-
#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
"already assigned to %s"
@@ -1782,7 +1772,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 4bb8a58b577b3..d39e08a1824c6 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] 33+ messages in thread
* [PATCH 13/14] vfio/mdev: consolidate all the description sysfs into the core code
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (11 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 12/14] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-22 6:22 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
13 siblings, 0 replies; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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 558bd7ebced86..fdf7d69378ec4 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -104,7 +104,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;
};
@@ -222,7 +222,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 7f46e2109af80..03780490c9f30 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)
{
@@ -1530,10 +1522,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 d39e08a1824c6..33674cb5ed5d4 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] 33+ messages in thread
* [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core
2022-08-22 6:21 simplify the mdev interface v7 Christoph Hellwig
` (12 preceding siblings ...)
2022-08-22 6:22 ` [PATCH 13/14] vfio/mdev: consolidate all the description " Christoph Hellwig
@ 2022-08-22 6:22 ` Christoph Hellwig
2022-08-23 18:07 ` Eric Farman
13 siblings, 1 reply; 33+ messages in thread
From: Christoph Hellwig @ 2022-08-22 6:22 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>
[hch: count instances per-parent instead of per-type, use an atomic_t
to avoid taking mdev_list_lock in the show method]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.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 | 17 ++++++++++++++---
drivers/vfio/mdev/mdev_sysfs.c | 5 ++++-
include/linux/mdev.h | 3 +++
samples/vfio-mdev/mdpy.c | 23 ++++-------------------
9 files changed, 29 insertions(+), 59 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index e5f21c725326b..7f5402fe857a2 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -141,7 +141,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 ffbfd1794d83e..3faf1e4e13005 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -44,13 +44,6 @@ static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
vfio_ccw_mdev_reset(private);
}
-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);
@@ -59,9 +52,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);
@@ -79,7 +69,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
err_atomic:
vfio_uninit_group_dev(&private->vdev);
- atomic_inc(&private->avail);
return ret;
}
@@ -95,7 +84,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
vfio_unregister_group_dev(&private->vdev);
vfio_uninit_group_dev(&private->vdev);
- atomic_inc(&private->avail);
}
static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
@@ -567,6 +555,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,
@@ -574,5 +563,4 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
- .get_available = vfio_ccw_get_available,
};
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index 7abe5a798e002..358996897efc8 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
* @io_region: MMIO region to input/output I/O arguments/results
* @io_mutex: protect against concurrent update of I/O regions
* @region: additional regions for other subchannel operations
@@ -94,7 +93,6 @@ struct vfio_ccw_private {
struct subchannel *sch;
int state;
struct completion *completion;
- atomic_t avail;
struct ccw_io_region *io_region;
struct mutex io_mutex;
struct vfio_ccw_region *region;
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 7d27ddfe55ae8..0d4fe4057dc5d 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -689,14 +689,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);
@@ -718,8 +713,6 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
err_list:
vfio_uninit_group_dev(&matrix_mdev->vdev);
kfree(matrix_mdev);
-err_dec_available:
- atomic_inc(&matrix_dev->available_instances);
return ret;
}
@@ -781,12 +774,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
mutex_unlock(&matrix_dev->guests_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);
}
#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
@@ -1764,6 +1751,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,
@@ -1772,15 +1760,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 441dc8dda380b..2eddd5f34ed34 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -29,7 +29,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
* @mdevs_lock: mutex for locking the AP matrix device. This lock will be
@@ -46,7 +45,6 @@
*/
struct ap_matrix_dev {
struct device device;
- atomic_t available_instances;
struct ap_config_info info;
struct list_head mdev_list;
struct mutex mdevs_lock; /* serializes access to each ap_matrix_mdev */
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 93f8caf2e5f77..2d0302995d7b7 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;
+ atomic_set(&parent->available_instances, mdev_driver->max_instances);
if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
@@ -115,14 +116,17 @@ EXPORT_SYMBOL(mdev_unregister_parent);
static void mdev_device_release(struct device *dev)
{
struct mdev_device *mdev = to_mdev_device(dev);
-
- /* Pairs with the get in mdev_device_create() */
- kobject_put(&mdev->type->kobj);
+ struct mdev_parent *parent = mdev->type->parent;
mutex_lock(&mdev_list_lock);
list_del(&mdev->next);
+ if (!parent->mdev_driver->get_available)
+ atomic_inc(&parent->available_instances);
mutex_unlock(&mdev_list_lock);
+ /* Pairs with the get in mdev_device_create() */
+ kobject_put(&mdev->type->kobj);
+
dev_dbg(&mdev->dev, "MDEV: destroying\n");
kfree(mdev);
}
@@ -144,6 +148,13 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
}
}
+ if (!drv->get_available) {
+ if (atomic_dec_and_test(&parent->available_instances)) {
+ mutex_unlock(&mdev_list_lock);
+ return -EUSERS;
+ }
+ }
+
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev) {
mutex_unlock(&mdev_list_lock);
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index c5cd035d591d0..af51c1cdb7d40 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -108,7 +108,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
{
struct mdev_driver *drv = mtype->parent->mdev_driver;
- return sysfs_emit(buf, "%u\n", drv->get_available(mtype));
+ if (drv->get_available)
+ return sysfs_emit(buf, "%u\n", drv->get_available(mtype));
+ return sysfs_emit(buf, "%u\n",
+ atomic_read(&mtype->parent->available_instances));
}
static MDEV_TYPE_ATTR_RO(available_instances);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 33674cb5ed5d4..139d05b26f820 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;
+ atomic_t 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] 33+ messages in thread
* Re: [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core
2022-08-22 6:22 ` [PATCH 14/14] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
@ 2022-08-23 18:07 ` Eric Farman
0 siblings, 0 replies; 33+ messages in thread
From: Eric Farman @ 2022-08-23 18:07 UTC (permalink / raw)
To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
Jason Herne, Matthew Rosato, Zhenyu Wang, Zhi Wang,
Alex Williamson
Cc: Jason Gunthorpe, kvm, linux-s390, intel-gvt-dev, Kevin Tian
On Mon, 2022-08-22 at 08:22 +0200, Christoph Hellwig wrote:
> 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>
> [hch: count instances per-parent instead of per-type, use an atomic_t
> to avoid taking mdev_list_lock in the show method]
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
...snip...
> diff --git a/drivers/vfio/mdev/mdev_core.c
> b/drivers/vfio/mdev/mdev_core.c
> index 93f8caf2e5f77..2d0302995d7b7 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;
> + atomic_set(&parent->available_instances, mdev_driver-
> >max_instances);
>
> if (!mdev_bus_compat_class) {
> mdev_bus_compat_class =
> class_compat_register("mdev_bus");
> @@ -115,14 +116,17 @@ EXPORT_SYMBOL(mdev_unregister_parent);
> static void mdev_device_release(struct device *dev)
> {
> struct mdev_device *mdev = to_mdev_device(dev);
> -
> - /* Pairs with the get in mdev_device_create() */
> - kobject_put(&mdev->type->kobj);
> + struct mdev_parent *parent = mdev->type->parent;
>
> mutex_lock(&mdev_list_lock);
> list_del(&mdev->next);
> + if (!parent->mdev_driver->get_available)
> + atomic_inc(&parent->available_instances);
> mutex_unlock(&mdev_list_lock);
>
> + /* Pairs with the get in mdev_device_create() */
> + kobject_put(&mdev->type->kobj);
> +
> dev_dbg(&mdev->dev, "MDEV: destroying\n");
> kfree(mdev);
> }
> @@ -144,6 +148,13 @@ int mdev_device_create(struct mdev_type *type,
> const guid_t *uuid)
> }
> }
>
> + if (!drv->get_available) {
> + if (atomic_dec_and_test(&parent-
> >available_instances)) {
This is still broken.
https://lore.kernel.org/r/20220719144808.GA21431@lst.de/
Thanks,
Eric
> + mutex_unlock(&mdev_list_lock);
> + return -EUSERS;
> + }
> + }
> +
^ permalink raw reply [flat|nested] 33+ messages in thread