Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfio/mdev: consolidate all the available_instance sysfs into the core code

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>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Link: https://lore.kernel.org/r/20220923092652.100656-13-hch@lst.de
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Christoph Hellwig and committed by
Alex Williamson
f2fbc72e 0bc79069

+55 -102
+2 -1
Documentation/driver-api/vfio-mediated-device.rst
··· 103 103 struct mdev_driver { 104 104 int (*probe) (struct mdev_device *dev); 105 105 void (*remove) (struct mdev_device *dev); 106 + unsigned int (*get_available)(struct mdev_type *mtype); 106 107 const struct attribute * const *types_attrs; 107 108 struct device_driver driver; 108 109 }; ··· 208 207 209 208 * available_instances 210 209 211 - This attribute should show the number of devices of type <type-id> that can be 210 + This attribute shows the number of devices of type <type-id> that can be 212 211 created. 213 212 214 213 * [device]
-1
drivers/gpu/drm/i915/gvt/gvt.h
··· 314 314 struct mdev_type type; 315 315 char name[16]; 316 316 const struct intel_vgpu_config *conf; 317 - unsigned int avail_instance; 318 317 }; 319 318 320 319 struct intel_gvt {
+22 -12
drivers/gpu/drm/i915/gvt/kvmgt.c
··· 113 113 struct kvm_memory_slot *slot, 114 114 struct kvm_page_track_notifier_node *node); 115 115 116 - static ssize_t available_instances_show(struct mdev_type *mtype, 117 - struct mdev_type_attribute *attr, 118 - char *buf) 119 - { 120 - struct intel_vgpu_type *type = 121 - container_of(mtype, struct intel_vgpu_type, type); 122 - 123 - return sprintf(buf, "%u\n", type->avail_instance); 124 - } 125 - 126 116 static ssize_t description_show(struct mdev_type *mtype, 127 117 struct mdev_type_attribute *attr, char *buf) 128 118 { ··· 128 138 type->conf->weight); 129 139 } 130 140 131 - static MDEV_TYPE_ATTR_RO(available_instances); 132 141 static MDEV_TYPE_ATTR_RO(description); 133 142 134 143 static const struct attribute *gvt_type_attrs[] = { 135 - &mdev_type_attr_available_instances.attr, 136 144 &mdev_type_attr_description.attr, 137 145 NULL, 138 146 }; ··· 1521 1533 vfio_put_device(&vgpu->vfio_device); 1522 1534 } 1523 1535 1536 + static unsigned int intel_vgpu_get_available(struct mdev_type *mtype) 1537 + { 1538 + struct intel_vgpu_type *type = 1539 + container_of(mtype, struct intel_vgpu_type, type); 1540 + struct intel_gvt *gvt = kdev_to_i915(mtype->parent->dev)->gvt; 1541 + unsigned int low_gm_avail, high_gm_avail, fence_avail; 1542 + 1543 + mutex_lock(&gvt->lock); 1544 + low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE - 1545 + gvt->gm.vgpu_allocated_low_gm_size; 1546 + high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE - 1547 + gvt->gm.vgpu_allocated_high_gm_size; 1548 + fence_avail = gvt_fence_sz(gvt) - HOST_FENCE - 1549 + gvt->fence.vgpu_allocated_fence_num; 1550 + mutex_unlock(&gvt->lock); 1551 + 1552 + return min3(low_gm_avail / type->conf->low_mm, 1553 + high_gm_avail / type->conf->high_mm, 1554 + fence_avail / type->conf->fence); 1555 + } 1556 + 1524 1557 static struct mdev_driver intel_vgpu_mdev_driver = { 1525 1558 .device_api = VFIO_DEVICE_API_PCI_STRING, 1526 1559 .driver = { ··· 1551 1542 }, 1552 1543 .probe = intel_vgpu_probe, 1553 1544 .remove = intel_vgpu_remove, 1545 + .get_available = intel_vgpu_get_available, 1554 1546 .types_attrs = gvt_type_attrs, 1555 1547 }; 1556 1548
+3 -38
drivers/gpu/drm/i915/gvt/vgpu.c
··· 129 129 sprintf(gvt->types[i].name, "GVTg_V%u_%s", 130 130 GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name); 131 131 gvt->types[i].conf = conf; 132 - gvt->types[i].avail_instance = min(low_avail / conf->low_mm, 133 - high_avail / conf->high_mm); 134 132 135 133 gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n", 136 - i, gvt->types[i].name, gvt->types[i].avail_instance, 134 + i, gvt->types[i].name, 135 + min(low_avail / conf->low_mm, 136 + high_avail / conf->high_mm), 137 137 conf->low_mm, conf->high_mm, conf->fence, 138 138 conf->weight, vgpu_edid_str(conf->edid)); 139 139 ··· 155 155 { 156 156 kfree(gvt->mdev_types); 157 157 kfree(gvt->types); 158 - } 159 - 160 - static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt) 161 - { 162 - int i; 163 - unsigned int low_gm_avail, high_gm_avail, fence_avail; 164 - unsigned int low_gm_min, high_gm_min, fence_min; 165 - 166 - /* Need to depend on maxium hw resource size but keep on 167 - * static config for now. 168 - */ 169 - low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE - 170 - gvt->gm.vgpu_allocated_low_gm_size; 171 - high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE - 172 - gvt->gm.vgpu_allocated_high_gm_size; 173 - fence_avail = gvt_fence_sz(gvt) - HOST_FENCE - 174 - gvt->fence.vgpu_allocated_fence_num; 175 - 176 - for (i = 0; i < gvt->num_types; i++) { 177 - low_gm_min = low_gm_avail / gvt->types[i].conf->low_mm; 178 - high_gm_min = high_gm_avail / gvt->types[i].conf->high_mm; 179 - fence_min = fence_avail / gvt->types[i].conf->fence; 180 - gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min), 181 - fence_min); 182 - 183 - gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n", 184 - i, gvt->types[i].name, 185 - gvt->types[i].avail_instance, gvt->types[i].conf->low_mm, 186 - gvt->types[i].conf->high_mm, gvt->types[i].conf->fence); 187 - } 188 158 } 189 159 190 160 /** ··· 251 281 intel_vgpu_clean_mmio(vgpu); 252 282 intel_vgpu_dmabuf_cleanup(vgpu); 253 283 mutex_unlock(&vgpu->vgpu_lock); 254 - 255 - mutex_lock(&gvt->lock); 256 - intel_gvt_update_vgpu_types(gvt); 257 - mutex_unlock(&gvt->lock); 258 284 } 259 285 260 286 #define IDLE_VGPU_IDR 0 ··· 380 414 if (ret) 381 415 goto out_clean_sched_policy; 382 416 383 - intel_gvt_update_vgpu_types(gvt); 384 417 intel_gvt_update_reg_whitelist(vgpu); 385 418 mutex_unlock(&gvt->lock); 386 419 return 0;
+3 -11
drivers/s390/cio/vfio_ccw_ops.c
··· 44 44 vfio_ccw_mdev_reset(private); 45 45 } 46 46 47 - static ssize_t available_instances_show(struct mdev_type *mtype, 48 - struct mdev_type_attribute *attr, 49 - char *buf) 47 + static unsigned int vfio_ccw_get_available(struct mdev_type *mtype) 50 48 { 51 49 struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev); 52 50 53 - return sprintf(buf, "%d\n", atomic_read(&private->avail)); 51 + return atomic_read(&private->avail); 54 52 } 55 - static MDEV_TYPE_ATTR_RO(available_instances); 56 - 57 - static const struct attribute *mdev_types_attrs[] = { 58 - &mdev_type_attr_available_instances.attr, 59 - NULL, 60 - }; 61 53 62 54 static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) 63 55 { ··· 612 620 }, 613 621 .probe = vfio_ccw_mdev_probe, 614 622 .remove = vfio_ccw_mdev_remove, 615 - .types_attrs = mdev_types_attrs, 623 + .get_available = vfio_ccw_get_available, 616 624 };
+3 -13
drivers/s390/crypto/vfio_ap_ops.c
··· 790 790 vfio_put_device(&matrix_mdev->vdev); 791 791 } 792 792 793 - static ssize_t available_instances_show(struct mdev_type *mtype, 794 - struct mdev_type_attribute *attr, 795 - char *buf) 793 + static unsigned int vfio_ap_mdev_get_available(struct mdev_type *mtype) 796 794 { 797 - return sprintf(buf, "%d\n", 798 - atomic_read(&matrix_dev->available_instances)); 795 + return atomic_read(&matrix_dev->available_instances); 799 796 } 800 - 801 - static MDEV_TYPE_ATTR_RO(available_instances); 802 - 803 - static const struct attribute *vfio_ap_mdev_type_attrs[] = { 804 - &mdev_type_attr_available_instances.attr, 805 - NULL, 806 - }; 807 797 808 798 #define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \ 809 799 "already assigned to %s" ··· 1780 1790 }, 1781 1791 .probe = vfio_ap_mdev_probe, 1782 1792 .remove = vfio_ap_mdev_remove, 1783 - .types_attrs = vfio_ap_mdev_type_attrs, 1793 + .get_available = vfio_ap_mdev_get_available, 1784 1794 }; 1785 1795 1786 1796 int vfio_ap_mdev_register(void)
+11
drivers/vfio/mdev/mdev_sysfs.c
··· 90 90 91 91 static MDEV_TYPE_ATTR_RO(name); 92 92 93 + static ssize_t available_instances_show(struct mdev_type *mtype, 94 + struct mdev_type_attribute *attr, 95 + char *buf) 96 + { 97 + struct mdev_driver *drv = mtype->parent->mdev_driver; 98 + 99 + return sysfs_emit(buf, "%u\n", drv->get_available(mtype)); 100 + } 101 + static MDEV_TYPE_ATTR_RO(available_instances); 102 + 93 103 static struct attribute *mdev_types_core_attrs[] = { 94 104 &mdev_type_attr_create.attr, 95 105 &mdev_type_attr_device_api.attr, 96 106 &mdev_type_attr_name.attr, 107 + &mdev_type_attr_available_instances.attr, 97 108 NULL, 98 109 }; 99 110
+2
include/linux/mdev.h
··· 72 72 * @device_api: string to return for the device_api sysfs 73 73 * @probe: called when new device created 74 74 * @remove: called when device removed 75 + * @get_available: Return the max number of instances that can be created 75 76 * @types_attrs: attributes to the type kobjects. 76 77 * @driver: device driver structure 77 78 **/ ··· 80 79 const char *device_api; 81 80 int (*probe)(struct mdev_device *dev); 82 81 void (*remove)(struct mdev_device *dev); 82 + unsigned int (*get_available)(struct mdev_type *mtype); 83 83 const struct attribute * const *types_attrs; 84 84 struct device_driver driver; 85 85 };
+3 -7
samples/vfio-mdev/mbochs.c
··· 1361 1361 } 1362 1362 static MDEV_TYPE_ATTR_RO(description); 1363 1363 1364 - static ssize_t available_instances_show(struct mdev_type *mtype, 1365 - struct mdev_type_attribute *attr, 1366 - char *buf) 1364 + static unsigned int mbochs_get_available(struct mdev_type *mtype) 1367 1365 { 1368 1366 struct mbochs_type *type = 1369 1367 container_of(mtype, struct mbochs_type, type); 1370 - int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes; 1371 1368 1372 - return sprintf(buf, "%d\n", count); 1369 + return atomic_read(&mbochs_avail_mbytes) / type->mbytes; 1373 1370 } 1374 - static MDEV_TYPE_ATTR_RO(available_instances); 1375 1371 1376 1372 static const struct attribute *mdev_types_attrs[] = { 1377 1373 &mdev_type_attr_description.attr, 1378 - &mdev_type_attr_available_instances.attr, 1379 1374 NULL, 1380 1375 }; 1381 1376 ··· 1394 1399 }, 1395 1400 .probe = mbochs_probe, 1396 1401 .remove = mbochs_remove, 1402 + .get_available = mbochs_get_available, 1397 1403 .types_attrs = mdev_types_attrs, 1398 1404 }; 1399 1405
+3 -6
samples/vfio-mdev/mdpy.c
··· 671 671 } 672 672 static MDEV_TYPE_ATTR_RO(description); 673 673 674 - static ssize_t available_instances_show(struct mdev_type *mtype, 675 - struct mdev_type_attribute *attr, 676 - char *buf) 674 + static unsigned int mdpy_get_available(struct mdev_type *mtype) 677 675 { 678 - return sprintf(buf, "%d\n", max_devices - mdpy_count); 676 + return max_devices - mdpy_count; 679 677 } 680 - static MDEV_TYPE_ATTR_RO(available_instances); 681 678 682 679 static const struct attribute *mdev_types_attrs[] = { 683 680 &mdev_type_attr_description.attr, 684 - &mdev_type_attr_available_instances.attr, 685 681 NULL, 686 682 }; 687 683 ··· 700 704 }, 701 705 .probe = mdpy_probe, 702 706 .remove = mdpy_remove, 707 + .get_available = mdpy_get_available, 703 708 .types_attrs = mdev_types_attrs, 704 709 }; 705 710
+3 -13
samples/vfio-mdev/mtty.c
··· 1256 1256 NULL, 1257 1257 }; 1258 1258 1259 - static ssize_t available_instances_show(struct mdev_type *mtype, 1260 - struct mdev_type_attribute *attr, 1261 - char *buf) 1259 + static unsigned int mtty_get_available(struct mdev_type *mtype) 1262 1260 { 1263 1261 struct mtty_type *type = container_of(mtype, struct mtty_type, type); 1264 1262 1265 - return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) / 1266 - type->nr_ports); 1263 + return atomic_read(&mdev_avail_ports) / type->nr_ports; 1267 1264 } 1268 - 1269 - static MDEV_TYPE_ATTR_RO(available_instances); 1270 - 1271 - static const struct attribute *mdev_types_attrs[] = { 1272 - &mdev_type_attr_available_instances.attr, 1273 - NULL, 1274 - }; 1275 1265 1276 1266 static const struct vfio_device_ops mtty_dev_ops = { 1277 1267 .name = "vfio-mtty", ··· 1282 1292 }, 1283 1293 .probe = mtty_probe, 1284 1294 .remove = mtty_remove, 1285 - .types_attrs = mdev_types_attrs, 1295 + .get_available = mtty_get_available, 1286 1296 }; 1287 1297 1288 1298 static void mtty_device_release(struct device *dev)