Skip to content

Commit da44c34

Browse files
Christoph Hellwigawilliam
Christoph Hellwig
authored andcommitted
vfio/mdev: simplify mdev_type handling
Instead of abusing struct attribute_group to control initialization of struct mdev_type, just define the actual attributes in the mdev_driver, allocate the mdev_type structures in the caller and pass them to mdev_register_parent. This allows the caller to use container_of to get at the containing structure and thus significantly simplify the code. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Tony Krowiak <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Kirti Wankhede <[email protected]> Reviewed-by: Eric Farman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 89345d5 commit da44c34

File tree

17 files changed

+165
-326
lines changed

17 files changed

+165
-326
lines changed

Documentation/driver-api/vfio-mediated-device.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ structure to represent a mediated device's driver::
103103
struct mdev_driver {
104104
int (*probe) (struct mdev_device *dev);
105105
void (*remove) (struct mdev_device *dev);
106-
struct attribute_group **supported_type_groups;
106+
const struct attribute * const *types_attrs;
107107
struct device_driver driver;
108108
};
109109

drivers/gpu/drm/i915/gvt/gvt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ struct intel_vgpu_config {
310310
const char *name;
311311
};
312312

313-
#define NR_MAX_INTEL_VGPU_TYPES 20
314313
struct intel_vgpu_type {
314+
struct mdev_type type;
315315
char name[16];
316316
const struct intel_vgpu_config *conf;
317317
unsigned int avail_instance;
@@ -339,6 +339,7 @@ struct intel_gvt {
339339
struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
340340
DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
341341
struct mdev_parent parent;
342+
struct mdev_type **mdev_types;
342343
struct intel_vgpu_type *types;
343344
unsigned int num_types;
344345
struct intel_vgpu *idle_vgpu;

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 14 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
117117
struct mdev_type_attribute *attr,
118118
char *buf)
119119
{
120-
struct intel_vgpu_type *type;
121-
unsigned int num = 0;
122-
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
120+
struct intel_vgpu_type *type =
121+
container_of(mtype, struct intel_vgpu_type, type);
123122

124-
type = &gvt->types[mtype_get_type_group_id(mtype)];
125-
if (!type)
126-
num = 0;
127-
else
128-
num = type->avail_instance;
129-
130-
return sprintf(buf, "%u\n", num);
123+
return sprintf(buf, "%u\n", type->avail_instance);
131124
}
132125

133126
static ssize_t device_api_show(struct mdev_type *mtype,
@@ -139,12 +132,8 @@ static ssize_t device_api_show(struct mdev_type *mtype,
139132
static ssize_t description_show(struct mdev_type *mtype,
140133
struct mdev_type_attribute *attr, char *buf)
141134
{
142-
struct intel_vgpu_type *type;
143-
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
144-
145-
type = &gvt->types[mtype_get_type_group_id(mtype)];
146-
if (!type)
147-
return 0;
135+
struct intel_vgpu_type *type =
136+
container_of(mtype, struct intel_vgpu_type, type);
148137

149138
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
150139
"fence: %d\nresolution: %s\n"
@@ -158,74 +147,22 @@ static ssize_t description_show(struct mdev_type *mtype,
158147
static ssize_t name_show(struct mdev_type *mtype,
159148
struct mdev_type_attribute *attr, char *buf)
160149
{
161-
struct intel_vgpu_type *type;
162-
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
163-
164-
type = &gvt->types[mtype_get_type_group_id(mtype)];
165-
if (!type)
166-
return 0;
167-
168-
return sprintf(buf, "%s\n", type->name);
150+
return sprintf(buf, "%s\n", mtype->sysfs_name);
169151
}
170152

171153
static MDEV_TYPE_ATTR_RO(available_instances);
172154
static MDEV_TYPE_ATTR_RO(device_api);
173155
static MDEV_TYPE_ATTR_RO(description);
174156
static MDEV_TYPE_ATTR_RO(name);
175157

176-
static struct attribute *gvt_type_attrs[] = {
158+
static const struct attribute *gvt_type_attrs[] = {
177159
&mdev_type_attr_available_instances.attr,
178160
&mdev_type_attr_device_api.attr,
179161
&mdev_type_attr_description.attr,
180162
&mdev_type_attr_name.attr,
181163
NULL,
182164
};
183165

184-
static struct attribute_group *gvt_vgpu_type_groups[] = {
185-
[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
186-
};
187-
188-
static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
189-
{
190-
int i, j;
191-
struct intel_vgpu_type *type;
192-
struct attribute_group *group;
193-
194-
for (i = 0; i < gvt->num_types; i++) {
195-
type = &gvt->types[i];
196-
197-
group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
198-
if (!group)
199-
goto unwind;
200-
201-
group->name = type->name;
202-
group->attrs = gvt_type_attrs;
203-
gvt_vgpu_type_groups[i] = group;
204-
}
205-
206-
return 0;
207-
208-
unwind:
209-
for (j = 0; j < i; j++) {
210-
group = gvt_vgpu_type_groups[j];
211-
kfree(group);
212-
}
213-
214-
return -ENOMEM;
215-
}
216-
217-
static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
218-
{
219-
int i;
220-
struct attribute_group *group;
221-
222-
for (i = 0; i < gvt->num_types; i++) {
223-
group = gvt_vgpu_type_groups[i];
224-
gvt_vgpu_type_groups[i] = NULL;
225-
kfree(group);
226-
}
227-
}
228-
229166
static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
230167
unsigned long size)
231168
{
@@ -1547,16 +1484,11 @@ static const struct attribute_group *intel_vgpu_groups[] = {
15471484
static int intel_vgpu_init_dev(struct vfio_device *vfio_dev)
15481485
{
15491486
struct mdev_device *mdev = to_mdev_device(vfio_dev->dev);
1550-
struct device *pdev = mdev_parent_dev(mdev);
1551-
struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
1552-
struct intel_vgpu_type *type;
15531487
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
1488+
struct intel_vgpu_type *type =
1489+
container_of(mdev->type, struct intel_vgpu_type, type);
15541490

1555-
type = &gvt->types[mdev_get_type_group_id(mdev)];
1556-
if (!type)
1557-
return -EINVAL;
1558-
1559-
vgpu->gvt = gvt;
1491+
vgpu->gvt = kdev_to_i915(mdev_parent_dev(mdev))->gvt;
15601492
return intel_gvt_create_vgpu(vgpu, type->conf);
15611493
}
15621494

@@ -1625,7 +1557,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
16251557
},
16261558
.probe = intel_vgpu_probe,
16271559
.remove = intel_vgpu_remove,
1628-
.supported_type_groups = gvt_vgpu_type_groups,
1560+
.types_attrs = gvt_type_attrs,
16291561
};
16301562

16311563
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
@@ -1924,7 +1856,6 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
19241856
return;
19251857

19261858
mdev_unregister_parent(&gvt->parent);
1927-
intel_gvt_cleanup_vgpu_type_groups(gvt);
19281859
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
19291860
intel_gvt_clean_vgpu_types(gvt);
19301861

@@ -2024,20 +1955,15 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
20241955

20251956
intel_gvt_debugfs_init(gvt);
20261957

2027-
ret = intel_gvt_init_vgpu_type_groups(gvt);
2028-
if (ret)
2029-
goto out_destroy_idle_vgpu;
2030-
20311958
ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
2032-
&intel_vgpu_mdev_driver);
1959+
&intel_vgpu_mdev_driver,
1960+
gvt->mdev_types, gvt->num_types);
20331961
if (ret)
2034-
goto out_cleanup_vgpu_type_groups;
1962+
goto out_destroy_idle_vgpu;
20351963

20361964
gvt_dbg_core("gvt device initialization is done\n");
20371965
return 0;
20381966

2039-
out_cleanup_vgpu_type_groups:
2040-
intel_gvt_cleanup_vgpu_type_groups(gvt);
20411967
out_destroy_idle_vgpu:
20421968
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
20431969
intel_gvt_debugfs_clean(gvt);

drivers/gpu/drm/i915/gvt/vgpu.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,18 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
113113
if (!gvt->types)
114114
return -ENOMEM;
115115

116+
gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types),
117+
GFP_KERNEL);
118+
if (!gvt->mdev_types)
119+
goto out_free_types;
120+
116121
for (i = 0; i < num_types; ++i) {
117122
const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
118123

119124
if (low_avail / conf->low_mm == 0)
120125
break;
121126
if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
122-
goto out_free_types;
127+
goto out_free_mdev_types;
123128

124129
sprintf(gvt->types[i].name, "GVTg_V%u_%s",
125130
GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
@@ -131,18 +136,24 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
131136
i, gvt->types[i].name, gvt->types[i].avail_instance,
132137
conf->low_mm, conf->high_mm, conf->fence,
133138
conf->weight, vgpu_edid_str(conf->edid));
139+
140+
gvt->mdev_types[i] = &gvt->types[i].type;
141+
gvt->mdev_types[i]->sysfs_name = gvt->types[i].name;
134142
}
135143

136144
gvt->num_types = i;
137145
return 0;
138146

147+
out_free_mdev_types:
148+
kfree(gvt->mdev_types);
139149
out_free_types:
140150
kfree(gvt->types);
141151
return -EINVAL;
142152
}
143153

144154
void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
145155
{
156+
kfree(gvt->mdev_types);
146157
kfree(gvt->types);
147158
}
148159

drivers/s390/cio/vfio_ccw_drv.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private)
202202
mutex_destroy(&private->io_mutex);
203203
kfree(private);
204204
}
205-
206205
static int vfio_ccw_sch_probe(struct subchannel *sch)
207206
{
208207
struct pmcw *pmcw = &sch->schib.pmcw;
@@ -221,8 +220,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
221220

222221
dev_set_drvdata(&sch->dev, private);
223222

223+
private->mdev_type.sysfs_name = "io";
224+
private->mdev_types[0] = &private->mdev_type;
224225
ret = mdev_register_parent(&private->parent, &sch->dev,
225-
&vfio_ccw_mdev_driver);
226+
&vfio_ccw_mdev_driver,
227+
private->mdev_types, 1);
226228
if (ret)
227229
goto out_free;
228230

drivers/s390/cio/vfio_ccw_ops.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
6969
}
7070
static MDEV_TYPE_ATTR_RO(available_instances);
7171

72-
static struct attribute *mdev_types_attrs[] = {
72+
static const struct attribute *mdev_types_attrs[] = {
7373
&mdev_type_attr_name.attr,
7474
&mdev_type_attr_device_api.attr,
7575
&mdev_type_attr_available_instances.attr,
7676
NULL,
7777
};
7878

79-
static struct attribute_group mdev_type_group = {
80-
.name = "io",
81-
.attrs = mdev_types_attrs,
82-
};
83-
84-
static struct attribute_group *mdev_type_groups[] = {
85-
&mdev_type_group,
86-
NULL,
87-
};
88-
8979
static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)
9080
{
9181
struct vfio_ccw_private *private =
@@ -646,5 +636,5 @@ struct mdev_driver vfio_ccw_mdev_driver = {
646636
},
647637
.probe = vfio_ccw_mdev_probe,
648638
.remove = vfio_ccw_mdev_remove,
649-
.supported_type_groups = mdev_type_groups,
639+
.types_attrs = mdev_types_attrs,
650640
};

drivers/s390/cio/vfio_ccw_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct vfio_ccw_private {
120120
struct completion release_comp;
121121

122122
struct mdev_parent parent;
123+
struct mdev_type mdev_type;
124+
struct mdev_type *mdev_types[1];
123125
} __aligned(8);
124126

125127
int vfio_ccw_sch_quiesce(struct subchannel *sch);

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -816,23 +816,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
816816

817817
static MDEV_TYPE_ATTR_RO(device_api);
818818

819-
static struct attribute *vfio_ap_mdev_type_attrs[] = {
819+
static const struct attribute *vfio_ap_mdev_type_attrs[] = {
820820
&mdev_type_attr_name.attr,
821821
&mdev_type_attr_device_api.attr,
822822
&mdev_type_attr_available_instances.attr,
823823
NULL,
824824
};
825825

826-
static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
827-
.name = VFIO_AP_MDEV_TYPE_HWVIRT,
828-
.attrs = vfio_ap_mdev_type_attrs,
829-
};
830-
831-
static struct attribute_group *vfio_ap_mdev_type_groups[] = {
832-
&vfio_ap_mdev_hwvirt_type_group,
833-
NULL,
834-
};
835-
836826
#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
837827
"already assigned to %s"
838828

@@ -1817,7 +1807,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
18171807
},
18181808
.probe = vfio_ap_mdev_probe,
18191809
.remove = vfio_ap_mdev_remove,
1820-
.supported_type_groups = vfio_ap_mdev_type_groups,
1810+
.types_attrs = vfio_ap_mdev_type_attrs,
18211811
};
18221812

18231813
int vfio_ap_mdev_register(void)
@@ -1830,8 +1820,11 @@ int vfio_ap_mdev_register(void)
18301820
if (ret)
18311821
return ret;
18321822

1823+
matrix_dev->mdev_type.sysfs_name = VFIO_AP_MDEV_TYPE_HWVIRT;
1824+
matrix_dev->mdev_types[0] = &matrix_dev->mdev_type;
18331825
ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
1834-
&vfio_ap_matrix_driver);
1826+
&vfio_ap_matrix_driver,
1827+
matrix_dev->mdev_types, 1);
18351828
if (ret)
18361829
goto err_driver;
18371830
return 0;

drivers/s390/crypto/vfio_ap_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ struct ap_matrix_dev {
5353
struct ap_driver *vfio_ap_drv;
5454
struct mutex guests_lock; /* serializes access to each KVM guest */
5555
struct mdev_parent parent;
56+
struct mdev_type mdev_type;
57+
struct mdev_type *mdev_types[];
5658
};
5759

5860
extern struct ap_matrix_dev *matrix_dev;

0 commit comments

Comments
 (0)