All of lore.kernel.org
 help / color / mirror / Atom feed
* simplify the mdev interface v2
@ 2022-06-14  4:54 Christoph Hellwig
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
                   ` (13 more replies)
  0 siblings, 14 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

Hi all,

this series signigicantly simplies the mdev driver interface by following
the patterns for device model interaction used elsewhere in the kernel.

Changes since v1:
 - embedd the mdev_parent into a different sub-structure in i916
 - remove headers now inclued by mdev.h from individual source files
 - pass an array of mdev_types to mdev_register_parent
 - add additional patches to implement all attributes on the
   mdev_type in the core code

Diffstat:
 Documentation/driver-api/vfio-mediated-device.rst |   26 +-
 Documentation/s390/vfio-ap.rst                    |    2 
 Documentation/s390/vfio-ccw.rst                   |    2 
 drivers/gpu/drm/i915/gvt/gvt.h                    |    6 
 drivers/gpu/drm/i915/gvt/kvmgt.c                  |  158 +++------------
 drivers/gpu/drm/i915/gvt/vgpu.c                   |   60 +----
 drivers/s390/cio/cio.h                            |    4 
 drivers/s390/cio/vfio_ccw_drv.c                   |    3 
 drivers/s390/cio/vfio_ccw_ops.c                   |   60 -----
 drivers/s390/cio/vfio_ccw_private.h               |    2 
 drivers/s390/crypto/vfio_ap_ops.c                 |   68 ------
 drivers/s390/crypto/vfio_ap_private.h             |    6 
 drivers/vfio/mdev/mdev_core.c                     |  214 ++++++--------------
 drivers/vfio/mdev/mdev_driver.c                   |    7 
 drivers/vfio/mdev/mdev_private.h                  |   39 ---
 drivers/vfio/mdev/mdev_sysfs.c                    |  230 ++++++++--------------
 include/linux/mdev.h                              |   77 +++----
 samples/vfio-mdev/mbochs.c                        |  103 ++-------
 samples/vfio-mdev/mdpy.c                          |  115 ++---------
 samples/vfio-mdev/mtty.c                          |   94 +++-----
 20 files changed, 389 insertions(+), 887 deletions(-)

^ permalink raw reply	[flat|nested] 59+ messages in thread

* [PATCH 01/13] vfio/mdev: make mdev.h standalone includable
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14  9:50   ` Tian, Kevin
                     ` (2 more replies)
  2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
                   ` (12 subsequent siblings)
  13 siblings, 3 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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>
---
 drivers/gpu/drm/i915/gvt/kvmgt.c      | 2 --
 drivers/s390/cio/vfio_ccw_drv.c       | 2 --
 drivers/s390/crypto/vfio_ap_private.h | 1 -
 drivers/vfio/mdev/mdev_core.c         | 2 --
 drivers/vfio/mdev/mdev_driver.c       | 1 -
 drivers/vfio/mdev/mdev_sysfs.c        | 2 --
 include/linux/mdev.h                  | 3 +++
 samples/vfio-mdev/mbochs.c            | 1 -
 samples/vfio-mdev/mdpy.c              | 1 -
 samples/vfio-mdev/mtty.c              | 2 --
 10 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index e2f6c56ab3420..50c0081c4f0d5 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -34,7 +34,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/device.h>
 #include <linux/mm.h>
 #include <linux/kthread.h>
 #include <linux/sched/mm.h>
@@ -43,7 +42,6 @@
 #include <linux/rbtree.h>
 #include <linux/spinlock.h>
 #include <linux/eventfd.h>
-#include <linux/uuid.h>
 #include <linux/mdev.h>
 #include <linux/debugfs.h>
 
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index ee182cfb467d1..750d0315f1f5b 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -12,9 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/device.h>
 #include <linux/slab.h>
-#include <linux/uuid.h>
 #include <linux/mdev.h>
 
 #include <asm/isc.h>
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index a26efd804d0df..6616aa83347ad 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -13,7 +13,6 @@
 #define _VFIO_AP_PRIVATE_H_
 
 #include <linux/types.h>
-#include <linux/device.h>
 #include <linux/mdev.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index b8b9e7911e559..2c32923fbad27 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -8,9 +8,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/device.h>
 #include <linux/slab.h>
-#include <linux/uuid.h>
 #include <linux/sysfs.h>
 #include <linux/mdev.h>
 
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 9c2af59809e2e..7bd4bb9850e81 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -7,7 +7,6 @@
  *             Kirti Wankhede <kwankhede@nvidia.com>
  */
 
-#include <linux/device.h>
 #include <linux/iommu.h>
 #include <linux/mdev.h>
 
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 0ccfeb3dda245..4bfbf49aaa66a 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -9,9 +9,7 @@
 
 #include <linux/sysfs.h>
 #include <linux/ctype.h>
-#include <linux/device.h>
 #include <linux/slab.h>
-#include <linux/uuid.h>
 #include <linux/mdev.h>
 
 #include "mdev_private.h"
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index bb539794f54a8..555c1d015b5f0 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -10,6 +10,9 @@
 #ifndef MDEV_H
 #define MDEV_H
 
+#include <linux/device.h>
+#include <linux/uuid.h>
+
 struct mdev_type;
 
 struct mdev_device {
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 344c2901a82bf..d0d1bb7747240 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -21,7 +21,6 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index e8c46eb2e2468..0c4ca1f4be7ed 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -17,7 +17,6 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index f42a59ed2e3fe..4f5a6f2d3629d 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -12,7 +12,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
@@ -20,7 +19,6 @@
 #include <linux/cdev.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
-#include <linux/uuid.h>
 #include <linux/vfio.h>
 #include <linux/iommu.h>
 #include <linux/sysfs.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14  9:54   ` Tian, Kevin
                     ` (2 more replies)
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
                   ` (11 subsequent siblings)
  13 siblings, 3 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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>
---
 .../driver-api/vfio-mediated-device.rst       |  12 +-
 Documentation/s390/vfio-ap.rst                |   2 +-
 Documentation/s390/vfio-ccw.rst               |   2 +-
 drivers/gpu/drm/i915/gvt/gvt.h                |   2 +
 drivers/gpu/drm/i915/gvt/kvmgt.c              |   5 +-
 drivers/s390/cio/cio.h                        |   2 +
 drivers/s390/cio/vfio_ccw_ops.c               |   6 +-
 drivers/s390/crypto/vfio_ap_ops.c             |   5 +-
 drivers/s390/crypto/vfio_ap_private.h         |   1 +
 drivers/vfio/mdev/mdev_core.c                 | 116 +++---------------
 drivers/vfio/mdev/mdev_private.h              |  23 ----
 drivers/vfio/mdev/mdev_sysfs.c                |   4 +-
 include/linux/mdev.h                          |  15 ++-
 samples/vfio-mdev/mbochs.c                    |   5 +-
 samples/vfio-mdev/mdpy.c                      |   5 +-
 samples/vfio-mdev/mtty.c                      |   6 +-
 16 files changed, 65 insertions(+), 146 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index eded8719180fb..3749f59c855fa 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -60,19 +60,19 @@ devices as examples, as these devices are the first devices to use this module::
      |  MDEV CORE    |
      |   MODULE      |
      |   mdev.ko     |
-     | +-----------+ |  mdev_register_device() +--------------+
+     | +-----------+ |  mdev_register_parent() +--------------+
      | |           | +<------------------------+              |
      | |           | |                         |  nvidia.ko   |<-> physical
      | |           | +------------------------>+              |    device
      | |           | |        callbacks        +--------------+
      | | Physical  | |
-     | |  device   | |  mdev_register_device() +--------------+
+     | |  device   | |  mdev_register_parent() +--------------+
      | | interface | |<------------------------+              |
      | |           | |                         |  i915.ko     |<-> physical
      | |           | +------------------------>+              |    device
      | |           | |        callbacks        +--------------+
      | |           | |
-     | |           | |  mdev_register_device() +--------------+
+     | |           | |  mdev_register_parent() +--------------+
      | |           | +<------------------------+              |
      | |           | |                         | ccw_device.ko|<-> physical
      | |           | +------------------------>+              |    device
@@ -127,8 +127,8 @@ vfio_device_ops.
 When a driver wants to add the GUID creation sysfs to an existing device it has
 probe'd to then it should call::
 
-	extern int  mdev_register_device(struct device *dev,
-	                                 struct mdev_driver *mdev_driver);
+	int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+			struct mdev_driver *mdev_driver);
 
 This will provide the 'mdev_supported_types/XX/create' files which can then be
 used to trigger the creation of a mdev_device. The created mdev_device will be
@@ -136,7 +136,7 @@ attached to the specified driver.
 
 When the driver needs to remove itself it calls::
 
-	extern void mdev_unregister_device(struct device *dev);
+	void mdev_unregister_parent(struct mdev_parent *parent);
 
 Which will unbind and destroy all the created mdevs and remove the sysfs files.
 
diff --git a/Documentation/s390/vfio-ap.rst b/Documentation/s390/vfio-ap.rst
index f57ae621f33e8..37e16158c7fbf 100644
--- a/Documentation/s390/vfio-ap.rst
+++ b/Documentation/s390/vfio-ap.rst
@@ -299,7 +299,7 @@ of the VFIO AP mediated matrix device driver::
    |  MDEV CORE  |
    |   MODULE    |
    |   mdev.ko   |
-   | +---------+ | mdev_register_device() +--------------+
+   | +---------+ | mdev_register_parent() +--------------+
    | |Physical | +<-----------------------+              |
    | | device  | |                        |  vfio_ap.ko  |<-> matrix
    | |interface| +----------------------->+              |    device
diff --git a/Documentation/s390/vfio-ccw.rst b/Documentation/s390/vfio-ccw.rst
index 8aad08a8b8a50..ea928a3806f43 100644
--- a/Documentation/s390/vfio-ccw.rst
+++ b/Documentation/s390/vfio-ccw.rst
@@ -156,7 +156,7 @@ Below is a high Level block diagram::
  |  MDEV CORE  |
  |   MODULE    |
  |   mdev.ko   |
- | +---------+ | mdev_register_device() +--------------+
+ | +---------+ | mdev_register_parent() +--------------+
  | |Physical | +<-----------------------+              |
  | | device  | |                        |  vfio_ccw.ko |<-> subchannel
  | |interface| +----------------------->+              |     device
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index aee1a45da74bc..ddffd337f1c60 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"
@@ -327,6 +328,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 50c0081c4f0d5..70401374c72bc 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1958,7 +1958,7 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
 	if (drm_WARN_ON(&i915->drm, !gvt))
 		return;
 
-	mdev_unregister_device(i915->drm.dev);
+	mdev_unregister_parent(&gvt->parent);
 	intel_gvt_cleanup_vgpu_type_groups(gvt);
 	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
 	intel_gvt_clean_vgpu_types(gvt);
@@ -2063,7 +2063,8 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
 	if (ret)
 		goto out_destroy_idle_vgpu;
 
-	ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_driver);
+	ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
+				   &intel_vgpu_mdev_driver);
 	if (ret)
 		goto out_cleanup_vgpu_type_groups;
 
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index fa8df50bb49e3..22be5ac7d23c1 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -5,6 +5,7 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/mdev.h>
 #include <asm/chpid.h>
 #include <asm/cio.h>
 #include <asm/fcx.h>
@@ -108,6 +109,7 @@ struct subchannel {
 	 * frees it.  Use driver_set_override() to set or clear it.
 	 */
 	const char *driver_override;
+	struct mdev_parent parent;
 } __attribute__ ((aligned(8)));
 
 DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index b49e2e9db2dc6..9192a21085ce4 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -11,7 +11,6 @@
  */
 
 #include <linux/vfio.h>
-#include <linux/mdev.h>
 #include <linux/nospec.h>
 #include <linux/slab.h>
 
@@ -660,10 +659,11 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 
 int vfio_ccw_mdev_reg(struct subchannel *sch)
 {
-	return mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
+	return mdev_register_parent(&sch->parent, &sch->dev,
+				    &vfio_ccw_mdev_driver);
 }
 
 void vfio_ccw_mdev_unreg(struct subchannel *sch)
 {
-	mdev_unregister_device(&sch->dev);
+	mdev_unregister_parent(&sch->parent);
 }
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index a7d2a95796d36..834945150dc9f 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1485,7 +1485,8 @@ int vfio_ap_mdev_register(void)
 	if (ret)
 		return ret;
 
-	ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_driver);
+	ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
+				   &vfio_ap_matrix_driver);
 	if (ret)
 		goto err_driver;
 	return 0;
@@ -1497,6 +1498,6 @@ int vfio_ap_mdev_register(void)
 
 void vfio_ap_mdev_unregister(void)
 {
-	mdev_unregister_device(&matrix_dev->device);
+	mdev_unregister_parent(&matrix_dev->parent);
 	mdev_unregister_driver(&vfio_ap_matrix_driver);
 }
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 6616aa83347ad..0191f6bc973a4 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -45,6 +45,7 @@ struct ap_matrix_dev {
 	struct list_head mdev_list;
 	struct mutex lock;
 	struct ap_driver  *vfio_ap_drv;
+	struct mdev_parent parent;
 };
 
 extern struct ap_matrix_dev *matrix_dev;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 2c32923fbad27..d38faed14c689 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,69 @@ 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.
  * Returns a negative value on error, otherwise 0.
  */
-int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver)
+int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+		struct mdev_driver *mdev_driver)
 {
-	int ret;
-	struct mdev_parent *parent;
 	char *env_string = "MDEV_STATE=registered";
 	char *envp[] = { env_string, NULL };
+	int ret;
 
 	/* check for mandatory ops */
 	if (!mdev_driver->supported_type_groups)
 		return -EINVAL;
 
-	dev = get_device(dev);
-	if (!dev)
-		return -EINVAL;
-
-	mutex_lock(&parent_list_lock);
-
-	/* Check for duplicate */
-	parent = __find_parent_device(dev);
-	if (parent) {
-		parent = NULL;
-		ret = -EEXIST;
-		goto add_dev_err;
-	}
-
-	parent = kzalloc(sizeof(*parent), GFP_KERNEL);
-	if (!parent) {
-		ret = -ENOMEM;
-		goto add_dev_err;
-	}
-
-	kref_init(&parent->ref);
+	memset(parent, 0, sizeof(*parent));
 	init_rwsem(&parent->unreg_sem);
-
 	parent->dev = dev;
 	parent->mdev_driver = mdev_driver;
 
 	if (!mdev_bus_compat_class) {
 		mdev_bus_compat_class = class_compat_register("mdev_bus");
-		if (!mdev_bus_compat_class) {
-			ret = -ENOMEM;
-			goto add_dev_err;
-		}
+		if (!mdev_bus_compat_class)
+			return -ENOMEM;
 	}
 
 	ret = parent_create_sysfs_files(parent);
 	if (ret)
-		goto add_dev_err;
+		return ret;
 
 	ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
 	if (ret)
 		dev_warn(dev, "Failed to create compatibility class link\n");
 
-	list_add(&parent->next, &parent_list);
-	mutex_unlock(&parent_list_lock);
-
 	dev_info(dev, "MDEV: Registered\n");
 	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
-
 	return 0;
-
-add_dev_err:
-	mutex_unlock(&parent_list_lock);
-	if (parent)
-		mdev_put_parent(parent);
-	else
-		put_device(dev);
-	return ret;
 }
-EXPORT_SYMBOL(mdev_register_device);
+EXPORT_SYMBOL(mdev_register_parent);
 
 /*
- * mdev_unregister_device : Unregister a parent device
- * @dev: device structure representing parent device.
- *
- * Remove device from list of registered parent devices. Give a chance to free
- * existing mediated devices for given device.
+ * mdev_unregister_parent : Unregister a parent device
+ * @parent: parent structure to unregister
  */
-
-void mdev_unregister_device(struct device *dev)
+void mdev_unregister_parent(struct mdev_parent *parent)
 {
-	struct mdev_parent *parent;
 	char *env_string = "MDEV_STATE=unregistered";
 	char *envp[] = { env_string, NULL };
 
-	mutex_lock(&parent_list_lock);
-	parent = __find_parent_device(dev);
-
-	if (!parent) {
-		mutex_unlock(&parent_list_lock);
-		return;
-	}
-	dev_info(dev, "MDEV: Unregistering\n");
-
-	list_del(&parent->next);
-	mutex_unlock(&parent_list_lock);
+	dev_info(parent->dev, "MDEV: Unregistering\n");
 
 	down_write(&parent->unreg_sem);
-
-	class_compat_remove_link(mdev_bus_compat_class, dev, NULL);
-
-	device_for_each_child(dev, NULL, mdev_device_remove_cb);
-
+	class_compat_remove_link(mdev_bus_compat_class, parent->dev, NULL);
+	device_for_each_child(parent->dev, NULL, mdev_device_remove_cb);
 	parent_remove_sysfs_files(parent);
 	up_write(&parent->unreg_sem);
 
-	mdev_put_parent(parent);
-
-	/* We still have the caller's reference to use for the uevent */
-	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+	kobject_uevent_env(&parent->dev->kobj, KOBJ_CHANGE, envp);
 }
-EXPORT_SYMBOL(mdev_unregister_device);
+EXPORT_SYMBOL(mdev_unregister_parent);
 
 static void mdev_device_release(struct device *dev)
 {
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index 7c9fc79f3d838..297f911fdc890 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -13,17 +13,6 @@
 int  mdev_bus_register(void);
 void mdev_bus_unregister(void);
 
-struct mdev_parent {
-	struct device *dev;
-	struct mdev_driver *mdev_driver;
-	struct kref ref;
-	struct list_head next;
-	struct kset *mdev_types_kset;
-	struct list_head type_list;
-	/* Synchronize device creation/removal with parent unregistration */
-	struct rw_semaphore unreg_sem;
-};
-
 struct mdev_type {
 	struct kobject kobj;
 	struct kobject *devices_kobj;
@@ -48,16 +37,4 @@ void mdev_remove_sysfs_files(struct mdev_device *mdev);
 int mdev_device_create(struct mdev_type *kobj, const guid_t *uuid);
 int  mdev_device_remove(struct mdev_device *dev);
 
-void mdev_release_parent(struct kref *kref);
-
-static inline void mdev_get_parent(struct mdev_parent *parent)
-{
-	kref_get(&parent->ref);
-}
-
-static inline void mdev_put_parent(struct mdev_parent *parent)
-{
-	kref_put(&parent->ref, mdev_release_parent);
-}
-
 #endif /* MDEV_PRIVATE_H */
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 4bfbf49aaa66a..b71ffc5594870 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -81,7 +81,7 @@ static void mdev_type_release(struct kobject *kobj)
 
 	pr_debug("Releasing group %s\n", kobj->name);
 	/* Pairs with the get in add_mdev_supported_type() */
-	mdev_put_parent(type->parent);
+	put_device(type->parent->dev);
 	kfree(type);
 }
 
@@ -110,7 +110,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
 	type->kobj.kset = parent->mdev_types_kset;
 	type->parent = parent;
 	/* Pairs with the put in mdev_type_release() */
-	mdev_get_parent(parent);
+	get_device(parent->dev);
 	type->type_group_id = type_group_id;
 
 	ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL,
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 555c1d015b5f0..327ce3e5c6b5f 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -23,6 +23,16 @@ struct mdev_device {
 	bool active;
 };
 
+/* embedded into the struct device that the mdev devices hang off */
+struct mdev_parent {
+	struct device *dev;
+	struct mdev_driver *mdev_driver;
+	struct kset *mdev_types_kset;
+	struct list_head type_list;
+	/* Synchronize device creation/removal with parent unregistration */
+	struct rw_semaphore unreg_sem;
+};
+
 static inline struct mdev_device *to_mdev_device(struct device *dev)
 {
 	return container_of(dev, struct mdev_device, dev);
@@ -75,8 +85,9 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
 
 extern struct bus_type mdev_bus_type;
 
-int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver);
-void mdev_unregister_device(struct device *dev);
+int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+		struct mdev_driver *mdev_driver);
+void mdev_unregister_parent(struct mdev_parent *parent);
 
 int mdev_register_driver(struct mdev_driver *drv);
 void mdev_unregister_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index d0d1bb7747240..30b3643b3b389 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -128,6 +128,7 @@ static dev_t		mbochs_devt;
 static struct class	*mbochs_class;
 static struct cdev	mbochs_cdev;
 static struct device	mbochs_dev;
+static struct mdev_parent mbochs_parent;
 static atomic_t mbochs_avail_mbytes;
 static const struct vfio_device_ops mbochs_dev_ops;
 
@@ -1456,7 +1457,7 @@ static int __init mbochs_dev_init(void)
 	if (ret)
 		goto err_class;
 
-	ret = mdev_register_device(&mbochs_dev, &mbochs_driver);
+	ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
 	if (ret)
 		goto err_device;
 
@@ -1477,7 +1478,7 @@ static int __init mbochs_dev_init(void)
 static void __exit mbochs_dev_exit(void)
 {
 	mbochs_dev.bus = NULL;
-	mdev_unregister_device(&mbochs_dev);
+	mdev_unregister_parent(&mbochs_parent);
 
 	device_unregister(&mbochs_dev);
 	mdev_unregister_driver(&mbochs_driver);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 0c4ca1f4be7ed..132bb055628a6 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -83,6 +83,7 @@ static dev_t		mdpy_devt;
 static struct class	*mdpy_class;
 static struct cdev	mdpy_cdev;
 static struct device	mdpy_dev;
+static struct mdev_parent mdpy_parent;
 static u32		mdpy_count;
 static const struct vfio_device_ops mdpy_dev_ops;
 
@@ -765,7 +766,7 @@ static int __init mdpy_dev_init(void)
 	if (ret)
 		goto err_class;
 
-	ret = mdev_register_device(&mdpy_dev, &mdpy_driver);
+	ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver);
 	if (ret)
 		goto err_device;
 
@@ -786,7 +787,7 @@ static int __init mdpy_dev_init(void)
 static void __exit mdpy_dev_exit(void)
 {
 	mdpy_dev.bus = NULL;
-	mdev_unregister_device(&mdpy_dev);
+	mdev_unregister_parent(&mdpy_parent);
 
 	device_unregister(&mdpy_dev);
 	mdev_unregister_driver(&mdpy_driver);
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 4f5a6f2d3629d..8ba5f6084a093 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -72,6 +72,7 @@ static struct mtty_dev {
 	struct cdev	vd_cdev;
 	struct idr	vd_idr;
 	struct device	dev;
+	struct mdev_parent parent;
 } mtty_dev;
 
 struct mdev_region_info {
@@ -1350,7 +1351,8 @@ static int __init mtty_dev_init(void)
 	if (ret)
 		goto err_class;
 
-	ret = mdev_register_device(&mtty_dev.dev, &mtty_driver);
+	ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
+				   &mtty_driver);
 	if (ret)
 		goto err_device;
 	return 0;
@@ -1370,7 +1372,7 @@ static int __init mtty_dev_init(void)
 static void __exit mtty_dev_exit(void)
 {
 	mtty_dev.dev.bus = NULL;
-	mdev_unregister_device(&mtty_dev.dev);
+	mdev_unregister_parent(&mtty_dev.parent);
 
 	device_unregister(&mtty_dev.dev);
 	idr_destroy(&mtty_dev.vd_idr);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
  2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14  6:14   ` Yi Liu
                     ` (3 more replies)
  2022-06-14  4:54 ` [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files Christoph Hellwig
                   ` (10 subsequent siblings)
  13 siblings, 4 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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
struture and thus significantly simplify the code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 .../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               |  18 ++-
 drivers/s390/cio/cio.h                        |   2 +
 drivers/s390/cio/vfio_ccw_ops.c               |  19 +--
 drivers/s390/crypto/vfio_ap_ops.c             |  19 +--
 drivers/s390/crypto/vfio_ap_private.h         |   2 +
 drivers/vfio/mdev/mdev_core.c                 |  54 ++++-----
 drivers/vfio/mdev/mdev_driver.c               |   5 +-
 drivers/vfio/mdev/mdev_private.h              |  14 +--
 drivers/vfio/mdev/mdev_sysfs.c                | 111 ++----------------
 include/linux/mdev.h                          |  26 ++--
 samples/vfio-mdev/mbochs.c                    |  57 ++++-----
 samples/vfio-mdev/mdpy.c                      |  50 +++-----
 samples/vfio-mdev/mtty.c                      |  62 +++++-----
 16 files changed, 181 insertions(+), 361 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 3749f59c855fa..599008bdc1dcb 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -105,7 +105,7 @@ structure to represent a mediated device's driver::
      struct mdev_driver {
 	     int  (*probe)  (struct mdev_device *dev);
 	     void (*remove) (struct mdev_device *dev);
-	     struct attribute_group **supported_type_groups;
+	     const struct attribute * const *types_attrs;
 	     struct device_driver    driver;
      };
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index ddffd337f1c60..0ccb9bb7180cd 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -298,7 +298,7 @@ struct intel_gvt_firmware {
 
 #define NR_MAX_INTEL_VGPU_TYPES 20
 struct intel_vgpu_type {
-	char name[16];
+	struct mdev_type type;
 	unsigned int avail_instance;
 	unsigned int low_gm_size;
 	unsigned int high_gm_size;
@@ -329,6 +329,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 70401374c72bc..1c6b7e8bec4fb 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -117,17 +117,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
 {
-	struct intel_vgpu_type *type;
-	unsigned int num = 0;
-	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
+	struct intel_vgpu_type *type =
+		container_of(mtype, struct intel_vgpu_type, type);
 
-	type = &gvt->types[mtype_get_type_group_id(mtype)];
-	if (!type)
-		num = 0;
-	else
-		num = type->avail_instance;
-
-	return sprintf(buf, "%u\n", num);
+	return sprintf(buf, "%u\n", type->avail_instance);
 }
 
 static ssize_t device_api_show(struct mdev_type *mtype,
@@ -139,12 +132,8 @@ static ssize_t device_api_show(struct mdev_type *mtype,
 static ssize_t description_show(struct mdev_type *mtype,
 				struct mdev_type_attribute *attr, char *buf)
 {
-	struct intel_vgpu_type *type;
-	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
-
-	type = &gvt->types[mtype_get_type_group_id(mtype)];
-	if (!type)
-		return 0;
+	struct intel_vgpu_type *type =
+		container_of(mtype, struct intel_vgpu_type, type);
 
 	return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
 		       "fence: %d\nresolution: %s\n"
@@ -158,14 +147,7 @@ static ssize_t description_show(struct mdev_type *mtype,
 static ssize_t name_show(struct mdev_type *mtype,
 			 struct mdev_type_attribute *attr, char *buf)
 {
-	struct intel_vgpu_type *type;
-	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
-
-	type = &gvt->types[mtype_get_type_group_id(mtype)];
-	if (!type)
-		return 0;
-
-	return sprintf(buf, "%s\n", type->name);
+	return sprintf(buf, "%s\n", mtype->sysfs_name);
 }
 
 static MDEV_TYPE_ATTR_RO(available_instances);
@@ -173,7 +155,7 @@ static MDEV_TYPE_ATTR_RO(device_api);
 static MDEV_TYPE_ATTR_RO(description);
 static MDEV_TYPE_ATTR_RO(name);
 
-static struct attribute *gvt_type_attrs[] = {
+static const struct attribute *gvt_type_attrs[] = {
 	&mdev_type_attr_available_instances.attr,
 	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_description.attr,
@@ -181,51 +163,6 @@ static struct attribute *gvt_type_attrs[] = {
 	NULL,
 };
 
-static struct attribute_group *gvt_vgpu_type_groups[] = {
-	[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
-};
-
-static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
-{
-	int i, j;
-	struct intel_vgpu_type *type;
-	struct attribute_group *group;
-
-	for (i = 0; i < gvt->num_types; i++) {
-		type = &gvt->types[i];
-
-		group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
-		if (!group)
-			goto unwind;
-
-		group->name = type->name;
-		group->attrs = gvt_type_attrs;
-		gvt_vgpu_type_groups[i] = group;
-	}
-
-	return 0;
-
-unwind:
-	for (j = 0; j < i; j++) {
-		group = gvt_vgpu_type_groups[j];
-		kfree(group);
-	}
-
-	return -ENOMEM;
-}
-
-static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
-{
-	int i;
-	struct attribute_group *group;
-
-	for (i = 0; i < gvt->num_types; i++) {
-		group = gvt_vgpu_type_groups[i];
-		gvt_vgpu_type_groups[i] = NULL;
-		kfree(group);
-	}
-}
-
 static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 		unsigned long size)
 {
@@ -1614,14 +1551,11 @@ static int intel_vgpu_probe(struct mdev_device *mdev)
 {
 	struct device *pdev = mdev_parent_dev(mdev);
 	struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
-	struct intel_vgpu_type *type;
+	struct intel_vgpu_type *type =
+		container_of(mdev->type, struct intel_vgpu_type, type);
 	struct intel_vgpu *vgpu;
 	int ret;
 
-	type = &gvt->types[mdev_get_type_group_id(mdev)];
-	if (!type)
-		return -EINVAL;
-
 	vgpu = intel_gvt_create_vgpu(gvt, type);
 	if (IS_ERR(vgpu)) {
 		gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
@@ -1660,7 +1594,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
 	},
 	.probe		= intel_vgpu_probe,
 	.remove		= intel_vgpu_remove,
-	.supported_type_groups	= gvt_vgpu_type_groups,
+	.types_attrs	= gvt_type_attrs,
 };
 
 int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
@@ -1959,7 +1893,6 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
 		return;
 
 	mdev_unregister_parent(&gvt->parent);
-	intel_gvt_cleanup_vgpu_type_groups(gvt);
 	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
 	intel_gvt_clean_vgpu_types(gvt);
 
@@ -2059,20 +1992,15 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
 
 	intel_gvt_debugfs_init(gvt);
 
-	ret = intel_gvt_init_vgpu_type_groups(gvt);
-	if (ret)
-		goto out_destroy_idle_vgpu;
-
 	ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
-				   &intel_vgpu_mdev_driver);
+				   &intel_vgpu_mdev_driver,
+				   gvt->mdev_types, gvt->num_types);
 	if (ret)
-		goto out_cleanup_vgpu_type_groups;
+		goto out_destroy_idle_vgpu;
 
 	gvt_dbg_core("gvt device initialization is done\n");
 	return 0;
 
-out_cleanup_vgpu_type_groups:
-	intel_gvt_cleanup_vgpu_type_groups(gvt);
 out_destroy_idle_vgpu:
 	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
 	intel_gvt_debugfs_clean(gvt);
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 46da19b3225d2..2f38b90ecb8ac 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -131,6 +131,13 @@ 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) {
+		kfree(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)
@@ -150,19 +157,21 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
 						   high_avail / vgpu_types[i].high_mm);
 
 		if (GRAPHICS_VER(gvt->gt->i915) == 8)
-			sprintf(gvt->types[i].name, "GVTg_V4_%s",
+			sprintf(gvt->types[i].type.sysfs_name, "GVTg_V4_%s",
 				vgpu_types[i].name);
 		else if (GRAPHICS_VER(gvt->gt->i915) == 9)
-			sprintf(gvt->types[i].name, "GVTg_V5_%s",
+			sprintf(gvt->types[i].type.sysfs_name, "GVTg_V5_%s",
 				vgpu_types[i].name);
 
 		gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
-			     i, gvt->types[i].name,
+			     i, gvt->types[i].type.sysfs_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));
+
+		gvt->mdev_types[i] = &gvt->types[i].type;
 	}
 
 	gvt->num_types = i;
@@ -171,6 +180,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);
 }
 
@@ -198,7 +208,7 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
 						   fence_min);
 
 		gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
-		       i, gvt->types[i].name,
+		       i, gvt->types[i].type.sysfs_name,
 		       gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
 		       gvt->types[i].high_gm_size, gvt->types[i].fence);
 	}
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 22be5ac7d23c1..1da45307a1862 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -110,6 +110,8 @@ struct subchannel {
 	 */
 	const char *driver_override;
 	struct mdev_parent parent;
+	struct mdev_type mdev_type;
+	struct mdev_type *mdev_types[1];
 } __attribute__ ((aligned(8)));
 
 DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 9192a21085ce4..25b8d42a522ac 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -95,23 +95,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 }
 static MDEV_TYPE_ATTR_RO(available_instances);
 
-static struct attribute *mdev_types_attrs[] = {
+static const struct attribute *mdev_types_attrs[] = {
 	&mdev_type_attr_name.attr,
 	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
 
-static struct attribute_group mdev_type_group = {
-	.name  = "io",
-	.attrs = mdev_types_attrs,
-};
-
-static struct attribute_group *mdev_type_groups[] = {
-	&mdev_type_group,
-	NULL,
-};
-
 static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 {
 	struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
@@ -654,13 +644,16 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 	},
 	.probe = vfio_ccw_mdev_probe,
 	.remove = vfio_ccw_mdev_remove,
-	.supported_type_groups  = mdev_type_groups,
+	.types_attrs = mdev_types_attrs,
 };
 
 int vfio_ccw_mdev_reg(struct subchannel *sch)
 {
+	sprintf(sch->mdev_type.sysfs_name, "io");
+	sch->mdev_types[0] = &sch->mdev_type;
 	return mdev_register_parent(&sch->parent, &sch->dev,
-				    &vfio_ccw_mdev_driver);
+				    &vfio_ccw_mdev_driver, sch->mdev_types,
+				    1);
 }
 
 void vfio_ccw_mdev_unreg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 834945150dc9f..ff25858b2ebbe 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -537,23 +537,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
 
 static MDEV_TYPE_ATTR_RO(device_api);
 
-static struct attribute *vfio_ap_mdev_type_attrs[] = {
+static const struct attribute *vfio_ap_mdev_type_attrs[] = {
 	&mdev_type_attr_name.attr,
 	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
 
-static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
-	.name = VFIO_AP_MDEV_TYPE_HWVIRT,
-	.attrs = vfio_ap_mdev_type_attrs,
-};
-
-static struct attribute_group *vfio_ap_mdev_type_groups[] = {
-	&vfio_ap_mdev_hwvirt_type_group,
-	NULL,
-};
-
 struct vfio_ap_queue_reserved {
 	unsigned long *apid;
 	unsigned long *apqi;
@@ -1472,7 +1462,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
 	},
 	.probe = vfio_ap_mdev_probe,
 	.remove = vfio_ap_mdev_remove,
-	.supported_type_groups = vfio_ap_mdev_type_groups,
+	.types_attrs = vfio_ap_mdev_type_attrs,
 };
 
 int vfio_ap_mdev_register(void)
@@ -1485,8 +1475,11 @@ int vfio_ap_mdev_register(void)
 	if (ret)
 		return ret;
 
+	strcpy(matrix_dev->mdev_type.sysfs_name, VFIO_AP_MDEV_TYPE_HWVIRT);
+	matrix_dev->mdev_types[0] = &matrix_dev->mdev_type;
 	ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
-				   &vfio_ap_matrix_driver);
+				   &vfio_ap_matrix_driver,
+				   matrix_dev->mdev_types, 1);
 	if (ret)
 		goto err_driver;
 	return 0;
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 0191f6bc973a4..5dc5050d03791 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -46,6 +46,8 @@ struct ap_matrix_dev {
 	struct mutex lock;
 	struct ap_driver  *vfio_ap_drv;
 	struct mdev_parent parent;
+	struct mdev_type mdev_type;
+	struct mdev_type *mdev_types[];
 };
 
 extern struct ap_matrix_dev *matrix_dev;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index d38faed14c689..71c7f4e521a74 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,19 +65,19 @@ 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
  *
  * 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;
+	int i;
 
 	memset(parent, 0, sizeof(*parent));
 	init_rwsem(&parent->unreg_sem);
@@ -110,9 +90,23 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
 			return -ENOMEM;
 	}
 
-	ret = parent_create_sysfs_files(parent);
-	if (ret)
+	parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
+					       NULL, &parent->dev->kobj);
+	if (!parent->mdev_types_kset)
+		return -ENOMEM;
+
+	for (i = 0; i < nr_types; i++) {
+		ret = mdev_type_add(parent, types[i]);
+		if (ret)
+			break;
+	}
+	parent->types = types;
+	parent->nr_types = i;
+
+	if (ret) {
+		mdev_unregister_parent(parent);
 		return ret;
+	}
 
 	ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
 	if (ret)
@@ -132,13 +126,17 @@ void mdev_unregister_parent(struct mdev_parent *parent)
 {
 	char *env_string = "MDEV_STATE=unregistered";
 	char *envp[] = { env_string, NULL };
+	int i;
 
 	dev_info(parent->dev, "MDEV: Unregistering\n");
 
+	for (i = 0; i < parent->nr_types; i++)
+		mdev_type_remove(parent->types[i]);
+									  
 	down_write(&parent->unreg_sem);
 	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);
+	kset_unregister(parent->mdev_types_kset);
 	up_write(&parent->unreg_sem);
 
 	kobject_uevent_env(&parent->dev->kobj, KOBJ_CHANGE, envp);
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..6980f504018f3 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)	\
@@ -28,12 +20,12 @@ extern const struct attribute_group *mdev_device_groups[];
 #define to_mdev_type(_kobj)		\
 	container_of(_kobj, struct mdev_type, kobj)
 
-int  parent_create_sysfs_files(struct mdev_parent *parent);
-void parent_remove_sysfs_files(struct mdev_parent *parent);
-
 int  mdev_create_sysfs_files(struct mdev_device *mdev);
 void mdev_remove_sysfs_files(struct mdev_device *mdev);
 
+int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type);
+void mdev_type_remove(struct mdev_type *type);
+
 int mdev_device_create(struct mdev_type *kobj, const guid_t *uuid);
 int  mdev_device_remove(struct mdev_device *dev);
 
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index b71ffc5594870..09745e8e120f9 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -80,8 +80,6 @@ static void mdev_type_release(struct kobject *kobj)
 	struct mdev_type *type = to_mdev_type(kobj);
 
 	pr_debug("Releasing group %s\n", kobj->name);
-	/* Pairs with the get in add_mdev_supported_type() */
-	put_device(type->parent->dev);
 	kfree(type);
 }
 
@@ -90,36 +88,17 @@ 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)
+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);
-	if (ret) {
-		kobject_put(&type->kobj);
-		return ERR_PTR(ret);
-	}
+	type->kobj.kset = parent->mdev_types_kset;
+	ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL, "%s-%s",
+				   dev_driver_string(parent->dev),
+				   type->sysfs_name);
+	if (ret)
+		return ret;
 
 	ret = sysfs_create_file(&type->kobj, &mdev_type_attr_create.attr);
 	if (ret)
@@ -131,13 +110,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,80 +122,19 @@ 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)
+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(&ltype->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);
-	}
-
-	kset_unregister(parent->mdev_types_kset);
-}
-
-int parent_create_sysfs_files(struct mdev_parent *parent)
-{
-	int ret;
-
-	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;
-	return 0;
-
-create_err:
-	kset_unregister(parent->mdev_types_kset);
-	return ret;
-}
-
 static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 {
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 327ce3e5c6b5f..d28ddf0f561a0 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: */
+	char sysfs_name[32];
+
+	/* set by the core, can be used drivers */
+	struct mdev_parent *parent;
+
+	/* internal only */
+	struct kobject kobj;
+	struct kobject *devices_kobj;
+};
+
 /* embedded into the struct device that the mdev devices hang off */
 struct mdev_parent {
 	struct device *dev;
 	struct mdev_driver *mdev_driver;
 	struct kset *mdev_types_kset;
-	struct list_head type_list;
 	/* Synchronize device creation/removal with parent unregistration */
 	struct rw_semaphore unreg_sem;
+	struct mdev_type **types;
+	unsigned int nr_types;
 };
 
 static inline struct mdev_device *to_mdev_device(struct device *dev)
@@ -38,8 +51,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
 	return container_of(dev, struct mdev_device, dev);
 }
 
-unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
-unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
 struct device *mtype_get_parent_dev(struct mdev_type *mtype);
 
 /* interface for exporting mdev supported type attributes */
@@ -66,15 +77,13 @@ struct mdev_type_attribute mdev_type_attr_##_name =		\
  * struct mdev_driver - Mediated device driver
  * @probe: called when new device created
  * @remove: called when device removed
- * @supported_type_groups: Attributes to define supported types. It is mandatory
- *			to provide supported types.
+ * @types_attrs: attributes to the type kobjects.
  * @driver: device driver structure
- *
  **/
 struct mdev_driver {
 	int (*probe)(struct mdev_device *dev);
 	void (*remove)(struct mdev_device *dev);
-	struct attribute_group **supported_type_groups;
+	const struct attribute * const *types_attrs;
 	struct device_driver driver;
 };
 
@@ -86,7 +95,8 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
 extern struct bus_type mdev_bus_type;
 
 int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
-		struct mdev_driver *mdev_driver);
+		struct mdev_driver *mdev_driver, struct mdev_type **types,
+		unsigned int nr_types);
 void mdev_unregister_parent(struct mdev_parent *parent);
 
 int mdev_register_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 30b3643b3b389..1069f561cb012 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -99,23 +99,27 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
 #define MBOCHS_TYPE_2 "medium"
 #define MBOCHS_TYPE_3 "large"
 
-static const struct mbochs_type {
+static struct mbochs_type {
+	struct mdev_type type;
 	const char *name;
 	u32 mbytes;
 	u32 max_x;
 	u32 max_y;
 } mbochs_types[] = {
 	{
+		.type.sysfs_name	= MBOCHS_TYPE_1,
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
 		.mbytes = 4,
 		.max_x  = 800,
 		.max_y  = 600,
 	}, {
+		.type.sysfs_name	= MBOCHS_TYPE_2,
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
 		.mbytes = 16,
 		.max_x  = 1920,
 		.max_y  = 1440,
 	}, {
+		.type.sysfs_name	= MBOCHS_TYPE_3,
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
 		.mbytes = 64,
 		.max_x  = 0,
@@ -123,6 +127,11 @@ static const struct mbochs_type {
 	},
 };
 
+static struct mdev_type *mbochs_mdev_types[] = {
+	&mbochs_types[0].type,
+	&mbochs_types[1].type,
+	&mbochs_types[2].type,
+};
 
 static dev_t		mbochs_devt;
 static struct class	*mbochs_class;
@@ -508,8 +517,8 @@ static int mbochs_reset(struct mdev_state *mdev_state)
 static int mbochs_probe(struct mdev_device *mdev)
 {
 	int avail_mbytes = atomic_read(&mbochs_avail_mbytes);
-	const struct mbochs_type *type =
-		&mbochs_types[mdev_get_type_group_id(mdev)];
+	struct mbochs_type *type =
+		container_of(mdev->type, struct mbochs_type, type);
 	struct device *dev = mdev_dev(mdev);
 	struct mdev_state *mdev_state;
 	int ret = -ENOMEM;
@@ -1328,8 +1337,8 @@ static const struct attribute_group *mdev_dev_groups[] = {
 static ssize_t name_show(struct mdev_type *mtype,
 			 struct mdev_type_attribute *attr, char *buf)
 {
-	const struct mbochs_type *type =
-		&mbochs_types[mtype_get_type_group_id(mtype)];
+	struct mbochs_type *type =
+		container_of(mtype, struct mbochs_type, type);
 
 	return sprintf(buf, "%s\n", type->name);
 }
@@ -1338,8 +1347,8 @@ static MDEV_TYPE_ATTR_RO(name);
 static ssize_t description_show(struct mdev_type *mtype,
 				struct mdev_type_attribute *attr, char *buf)
 {
-	const struct mbochs_type *type =
-		&mbochs_types[mtype_get_type_group_id(mtype)];
+	struct mbochs_type *type =
+		container_of(mtype, struct mbochs_type, type);
 
 	return sprintf(buf, "virtual display, %d MB video memory\n",
 		       type ? type->mbytes  : 0);
@@ -1350,8 +1359,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
 {
-	const struct mbochs_type *type =
-		&mbochs_types[mtype_get_type_group_id(mtype)];
+	struct mbochs_type *type =
+		container_of(mtype, struct mbochs_type, type);
 	int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes;
 
 	return sprintf(buf, "%d\n", count);
@@ -1365,7 +1374,7 @@ static ssize_t device_api_show(struct mdev_type *mtype,
 }
 static MDEV_TYPE_ATTR_RO(device_api);
 
-static struct attribute *mdev_types_attrs[] = {
+static const struct attribute *mdev_types_attrs[] = {
 	&mdev_type_attr_name.attr,
 	&mdev_type_attr_description.attr,
 	&mdev_type_attr_device_api.attr,
@@ -1373,28 +1382,6 @@ static struct attribute *mdev_types_attrs[] = {
 	NULL,
 };
 
-static struct attribute_group mdev_type_group1 = {
-	.name  = MBOCHS_TYPE_1,
-	.attrs = mdev_types_attrs,
-};
-
-static struct attribute_group mdev_type_group2 = {
-	.name  = MBOCHS_TYPE_2,
-	.attrs = mdev_types_attrs,
-};
-
-static struct attribute_group mdev_type_group3 = {
-	.name  = MBOCHS_TYPE_3,
-	.attrs = mdev_types_attrs,
-};
-
-static struct attribute_group *mdev_type_groups[] = {
-	&mdev_type_group1,
-	&mdev_type_group2,
-	&mdev_type_group3,
-	NULL,
-};
-
 static const struct vfio_device_ops mbochs_dev_ops = {
 	.close_device = mbochs_close_device,
 	.read = mbochs_read,
@@ -1412,7 +1399,7 @@ static struct mdev_driver mbochs_driver = {
 	},
 	.probe = mbochs_probe,
 	.remove	= mbochs_remove,
-	.supported_type_groups = mdev_type_groups,
+	.types_attrs = mdev_types_attrs,
 };
 
 static const struct file_operations vd_fops = {
@@ -1457,7 +1444,9 @@ static int __init mbochs_dev_init(void)
 	if (ret)
 		goto err_class;
 
-	ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
+	ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver,
+				   mbochs_mdev_types,
+				   ARRAY_SIZE(mbochs_mdev_types));
 	if (ret)
 		goto err_device;
 
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 132bb055628a6..40b1c8a58157c 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,
@@ -78,6 +82,12 @@ static const struct mdpy_type {
 		.height = 1080,
 	},
 };
+	
+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;
@@ -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] 59+ messages in thread

* [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:03   ` Kirti Wankhede
  2022-06-14  4:54 ` [PATCH 05/13] vfio/mdev: remove mdev_from_dev Christoph Hellwig
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian

Just fold these two trivial helpers into their only callers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
 drivers/vfio/mdev/mdev_core.c    | 12 ++++++++++--
 drivers/vfio/mdev/mdev_private.h |  3 ---
 drivers/vfio/mdev/mdev_sysfs.c   | 28 ----------------------------
 3 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 71c7f4e521a74..fe4230b21993d 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -44,7 +44,8 @@ static void mdev_device_remove_common(struct mdev_device *mdev)
 {
 	struct mdev_parent *parent = mdev->type->parent;
 
-	mdev_remove_sysfs_files(mdev);
+	sysfs_remove_link(&mdev->dev.kobj, "mdev_type");
+	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
 	device_del(&mdev->dev);
 	lockdep_assert_held(&parent->unreg_sem);
 	/* Balances with device_initialize() */
@@ -212,16 +213,23 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
 	if (ret)
 		goto out_del;
 
-	ret = mdev_create_sysfs_files(mdev);
+	ret = sysfs_create_link(type->devices_kobj, &mdev->dev.kobj,
+				dev_name(&mdev->dev));
 	if (ret)
 		goto out_del;
 
+	ret = sysfs_create_link(&mdev->dev.kobj, &type->kobj, "mdev_type");
+	if (ret)
+		goto out_remove_type_link;
+
 	mdev->active = true;
 	dev_dbg(&mdev->dev, "MDEV: created\n");
 	up_read(&parent->unreg_sem);
 
 	return 0;
 
+out_remove_type_link:
+	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
 out_del:
 	device_del(&mdev->dev);
 out_unlock:
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index 6980f504018f3..346b9ec320466 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -20,9 +20,6 @@ extern const struct attribute_group *mdev_device_groups[];
 #define to_mdev_type(_kobj)		\
 	container_of(_kobj, struct mdev_type, kobj)
 
-int  mdev_create_sysfs_files(struct mdev_device *mdev);
-void mdev_remove_sysfs_files(struct mdev_device *mdev);
-
 int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type);
 void mdev_type_remove(struct mdev_type *type);
 
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 09745e8e120f9..dd81b91afcf7d 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -170,31 +170,3 @@ const struct attribute_group *mdev_device_groups[] = {
 	&mdev_device_group,
 	NULL
 };
-
-int mdev_create_sysfs_files(struct mdev_device *mdev)
-{
-	struct mdev_type *type = mdev->type;
-	struct kobject *kobj = &mdev->dev.kobj;
-	int ret;
-
-	ret = sysfs_create_link(type->devices_kobj, kobj, dev_name(&mdev->dev));
-	if (ret)
-		return ret;
-
-	ret = sysfs_create_link(kobj, &type->kobj, "mdev_type");
-	if (ret)
-		goto type_link_failed;
-	return ret;
-
-type_link_failed:
-	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
-	return ret;
-}
-
-void mdev_remove_sysfs_files(struct mdev_device *mdev)
-{
-	struct kobject *kobj = &mdev->dev.kobj;
-
-	sysfs_remove_link(kobj, "mdev_type");
-	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
-}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 05/13] vfio/mdev: remove mdev_from_dev
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:06   ` Kirti Wankhede
  2022-06-14  4:54 ` [PATCH 06/13] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, 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>
---
 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 fe4230b21993d..49a4a26787ce6 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -54,10 +54,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 d28ddf0f561a0..409e86d343a05 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -107,9 +107,5 @@ static inline struct device *mdev_dev(struct mdev_device *mdev)
 {
 	return &mdev->dev;
 }
-static inline struct mdev_device *mdev_from_dev(struct device *dev)
-{
-	return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL;
-}
 
 #endif /* MDEV_H */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 06/13] vfio/mdev: unexport mdev_bus_type
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 05/13] vfio/mdev: remove mdev_from_dev Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:08   ` Kirti Wankhede
  2022-06-14  4:54 ` [PATCH 07/13] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, 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>
---
 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 346b9ec320466..62a98b78d929d 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 409e86d343a05..dd11c142bf887 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -92,8 +92,6 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
 	return &mdev->uuid;
 }
 
-extern struct bus_type mdev_bus_type;
-
 int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
 		struct mdev_driver *mdev_driver, struct mdev_type **types,
 		unsigned int nr_types);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 07/13] vfio/mdev: remove mdev_parent_dev
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 06/13] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:11   ` Kirti Wankhede
  2022-06-14  4:54 ` [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, 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>
---
 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 599008bdc1dcb..27247b3bdcb57 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -202,9 +202,6 @@ Directories and files under the sysfs for Each Physical Device
 
 	sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
 
-  (or using mdev_parent_dev(mdev) to arrive at the parent device outside
-  of the core mdev code)
-
 * device_api
 
   This attribute should show which device API is being created, for example,
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1c6b7e8bec4fb..136f9c0df48b9 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1549,7 +1549,7 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
 
 static int intel_vgpu_probe(struct mdev_device *mdev)
 {
-	struct device *pdev = mdev_parent_dev(mdev);
+	struct device *pdev = mdev->type->parent->dev;
 	struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
 	struct intel_vgpu_type *type =
 		container_of(mdev->type, struct intel_vgpu_type, type);
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 49a4a26787ce6..479ae5ed6c392 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 dd11c142bf887..83c85a0247f25 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -100,7 +100,6 @@ void mdev_unregister_parent(struct mdev_parent *parent);
 int mdev_register_driver(struct mdev_driver *drv);
 void mdev_unregister_driver(struct mdev_driver *drv);
 
-struct device *mdev_parent_dev(struct mdev_device *mdev);
 static inline struct device *mdev_dev(struct mdev_device *mdev)
 {
 	return &mdev->dev;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 07/13] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:13   ` Kirti Wankhede
  2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, 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>
---
 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 25b8d42a522ac..43d53736dfe3c 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -88,8 +88,7 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
 {
-	struct vfio_ccw_private *private =
-		dev_get_drvdata(mtype_get_parent_dev(mtype));
+	struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
 
 	return sprintf(buf, "%d\n", atomic_read(&private->avail));
 }
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 479ae5ed6c392..20513b7f6b5eb 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 83c85a0247f25..ecf964d34f2ca 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] 59+ messages in thread

* [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14 10:10   ` Tian, Kevin
                     ` (2 more replies)
  2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
                   ` (4 subsequent siblings)
  13 siblings, 3 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe

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>
---
 .../driver-api/vfio-mediated-device.rst       |  2 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c              |  9 +----
 drivers/s390/cio/vfio_ccw_ops.c               | 11 ++----
 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, 38 insertions(+), 68 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 27247b3bdcb57..e9913bfb4393b 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -204,7 +204,7 @@ Directories and files under the sysfs for Each Physical Device
 
 * device_api
 
-  This attribute should show which device API is being created, for example,
+  This attribute shows which device API is being created, for example,
   "vfio-pci" for a PCI device.
 
 * available_instances
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 136f9c0df48b9..44a418d897377 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -123,12 +123,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 	return sprintf(buf, "%u\n", type->avail_instance);
 }
 
-static ssize_t device_api_show(struct mdev_type *mtype,
-			       struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
-}
-
 static ssize_t description_show(struct mdev_type *mtype,
 				struct mdev_type_attribute *attr, char *buf)
 {
@@ -151,13 +145,11 @@ static ssize_t name_show(struct mdev_type *mtype,
 }
 
 static MDEV_TYPE_ATTR_RO(available_instances);
-static MDEV_TYPE_ATTR_RO(device_api);
 static MDEV_TYPE_ATTR_RO(description);
 static MDEV_TYPE_ATTR_RO(name);
 
 static const struct attribute *gvt_type_attrs[] = {
 	&mdev_type_attr_available_instances.attr,
-	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_description.attr,
 	&mdev_type_attr_name.attr,
 	NULL,
@@ -1587,6 +1579,7 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
 }
 
 static struct mdev_driver intel_vgpu_mdev_driver = {
+	.device_api	= VFIO_DEVICE_API_PCI_STRING,
 	.driver = {
 		.name		= "intel_vgpu_mdev",
 		.owner		= THIS_MODULE,
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 43d53736dfe3c..730d87a96a305 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -77,13 +77,6 @@ static ssize_t name_show(struct mdev_type *mtype,
 }
 static MDEV_TYPE_ATTR_RO(name);
 
-static ssize_t device_api_show(struct mdev_type *mtype,
-			       struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
-}
-static MDEV_TYPE_ATTR_RO(device_api);
-
 static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
@@ -96,7 +89,6 @@ static MDEV_TYPE_ATTR_RO(available_instances);
 
 static const struct attribute *mdev_types_attrs[] = {
 	&mdev_type_attr_name.attr,
-	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
@@ -636,6 +628,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
 };
 
 struct mdev_driver vfio_ccw_mdev_driver = {
+	.device_api = VFIO_DEVICE_API_CCW_STRING,
 	.driver = {
 		.name = "vfio_ccw_mdev",
 		.owner = THIS_MODULE,
@@ -648,7 +641,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 
 int vfio_ccw_mdev_reg(struct subchannel *sch)
 {
-	sprintf(sch->mdev_type.sysfs_name, "io");
+	strcat(sch->mdev_type.sysfs_name, "io");
 	sch->mdev_types[0] = &sch->mdev_type;
 	return mdev_register_parent(&sch->parent, &sch->dev,
 				    &vfio_ccw_mdev_driver, sch->mdev_types,
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index ff25858b2ebbe..da21fd60877fb 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -529,17 +529,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 
 static MDEV_TYPE_ATTR_RO(available_instances);
 
-static ssize_t device_api_show(struct mdev_type *mtype,
-			       struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%s\n", VFIO_DEVICE_API_AP_STRING);
-}
-
-static MDEV_TYPE_ATTR_RO(device_api);
-
 static const struct attribute *vfio_ap_mdev_type_attrs[] = {
 	&mdev_type_attr_name.attr,
-	&mdev_type_attr_device_api.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
@@ -1454,6 +1445,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
 };
 
 static struct mdev_driver vfio_ap_matrix_driver = {
+	.device_api = VFIO_DEVICE_API_AP_STRING,
 	.driver = {
 		.name = "vfio_ap_mdev",
 		.owner = THIS_MODULE,
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 5b3c94f4fb13d..60e8b9f6474e8 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -55,8 +55,10 @@ struct bus_type mdev_bus_type = {
  **/
 int mdev_register_driver(struct mdev_driver *drv)
 {
-	if (!drv->types_attrs)
+	if (!drv->types_attrs || !drv->device_api)
 		return -EINVAL;
+
+	/* initialize common driver fields */
 	drv->driver.bus = &mdev_bus_type;
 	return driver_register(&drv->driver);
 }
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index dd81b91afcf7d..20763f1aa9f5a 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);
@@ -84,8 +105,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,
 };
 
 int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
@@ -100,10 +122,6 @@ int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
 	if (ret)
 		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;
@@ -118,8 +136,6 @@ 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;
@@ -130,7 +146,6 @@ 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 ecf964d34f2ca..81e11e18b3e41 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 40b1c8a58157c..401a9a622673c 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] 59+ messages in thread

* [PATCH 10/13] vfio/mdev: consolidate all the name sysfs into the core code
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14 10:11   ` Tian, Kevin
                     ` (2 more replies)
  2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
                   ` (3 subsequent siblings)
  13 siblings, 3 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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>
---
 .../driver-api/vfio-mediated-device.rst       |  2 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c              |  8 -------
 drivers/s390/cio/vfio_ccw_ops.c               |  9 +-------
 drivers/s390/crypto/vfio_ap_ops.c             |  9 --------
 drivers/vfio/mdev/mdev_sysfs.c                | 11 ++++++++++
 include/linux/mdev.h                          |  1 +
 samples/vfio-mdev/mbochs.c                    | 20 ++++--------------
 samples/vfio-mdev/mdpy.c                      | 21 +++++--------------
 samples/vfio-mdev/mtty.c                      | 18 ++++------------
 9 files changed, 27 insertions(+), 72 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index e9913bfb4393b..87d207744db79 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -219,7 +219,7 @@ Directories and files under the sysfs for Each Physical Device
 
 * name
 
-  This attribute should show human readable name. This is optional attribute.
+  This attribute shows a human readable name.
 
 * description
 
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 44a418d897377..191e64ef70acf 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->weight);
 }
 
-static ssize_t name_show(struct mdev_type *mtype,
-			 struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%s\n", mtype->sysfs_name);
-}
-
 static MDEV_TYPE_ATTR_RO(available_instances);
 static MDEV_TYPE_ATTR_RO(description);
-static MDEV_TYPE_ATTR_RO(name);
 
 static const struct attribute *gvt_type_attrs[] = {
 	&mdev_type_attr_available_instances.attr,
 	&mdev_type_attr_description.attr,
-	&mdev_type_attr_name.attr,
 	NULL,
 };
 
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 730d87a96a305..35389f4b67dc5 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,13 +70,6 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static ssize_t name_show(struct mdev_type *mtype,
-			 struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
-}
-static MDEV_TYPE_ATTR_RO(name);
-
 static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
@@ -88,7 +81,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 static MDEV_TYPE_ATTR_RO(available_instances);
 
 static const struct attribute *mdev_types_attrs[] = {
-	&mdev_type_attr_name.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
@@ -642,6 +634,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 int vfio_ccw_mdev_reg(struct subchannel *sch)
 {
 	strcat(sch->mdev_type.sysfs_name, "io");
+	strcat(sch->mdev_type.pretty_name, "I/O subchannel (Non-QDIO)");
 	sch->mdev_types[0] = &sch->mdev_type;
 	return mdev_register_parent(&sch->parent, &sch->dev,
 				    &vfio_ccw_mdev_driver, sch->mdev_types,
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index da21fd60877fb..d6b2e819a615e 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -511,14 +511,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
 	atomic_inc(&matrix_dev->available_instances);
 }
 
-static ssize_t name_show(struct mdev_type *mtype,
-			 struct mdev_type_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%s\n", VFIO_AP_MDEV_NAME_HWVIRT);
-}
-
-static MDEV_TYPE_ATTR_RO(name);
-
 static ssize_t available_instances_show(struct mdev_type *mtype,
 					struct mdev_type_attribute *attr,
 					char *buf)
@@ -530,7 +522,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
 static MDEV_TYPE_ATTR_RO(available_instances);
 
 static const struct attribute *vfio_ap_mdev_type_attrs[] = {
-	&mdev_type_attr_name.attr,
 	&mdev_type_attr_available_instances.attr,
 	NULL,
 };
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 20763f1aa9f5a..8384e2992c706 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -81,9 +81,20 @@ 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)
+{
+	if (!mtype->pretty_name[0])
+		return sprintf(buf, "%s\n", mtype->sysfs_name);
+	return sprintf(buf, "%s\n", mtype->pretty_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 81e11e18b3e41..64ca2ba806ed3 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: */
 	char sysfs_name[32];
+	char pretty_name[32]; /* optional */
 
 	/* 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 401a9a622673c..1b2117772192f 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] 59+ messages in thread

* [PATCH 11/13] vfio/mdev: consolidate all the available_instance sysfs into the core code
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14 10:14   ` Tian, Kevin
                     ` (2 more replies)
  2022-06-14  4:54 ` [PATCH 12/13] vfio/mdev: consolidate all the description " Christoph Hellwig
                   ` (2 subsequent siblings)
  13 siblings, 3 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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>
---
 .../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               | 44 ++-----------------
 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(+), 105 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 87d207744db79..96b789f569c5a 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
      struct mdev_driver {
 	     int  (*probe)  (struct mdev_device *dev);
 	     void (*remove) (struct mdev_device *dev);
+	     unsigned int (*get_available)(struct mdev_type *mtype);
 	     const struct attribute * const *types_attrs;
 	     struct device_driver    driver;
      };
@@ -209,7 +210,7 @@ Directories and files under the sysfs for Each Physical Device
 
 * available_instances
 
-  This attribute should show the number of devices of type <type-id> that can be
+  This attribute shows the number of devices of type <type-id> that can be
   created.
 
 * [device]
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 0ccb9bb7180cd..91d1da18bdf40 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -299,7 +299,6 @@ struct intel_gvt_firmware {
 #define NR_MAX_INTEL_VGPU_TYPES 20
 struct intel_vgpu_type {
 	struct mdev_type type;
-	unsigned int avail_instance;
 	unsigned int low_gm_size;
 	unsigned int high_gm_size;
 	unsigned int fence;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 191e64ef70acf..0e14bf94534c4 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->weight);
 }
 
-static MDEV_TYPE_ATTR_RO(available_instances);
 static MDEV_TYPE_ATTR_RO(description);
 
 static const struct attribute *gvt_type_attrs[] = {
-	&mdev_type_attr_available_instances.attr,
 	&mdev_type_attr_description.attr,
 	NULL,
 };
@@ -1570,6 +1558,27 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
 	intel_gvt_destroy_vgpu(vgpu);
 }
 
+static unsigned int intel_vgpu_get_available(struct mdev_type *mtype)
+{
+	struct intel_vgpu_type *type =
+		container_of(mtype, struct intel_vgpu_type, type);
+	struct intel_gvt *gvt = kdev_to_i915(mtype->parent->dev)->gvt;
+	unsigned int low_gm_avail, high_gm_avail, fence_avail;
+
+	mutex_lock(&gvt->lock);
+	low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE -
+		gvt->gm.vgpu_allocated_low_gm_size;
+	high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE -
+		gvt->gm.vgpu_allocated_high_gm_size;
+	fence_avail = gvt_fence_sz(gvt) - HOST_FENCE -
+		gvt->fence.vgpu_allocated_fence_num;
+	mutex_unlock(&gvt->lock);
+
+	return min3(low_gm_avail / type->low_gm_size,
+		    high_gm_avail / type->high_gm_size,
+		    fence_avail / type->fence);
+}
+
 static struct mdev_driver intel_vgpu_mdev_driver = {
 	.device_api	= VFIO_DEVICE_API_PCI_STRING,
 	.driver = {
@@ -1579,6 +1588,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
 	},
 	.probe		= intel_vgpu_probe,
 	.remove		= intel_vgpu_remove,
+	.get_available	= intel_vgpu_get_available,
 	.types_attrs	= gvt_type_attrs,
 };
 
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 2f38b90ecb8ac..dc9f6b4d11e5d 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -153,8 +153,6 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
 
 		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].type.sysfs_name, "GVTg_V4_%s",
@@ -165,7 +163,8 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
 
 		gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
 			     i, gvt->types[i].type.sysfs_name,
-			     gvt->types[i].avail_instance,
+			     min(low_avail / vgpu_types[i].low_mm,
+				 high_avail / vgpu_types[i].high_mm),
 			     gvt->types[i].low_gm_size,
 			     gvt->types[i].high_gm_size, gvt->types[i].fence,
 			     gvt->types[i].weight,
@@ -184,36 +183,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].low_gm_size;
-		high_gm_min = high_gm_avail / gvt->types[i].high_gm_size;
-		fence_min = fence_avail / gvt->types[i].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].type.sysfs_name,
-		       gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
-		       gvt->types[i].high_gm_size, gvt->types[i].fence);
-	}
-}
-
 /**
  * intel_gvt_active_vgpu - activate a virtual GPU
  * @vgpu: virtual GPU
@@ -309,10 +278,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);
 }
 
@@ -499,11 +464,8 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt,
 
 	mutex_lock(&gvt->lock);
 	vgpu = __intel_gvt_create_vgpu(gvt, &param);
-	if (!IS_ERR(vgpu)) {
-		/* calculate left instance change for types */
-		intel_gvt_update_vgpu_types(gvt);
+	if (!IS_ERR(vgpu))
 		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 35389f4b67dc5..94cc62b808088 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,20 +70,12 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static ssize_t available_instances_show(struct mdev_type *mtype,
-					struct mdev_type_attribute *attr,
-					char *buf)
+static unsigned int vfio_ccw_get_available(struct mdev_type *mtype)
 {
 	struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
 
-	return sprintf(buf, "%d\n", atomic_read(&private->avail));
+	return atomic_read(&private->avail);
 }
-static MDEV_TYPE_ATTR_RO(available_instances);
-
-static const struct attribute *mdev_types_attrs[] = {
-	&mdev_type_attr_available_instances.attr,
-	NULL,
-};
 
 static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 {
@@ -628,7 +620,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 	},
 	.probe = vfio_ccw_mdev_probe,
 	.remove = vfio_ccw_mdev_remove,
-	.types_attrs = mdev_types_attrs,
+	.get_available = vfio_ccw_get_available,
 };
 
 int vfio_ccw_mdev_reg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index d6b2e819a615e..5e6cc43413117 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -511,21 +511,11 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
 	atomic_inc(&matrix_dev->available_instances);
 }
 
-static ssize_t available_instances_show(struct mdev_type *mtype,
-					struct mdev_type_attribute *attr,
-					char *buf)
+static unsigned int vfio_ap_mdev_get_available(struct mdev_type *mtype)
 {
-	return sprintf(buf, "%d\n",
-		       atomic_read(&matrix_dev->available_instances));
+	return atomic_read(&matrix_dev->available_instances);
 }
 
-static MDEV_TYPE_ATTR_RO(available_instances);
-
-static const struct attribute *vfio_ap_mdev_type_attrs[] = {
-	&mdev_type_attr_available_instances.attr,
-	NULL,
-};
-
 struct vfio_ap_queue_reserved {
 	unsigned long *apid;
 	unsigned long *apqi;
@@ -1445,7 +1435,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
 	},
 	.probe = vfio_ap_mdev_probe,
 	.remove = vfio_ap_mdev_remove,
-	.types_attrs = vfio_ap_mdev_type_attrs,
+	.get_available = vfio_ap_mdev_get_available,
 };
 
 int vfio_ap_mdev_register(void)
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 8384e2992c706..6e500d7f15441 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -91,10 +91,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 64ca2ba806ed3..1188a5172a289 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 1b2117772192f..f1fddcdfedf6d 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] 59+ messages in thread

* [PATCH 12/13] vfio/mdev: consolidate all the description sysfs into the core code
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-15 20:52   ` Kirti Wankhede
  2022-06-23 21:37   ` Jason Gunthorpe
  2022-06-14  4:54 ` [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
  2022-06-14  5:03 ` simplify the mdev interface v2 Yi Liu
  13 siblings, 2 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

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>
---
 .../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 96b789f569c5a..7b00214167cab 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -106,7 +106,7 @@ structure to represent a mediated device's driver::
 	     int  (*probe)  (struct mdev_device *dev);
 	     void (*remove) (struct mdev_device *dev);
 	     unsigned int (*get_available)(struct mdev_type *mtype);
-	     const struct attribute * const *types_attrs;
+	     ssize_t (*show_description)(struct mdev_type *mtype, char *buf);
 	     struct device_driver    driver;
      };
 
@@ -224,7 +224,7 @@ Directories and files under the sysfs for Each Physical Device
 
 * description
 
-  This attribute should show brief features/description of the type. This is
+  This attribute can show brief features/description of the type. This is an
   optional attribute.
 
 Directories and Files Under the sysfs for Each mdev Device
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 0e14bf94534c4..91c58924e6b23 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->weight);
 }
 
-static MDEV_TYPE_ATTR_RO(description);
-
-static const struct attribute *gvt_type_attrs[] = {
-	&mdev_type_attr_description.attr,
-	NULL,
-};
-
 static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
 		unsigned long size)
 {
@@ -1586,10 +1578,10 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
 		.owner		= THIS_MODULE,
 		.dev_groups	= intel_vgpu_groups,
 	},
-	.probe		= intel_vgpu_probe,
-	.remove		= intel_vgpu_remove,
-	.get_available	= intel_vgpu_get_available,
-	.types_attrs	= gvt_type_attrs,
+	.probe			= intel_vgpu_probe,
+	.remove			= intel_vgpu_remove,
+	.get_available		= intel_vgpu_get_available,
+	.show_description	= intel_vgpu_show_description,
 };
 
 int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 60e8b9f6474e8..7825d83a55f8c 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -55,7 +55,7 @@ struct bus_type mdev_bus_type = {
  **/
 int mdev_register_driver(struct mdev_driver *drv)
 {
-	if (!drv->types_attrs || !drv->device_api)
+	if (!drv->device_api)
 		return -EINVAL;
 
 	/* initialize common driver fields */
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 6e500d7f15441..03d3732723571 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)
@@ -101,16 +113,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[] = {
@@ -150,13 +181,8 @@ 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);
@@ -165,8 +191,6 @@ int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
 
 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 1188a5172a289..2ed91b20aaae8 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 f1fddcdfedf6d..c015ebd60d530 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] 59+ messages in thread

* [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 12/13] vfio/mdev: consolidate all the description " Christoph Hellwig
@ 2022-06-14  4:54 ` Christoph Hellwig
  2022-06-14 10:32   ` Tian, Kevin
  2022-06-14  5:03 ` simplify the mdev interface v2 Yi Liu
  13 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  4:54 UTC (permalink / raw)
  To: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe

From: Jason Gunthorpe <jgg@nvidia.com>

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_type. Implement it using correct locking, fixing mdpy.

Drivers provide a the value in the mdev_driver at registration time and
the core code provides a standard sysfs attribute to return the
available_instances.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[count instances per-parent instead of per-type]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 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         | 10 ++++++++++
 include/linux/mdev.h                  |  3 +++
 samples/vfio-mdev/mdpy.c              | 23 ++++-------------------
 8 files changed, 21 insertions(+), 55 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 750d0315f1f5b..449c76b29a3b5 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -149,7 +149,6 @@ static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
 	INIT_LIST_HEAD(&private->crw);
 	INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
 	INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
-	atomic_set(&private->avail, 1);
 
 	private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
 				       GFP_KERNEL);
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 94cc62b808088..b89ac599a9087 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -70,13 +70,6 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static unsigned int vfio_ccw_get_available(struct mdev_type *mtype)
-{
-	struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
-
-	return atomic_read(&private->avail);
-}
-
 static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 {
 	struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
@@ -85,9 +78,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 	if (private->state == VFIO_CCW_STATE_NOT_OPER)
 		return -ENODEV;
 
-	if (atomic_dec_if_positive(&private->avail) < 0)
-		return -EPERM;
-
 	memset(&private->vdev, 0, sizeof(private->vdev));
 	vfio_init_group_dev(&private->vdev, &mdev->dev,
 			    &vfio_ccw_dev_ops);
@@ -108,7 +98,6 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
 
 err_atomic:
 	vfio_uninit_group_dev(&private->vdev);
-	atomic_inc(&private->avail);
 	private->mdev = NULL;
 	private->state = VFIO_CCW_STATE_IDLE;
 	return ret;
@@ -135,7 +124,6 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
 	vfio_uninit_group_dev(&private->vdev);
 	cp_free(&private->cp);
 	private->mdev = NULL;
-	atomic_inc(&private->avail);
 }
 
 static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
@@ -613,6 +601,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
 
 struct mdev_driver vfio_ccw_mdev_driver = {
 	.device_api = VFIO_DEVICE_API_CCW_STRING,
+	.max_instances = 1,
 	.driver = {
 		.name = "vfio_ccw_mdev",
 		.owner = THIS_MODULE,
@@ -620,7 +609,6 @@ struct mdev_driver vfio_ccw_mdev_driver = {
 	},
 	.probe = vfio_ccw_mdev_probe,
 	.remove = vfio_ccw_mdev_remove,
-	.get_available = vfio_ccw_get_available,
 };
 
 int vfio_ccw_mdev_reg(struct subchannel *sch)
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index 7272eb7886124..d64d12e789048 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -72,7 +72,6 @@ struct vfio_ccw_crw {
  * @sch: pointer to the subchannel
  * @state: internal state of the device
  * @completion: synchronization helper of the I/O completion
- * @avail: available for creating a mediated device
  * @mdev: pointer to the mediated device
  * @nb: notifier for vfio events
  * @io_region: MMIO region to input/output I/O arguments/results
@@ -96,7 +95,6 @@ struct vfio_ccw_private {
 	struct subchannel	*sch;
 	int			state;
 	struct completion	*completion;
-	atomic_t		avail;
 	struct mdev_device	*mdev;
 	struct notifier_block	nb;
 	struct ccw_io_region	*io_region;
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 5e6cc43413117..3d1108f1b7556 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -461,14 +461,9 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
 	struct ap_matrix_mdev *matrix_mdev;
 	int ret;
 
-	if ((atomic_dec_if_positive(&matrix_dev->available_instances) < 0))
-		return -EPERM;
-
 	matrix_mdev = kzalloc(sizeof(*matrix_mdev), GFP_KERNEL);
-	if (!matrix_mdev) {
-		ret = -ENOMEM;
-		goto err_dec_available;
-	}
+	if (!matrix_mdev)
+		return -ENOMEM;
 	vfio_init_group_dev(&matrix_mdev->vdev, &mdev->dev,
 			    &vfio_ap_matrix_dev_ops);
 
@@ -491,8 +486,6 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
 	mutex_unlock(&matrix_dev->lock);
 	vfio_uninit_group_dev(&matrix_mdev->vdev);
 	kfree(matrix_mdev);
-err_dec_available:
-	atomic_inc(&matrix_dev->available_instances);
 	return ret;
 }
 
@@ -508,12 +501,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
 	mutex_unlock(&matrix_dev->lock);
 	vfio_uninit_group_dev(&matrix_mdev->vdev);
 	kfree(matrix_mdev);
-	atomic_inc(&matrix_dev->available_instances);
-}
-
-static unsigned int vfio_ap_mdev_get_available(struct mdev_type *mtype)
-{
-	return atomic_read(&matrix_dev->available_instances);
 }
 
 struct vfio_ap_queue_reserved {
@@ -1427,6 +1414,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
 
 static struct mdev_driver vfio_ap_matrix_driver = {
 	.device_api = VFIO_DEVICE_API_AP_STRING,
+	.max_instances = MAX_ZDEV_ENTRIES_EXT,
 	.driver = {
 		.name = "vfio_ap_mdev",
 		.owner = THIS_MODULE,
@@ -1435,15 +1423,12 @@ static struct mdev_driver vfio_ap_matrix_driver = {
 	},
 	.probe = vfio_ap_mdev_probe,
 	.remove = vfio_ap_mdev_remove,
-	.get_available = vfio_ap_mdev_get_available,
 };
 
 int vfio_ap_mdev_register(void)
 {
 	int ret;
 
-	atomic_set(&matrix_dev->available_instances, MAX_ZDEV_ENTRIES_EXT);
-
 	ret = mdev_register_driver(&vfio_ap_matrix_driver);
 	if (ret)
 		return ret;
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 5dc5050d03791..b808b343b771f 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -28,7 +28,6 @@
  * struct ap_matrix_dev - Contains the data for the matrix device.
  *
  * @device:	generic device structure associated with the AP matrix device
- * @available_instances: number of mediated matrix devices that can be created
  * @info:	the struct containing the output from the PQAP(QCI) instruction
  * @mdev_list:	the list of mediated matrix devices created
  * @lock:	mutex for locking the AP matrix device. This lock will be
@@ -40,7 +39,6 @@
  */
 struct ap_matrix_dev {
 	struct device device;
-	atomic_t available_instances;
 	struct ap_config_info info;
 	struct list_head mdev_list;
 	struct mutex lock;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 20513b7f6b5eb..3a4d4fc9b4222 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -66,6 +66,7 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
 	init_rwsem(&parent->unreg_sem);
 	parent->dev = dev;
 	parent->mdev_driver = mdev_driver;
+	parent->available_instances = mdev_driver->max_instances;
 
 	if (!mdev_bus_compat_class) {
 		mdev_bus_compat_class = class_compat_register("mdev_bus");
@@ -135,6 +136,7 @@ static void mdev_device_release(struct device *dev)
 
 	mutex_lock(&mdev_list_lock);
 	list_del(&mdev->next);
+	mdev->type->parent->available_instances++;
 	mutex_unlock(&mdev_list_lock);
 
 	dev_dbg(&mdev->dev, "MDEV: destroying\n");
@@ -158,6 +160,14 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
 		}
 	}
 
+	if (!drv->get_available) {
+		if (!parent->available_instances) {
+			mutex_unlock(&mdev_list_lock);
+			return -EUSERS;
+		}
+		parent->available_instances--;
+	}
+
 	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
 	if (!mdev) {
 		mutex_unlock(&mdev_list_lock);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 2ed91b20aaae8..7945a66477820 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -45,6 +45,7 @@ struct mdev_parent {
 	struct rw_semaphore unreg_sem;
 	struct mdev_type **types;
 	unsigned int nr_types;
+	unsigned int available_instances;
 };
 
 static inline struct mdev_device *to_mdev_device(struct device *dev)
@@ -55,6 +56,7 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
 /**
  * struct mdev_driver - Mediated device driver
  * @device_api:	String to return for the device_api sysfs
+ * @max_instances: Maximum number of instances supported (optional)
  * @probe: called when new device created
  * @remove: called when device removed
  * @get_available: Return the max number of instances that can be created
@@ -63,6 +65,7 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
  **/
 struct mdev_driver {
 	const char *device_api;
+	unsigned int max_instances;
 	int (*probe)(struct mdev_device *dev);
 	void (*remove)(struct mdev_device *dev);
 	unsigned int (*get_available)(struct mdev_type *mtype);
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index c015ebd60d530..39b6c285b075c 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] 59+ messages in thread

* Re: simplify the mdev interface v2
  2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2022-06-14  4:54 ` [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
@ 2022-06-14  5:03 ` Yi Liu
  2022-06-14  5:17   ` Christoph Hellwig
  13 siblings, 1 reply; 59+ messages in thread
From: Yi Liu @ 2022-06-14  5:03 UTC (permalink / raw)
  To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

Hi Chris,

On 2022/6/14 12:54, Christoph Hellwig wrote:
> Hi all,
> 
> this series signigicantly simplies the mdev driver interface by following
> the patterns for device model interaction used elsewhere in the kernel.
> 
> Changes since v1:
>   - embedd the mdev_parent into a different sub-structure in i916
>   - remove headers now inclued by mdev.h from individual source files
>   - pass an array of mdev_types to mdev_register_parent
>   - add additional patches to implement all attributes on the
>     mdev_type in the core code
> 
> Diffstat:
>   Documentation/driver-api/vfio-mediated-device.rst |   26 +-
>   Documentation/s390/vfio-ap.rst                    |    2
>   Documentation/s390/vfio-ccw.rst                   |    2
>   drivers/gpu/drm/i915/gvt/gvt.h                    |    6
>   drivers/gpu/drm/i915/gvt/kvmgt.c                  |  158 +++------------
>   drivers/gpu/drm/i915/gvt/vgpu.c                   |   60 +----
>   drivers/s390/cio/cio.h                            |    4
>   drivers/s390/cio/vfio_ccw_drv.c                   |    3
>   drivers/s390/cio/vfio_ccw_ops.c                   |   60 -----
>   drivers/s390/cio/vfio_ccw_private.h               |    2
>   drivers/s390/crypto/vfio_ap_ops.c                 |   68 ------
>   drivers/s390/crypto/vfio_ap_private.h             |    6
>   drivers/vfio/mdev/mdev_core.c                     |  214 ++++++--------------
>   drivers/vfio/mdev/mdev_driver.c                   |    7
>   drivers/vfio/mdev/mdev_private.h                  |   39 ---
>   drivers/vfio/mdev/mdev_sysfs.c                    |  230 ++++++++--------------
>   include/linux/mdev.h                              |   77 +++----
>   samples/vfio-mdev/mbochs.c                        |  103 ++-------
>   samples/vfio-mdev/mdpy.c                          |  115 ++---------
>   samples/vfio-mdev/mtty.c                          |   94 +++-----
>   20 files changed, 389 insertions(+), 887 deletions(-)

Is this series available on any github repo? I'd like to apply your series 
and apply my vfio_device cdev series on top of it.

-- 
Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: simplify the mdev interface v2
  2022-06-14  5:03 ` simplify the mdev interface v2 Yi Liu
@ 2022-06-14  5:17   ` Christoph Hellwig
  2022-06-14  5:30     ` Yi Liu
  0 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  5:17 UTC (permalink / raw)
  To: Yi Liu
  Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 01:03:55PM +0800, Yi Liu wrote:
> Is this series available on any github repo? I'd like to apply your series 
> and apply my vfio_device cdev series on top of it.

I have a git repository available, but nothing on crappy platforms like
github.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: simplify the mdev interface v2
  2022-06-14  5:17   ` Christoph Hellwig
@ 2022-06-14  5:30     ` Yi Liu
  2022-06-14  5:44       ` Christoph Hellwig
  0 siblings, 1 reply; 59+ messages in thread
From: Yi Liu @ 2022-06-14  5:30 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On 2022/6/14 13:17, Christoph Hellwig wrote:
> On Tue, Jun 14, 2022 at 01:03:55PM +0800, Yi Liu wrote:
>> Is this series available on any github repo? I'd like to apply your series
>> and apply my vfio_device cdev series on top of it.
> 
> I have a git repository available, but nothing on crappy platforms like
> github.

haha, could you share me your git repo? :-)

-- 
Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: simplify the mdev interface v2
  2022-06-14  5:30     ` Yi Liu
@ 2022-06-14  5:44       ` Christoph Hellwig
  2022-06-14  5:47         ` Yi Liu
  0 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-14  5:44 UTC (permalink / raw)
  To: Yi Liu
  Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 01:30:06PM +0800, Yi Liu wrote:
> On 2022/6/14 13:17, Christoph Hellwig wrote:
>> On Tue, Jun 14, 2022 at 01:03:55PM +0800, Yi Liu wrote:
>>> Is this series available on any github repo? I'd like to apply your series
>>> and apply my vfio_device cdev series on top of it.
>>
>> I have a git repository available, but nothing on crappy platforms like
>> github.
>
> haha, could you share me your git repo? :-)

git://git.infradead.org/users/hch/misc.git mdev-lifetime

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/mdev-lifetime

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: simplify the mdev interface v2
  2022-06-14  5:44       ` Christoph Hellwig
@ 2022-06-14  5:47         ` Yi Liu
  0 siblings, 0 replies; 59+ messages in thread
From: Yi Liu @ 2022-06-14  5:47 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On 2022/6/14 13:44, Christoph Hellwig wrote:
> On Tue, Jun 14, 2022 at 01:30:06PM +0800, Yi Liu wrote:
>> On 2022/6/14 13:17, Christoph Hellwig wrote:
>>> On Tue, Jun 14, 2022 at 01:03:55PM +0800, Yi Liu wrote:
>>>> Is this series available on any github repo? I'd like to apply your series
>>>> and apply my vfio_device cdev series on top of it.
>>>
>>> I have a git repository available, but nothing on crappy platforms like
>>> github.
>>
>> haha, could you share me your git repo? :-)
> 
> git://git.infradead.org/users/hch/misc.git mdev-lifetime
> 
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/mdev-lifetime

thanks.

Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
@ 2022-06-14  6:14   ` Yi Liu
  2022-06-14 10:06   ` Tian, Kevin
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 59+ messages in thread
From: Yi Liu @ 2022-06-14  6:14 UTC (permalink / raw)
  To: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev

On 2022/6/14 12:54, 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
> struture and thus significantly simplify the code.

s/struture/structure

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   .../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               |  18 ++-
>   drivers/s390/cio/cio.h                        |   2 +
>   drivers/s390/cio/vfio_ccw_ops.c               |  19 +--
>   drivers/s390/crypto/vfio_ap_ops.c             |  19 +--
>   drivers/s390/crypto/vfio_ap_private.h         |   2 +
>   drivers/vfio/mdev/mdev_core.c                 |  54 ++++-----
>   drivers/vfio/mdev/mdev_driver.c               |   5 +-
>   drivers/vfio/mdev/mdev_private.h              |  14 +--
>   drivers/vfio/mdev/mdev_sysfs.c                | 111 ++----------------
>   include/linux/mdev.h                          |  26 ++--
>   samples/vfio-mdev/mbochs.c                    |  57 ++++-----
>   samples/vfio-mdev/mdpy.c                      |  50 +++-----
>   samples/vfio-mdev/mtty.c                      |  62 +++++-----
>   16 files changed, 181 insertions(+), 361 deletions(-)
> 
> diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
> index 3749f59c855fa..599008bdc1dcb 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -105,7 +105,7 @@ structure to represent a mediated device's driver::
>        struct mdev_driver {
>   	     int  (*probe)  (struct mdev_device *dev);
>   	     void (*remove) (struct mdev_device *dev);
> -	     struct attribute_group **supported_type_groups;
> +	     const struct attribute * const *types_attrs;
>   	     struct device_driver    driver;
>        };
>   
> diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
> index ddffd337f1c60..0ccb9bb7180cd 100644
> --- a/drivers/gpu/drm/i915/gvt/gvt.h
> +++ b/drivers/gpu/drm/i915/gvt/gvt.h
> @@ -298,7 +298,7 @@ struct intel_gvt_firmware {
>   
>   #define NR_MAX_INTEL_VGPU_TYPES 20
>   struct intel_vgpu_type {
> -	char name[16];
> +	struct mdev_type type;
>   	unsigned int avail_instance;
>   	unsigned int low_gm_size;
>   	unsigned int high_gm_size;
> @@ -329,6 +329,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 70401374c72bc..1c6b7e8bec4fb 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -117,17 +117,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
>   {
> -	struct intel_vgpu_type *type;
> -	unsigned int num = 0;
> -	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
> +	struct intel_vgpu_type *type =
> +		container_of(mtype, struct intel_vgpu_type, type);
>   
> -	type = &gvt->types[mtype_get_type_group_id(mtype)];
> -	if (!type)
> -		num = 0;
> -	else
> -		num = type->avail_instance;
> -
> -	return sprintf(buf, "%u\n", num);
> +	return sprintf(buf, "%u\n", type->avail_instance);
>   }
>   
>   static ssize_t device_api_show(struct mdev_type *mtype,
> @@ -139,12 +132,8 @@ static ssize_t device_api_show(struct mdev_type *mtype,
>   static ssize_t description_show(struct mdev_type *mtype,
>   				struct mdev_type_attribute *attr, char *buf)
>   {
> -	struct intel_vgpu_type *type;
> -	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
> -
> -	type = &gvt->types[mtype_get_type_group_id(mtype)];
> -	if (!type)
> -		return 0;
> +	struct intel_vgpu_type *type =
> +		container_of(mtype, struct intel_vgpu_type, type);
>   
>   	return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
>   		       "fence: %d\nresolution: %s\n"
> @@ -158,14 +147,7 @@ static ssize_t description_show(struct mdev_type *mtype,
>   static ssize_t name_show(struct mdev_type *mtype,
>   			 struct mdev_type_attribute *attr, char *buf)
>   {
> -	struct intel_vgpu_type *type;
> -	struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
> -
> -	type = &gvt->types[mtype_get_type_group_id(mtype)];
> -	if (!type)
> -		return 0;
> -
> -	return sprintf(buf, "%s\n", type->name);
> +	return sprintf(buf, "%s\n", mtype->sysfs_name);
>   }
>   
>   static MDEV_TYPE_ATTR_RO(available_instances);
> @@ -173,7 +155,7 @@ static MDEV_TYPE_ATTR_RO(device_api);
>   static MDEV_TYPE_ATTR_RO(description);
>   static MDEV_TYPE_ATTR_RO(name);
>   
> -static struct attribute *gvt_type_attrs[] = {
> +static const struct attribute *gvt_type_attrs[] = {
>   	&mdev_type_attr_available_instances.attr,
>   	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_description.attr,
> @@ -181,51 +163,6 @@ static struct attribute *gvt_type_attrs[] = {
>   	NULL,
>   };
>   
> -static struct attribute_group *gvt_vgpu_type_groups[] = {
> -	[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
> -};
> -
> -static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
> -{
> -	int i, j;
> -	struct intel_vgpu_type *type;
> -	struct attribute_group *group;
> -
> -	for (i = 0; i < gvt->num_types; i++) {
> -		type = &gvt->types[i];
> -
> -		group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
> -		if (!group)
> -			goto unwind;
> -
> -		group->name = type->name;
> -		group->attrs = gvt_type_attrs;
> -		gvt_vgpu_type_groups[i] = group;
> -	}
> -
> -	return 0;
> -
> -unwind:
> -	for (j = 0; j < i; j++) {
> -		group = gvt_vgpu_type_groups[j];
> -		kfree(group);
> -	}
> -
> -	return -ENOMEM;
> -}
> -
> -static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
> -{
> -	int i;
> -	struct attribute_group *group;
> -
> -	for (i = 0; i < gvt->num_types; i++) {
> -		group = gvt_vgpu_type_groups[i];
> -		gvt_vgpu_type_groups[i] = NULL;
> -		kfree(group);
> -	}
> -}
> -
>   static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
>   		unsigned long size)
>   {
> @@ -1614,14 +1551,11 @@ static int intel_vgpu_probe(struct mdev_device *mdev)
>   {
>   	struct device *pdev = mdev_parent_dev(mdev);
>   	struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
> -	struct intel_vgpu_type *type;
> +	struct intel_vgpu_type *type =
> +		container_of(mdev->type, struct intel_vgpu_type, type);
>   	struct intel_vgpu *vgpu;
>   	int ret;
>   
> -	type = &gvt->types[mdev_get_type_group_id(mdev)];
> -	if (!type)
> -		return -EINVAL;
> -
>   	vgpu = intel_gvt_create_vgpu(gvt, type);
>   	if (IS_ERR(vgpu)) {
>   		gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
> @@ -1660,7 +1594,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
>   	},
>   	.probe		= intel_vgpu_probe,
>   	.remove		= intel_vgpu_remove,
> -	.supported_type_groups	= gvt_vgpu_type_groups,
> +	.types_attrs	= gvt_type_attrs,
>   };
>   
>   int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
> @@ -1959,7 +1893,6 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
>   		return;
>   
>   	mdev_unregister_parent(&gvt->parent);
> -	intel_gvt_cleanup_vgpu_type_groups(gvt);
>   	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
>   	intel_gvt_clean_vgpu_types(gvt);
>   
> @@ -2059,20 +1992,15 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
>   
>   	intel_gvt_debugfs_init(gvt);
>   
> -	ret = intel_gvt_init_vgpu_type_groups(gvt);
> -	if (ret)
> -		goto out_destroy_idle_vgpu;
> -
>   	ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
> -				   &intel_vgpu_mdev_driver);
> +				   &intel_vgpu_mdev_driver,
> +				   gvt->mdev_types, gvt->num_types);
>   	if (ret)
> -		goto out_cleanup_vgpu_type_groups;
> +		goto out_destroy_idle_vgpu;
>   
>   	gvt_dbg_core("gvt device initialization is done\n");
>   	return 0;
>   
> -out_cleanup_vgpu_type_groups:
> -	intel_gvt_cleanup_vgpu_type_groups(gvt);
>   out_destroy_idle_vgpu:
>   	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
>   	intel_gvt_debugfs_clean(gvt);
> diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
> index 46da19b3225d2..2f38b90ecb8ac 100644
> --- a/drivers/gpu/drm/i915/gvt/vgpu.c
> +++ b/drivers/gpu/drm/i915/gvt/vgpu.c
> @@ -131,6 +131,13 @@ 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) {
> +		kfree(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)
> @@ -150,19 +157,21 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
>   						   high_avail / vgpu_types[i].high_mm);
>   
>   		if (GRAPHICS_VER(gvt->gt->i915) == 8)
> -			sprintf(gvt->types[i].name, "GVTg_V4_%s",
> +			sprintf(gvt->types[i].type.sysfs_name, "GVTg_V4_%s",
>   				vgpu_types[i].name);
>   		else if (GRAPHICS_VER(gvt->gt->i915) == 9)
> -			sprintf(gvt->types[i].name, "GVTg_V5_%s",
> +			sprintf(gvt->types[i].type.sysfs_name, "GVTg_V5_%s",
>   				vgpu_types[i].name);
>   
>   		gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n",
> -			     i, gvt->types[i].name,
> +			     i, gvt->types[i].type.sysfs_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));
> +
> +		gvt->mdev_types[i] = &gvt->types[i].type;
>   	}
>   
>   	gvt->num_types = i;
> @@ -171,6 +180,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);
>   }
>   
> @@ -198,7 +208,7 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
>   						   fence_min);
>   
>   		gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n",
> -		       i, gvt->types[i].name,
> +		       i, gvt->types[i].type.sysfs_name,
>   		       gvt->types[i].avail_instance, gvt->types[i].low_gm_size,
>   		       gvt->types[i].high_gm_size, gvt->types[i].fence);
>   	}
> diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
> index 22be5ac7d23c1..1da45307a1862 100644
> --- a/drivers/s390/cio/cio.h
> +++ b/drivers/s390/cio/cio.h
> @@ -110,6 +110,8 @@ struct subchannel {
>   	 */
>   	const char *driver_override;
>   	struct mdev_parent parent;
> +	struct mdev_type mdev_type;
> +	struct mdev_type *mdev_types[1];
>   } __attribute__ ((aligned(8)));
>   
>   DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index 9192a21085ce4..25b8d42a522ac 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -95,23 +95,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   }
>   static MDEV_TYPE_ATTR_RO(available_instances);
>   
> -static struct attribute *mdev_types_attrs[] = {
> +static const struct attribute *mdev_types_attrs[] = {
>   	&mdev_type_attr_name.attr,
>   	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
>   
> -static struct attribute_group mdev_type_group = {
> -	.name  = "io",
> -	.attrs = mdev_types_attrs,
> -};
> -
> -static struct attribute_group *mdev_type_groups[] = {
> -	&mdev_type_group,
> -	NULL,
> -};
> -
>   static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
>   {
>   	struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
> @@ -654,13 +644,16 @@ struct mdev_driver vfio_ccw_mdev_driver = {
>   	},
>   	.probe = vfio_ccw_mdev_probe,
>   	.remove = vfio_ccw_mdev_remove,
> -	.supported_type_groups  = mdev_type_groups,
> +	.types_attrs = mdev_types_attrs,
>   };
>   
>   int vfio_ccw_mdev_reg(struct subchannel *sch)
>   {
> +	sprintf(sch->mdev_type.sysfs_name, "io");
> +	sch->mdev_types[0] = &sch->mdev_type;
>   	return mdev_register_parent(&sch->parent, &sch->dev,
> -				    &vfio_ccw_mdev_driver);
> +				    &vfio_ccw_mdev_driver, sch->mdev_types,
> +				    1);
>   }
>   
>   void vfio_ccw_mdev_unreg(struct subchannel *sch)
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 834945150dc9f..ff25858b2ebbe 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -537,23 +537,13 @@ static ssize_t device_api_show(struct mdev_type *mtype,
>   
>   static MDEV_TYPE_ATTR_RO(device_api);
>   
> -static struct attribute *vfio_ap_mdev_type_attrs[] = {
> +static const struct attribute *vfio_ap_mdev_type_attrs[] = {
>   	&mdev_type_attr_name.attr,
>   	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
>   
> -static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
> -	.name = VFIO_AP_MDEV_TYPE_HWVIRT,
> -	.attrs = vfio_ap_mdev_type_attrs,
> -};
> -
> -static struct attribute_group *vfio_ap_mdev_type_groups[] = {
> -	&vfio_ap_mdev_hwvirt_type_group,
> -	NULL,
> -};
> -
>   struct vfio_ap_queue_reserved {
>   	unsigned long *apid;
>   	unsigned long *apqi;
> @@ -1472,7 +1462,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
>   	},
>   	.probe = vfio_ap_mdev_probe,
>   	.remove = vfio_ap_mdev_remove,
> -	.supported_type_groups = vfio_ap_mdev_type_groups,
> +	.types_attrs = vfio_ap_mdev_type_attrs,
>   };
>   
>   int vfio_ap_mdev_register(void)
> @@ -1485,8 +1475,11 @@ int vfio_ap_mdev_register(void)
>   	if (ret)
>   		return ret;
>   
> +	strcpy(matrix_dev->mdev_type.sysfs_name, VFIO_AP_MDEV_TYPE_HWVIRT);
> +	matrix_dev->mdev_types[0] = &matrix_dev->mdev_type;
>   	ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
> -				   &vfio_ap_matrix_driver);
> +				   &vfio_ap_matrix_driver,
> +				   matrix_dev->mdev_types, 1);
>   	if (ret)
>   		goto err_driver;
>   	return 0;
> diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
> index 0191f6bc973a4..5dc5050d03791 100644
> --- a/drivers/s390/crypto/vfio_ap_private.h
> +++ b/drivers/s390/crypto/vfio_ap_private.h
> @@ -46,6 +46,8 @@ struct ap_matrix_dev {
>   	struct mutex lock;
>   	struct ap_driver  *vfio_ap_drv;
>   	struct mdev_parent parent;
> +	struct mdev_type mdev_type;
> +	struct mdev_type *mdev_types[];
>   };
>   
>   extern struct ap_matrix_dev *matrix_dev;
> diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
> index d38faed14c689..71c7f4e521a74 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,19 +65,19 @@ 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
>    *
>    * 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;
> +	int i;
>   
>   	memset(parent, 0, sizeof(*parent));
>   	init_rwsem(&parent->unreg_sem);
> @@ -110,9 +90,23 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
>   			return -ENOMEM;
>   	}
>   
> -	ret = parent_create_sysfs_files(parent);
> -	if (ret)
> +	parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
> +					       NULL, &parent->dev->kobj);
> +	if (!parent->mdev_types_kset)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < nr_types; i++) {
> +		ret = mdev_type_add(parent, types[i]);
> +		if (ret)
> +			break;
> +	}
> +	parent->types = types;
> +	parent->nr_types = i;
> +
> +	if (ret) {
> +		mdev_unregister_parent(parent);
>   		return ret;
> +	}
>   
>   	ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
>   	if (ret)
> @@ -132,13 +126,17 @@ void mdev_unregister_parent(struct mdev_parent *parent)
>   {
>   	char *env_string = "MDEV_STATE=unregistered";
>   	char *envp[] = { env_string, NULL };
> +	int i;
>   
>   	dev_info(parent->dev, "MDEV: Unregistering\n");
>   
> +	for (i = 0; i < parent->nr_types; i++)
> +		mdev_type_remove(parent->types[i]);
> +									

trailing spaces.

>   	down_write(&parent->unreg_sem);
>   	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);
> +	kset_unregister(parent->mdev_types_kset);
>   	up_write(&parent->unreg_sem);
>   
>   	kobject_uevent_env(&parent->dev->kobj, KOBJ_CHANGE, envp);
> 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..6980f504018f3 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)	\
> @@ -28,12 +20,12 @@ extern const struct attribute_group *mdev_device_groups[];
>   #define to_mdev_type(_kobj)		\
>   	container_of(_kobj, struct mdev_type, kobj)
>   
> -int  parent_create_sysfs_files(struct mdev_parent *parent);
> -void parent_remove_sysfs_files(struct mdev_parent *parent);
> -
>   int  mdev_create_sysfs_files(struct mdev_device *mdev);
>   void mdev_remove_sysfs_files(struct mdev_device *mdev);
>   
> +int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type);
> +void mdev_type_remove(struct mdev_type *type);
> +
>   int mdev_device_create(struct mdev_type *kobj, const guid_t *uuid);
>   int  mdev_device_remove(struct mdev_device *dev);
>   
> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
> index b71ffc5594870..09745e8e120f9 100644
> --- a/drivers/vfio/mdev/mdev_sysfs.c
> +++ b/drivers/vfio/mdev/mdev_sysfs.c
> @@ -80,8 +80,6 @@ static void mdev_type_release(struct kobject *kobj)
>   	struct mdev_type *type = to_mdev_type(kobj);
>   
>   	pr_debug("Releasing group %s\n", kobj->name);
> -	/* Pairs with the get in add_mdev_supported_type() */
> -	put_device(type->parent->dev);
>   	kfree(type);
>   }
>   
> @@ -90,36 +88,17 @@ 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)
> +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);
> -	if (ret) {
> -		kobject_put(&type->kobj);
> -		return ERR_PTR(ret);
> -	}
> +	type->kobj.kset = parent->mdev_types_kset;
> +	ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL, "%s-%s",
> +				   dev_driver_string(parent->dev),
> +				   type->sysfs_name);
> +	if (ret)
> +		return ret;
>   
>   	ret = sysfs_create_file(&type->kobj, &mdev_type_attr_create.attr);
>   	if (ret)
> @@ -131,13 +110,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,80 +122,19 @@ 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)
> +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(&ltype->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);
> -	}
> -
> -	kset_unregister(parent->mdev_types_kset);
> -}
> -
> -int parent_create_sysfs_files(struct mdev_parent *parent)
> -{
> -	int ret;
> -
> -	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;
> -	return 0;
> -
> -create_err:
> -	kset_unregister(parent->mdev_types_kset);
> -	return ret;
> -}
> -
>   static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
>   			    const char *buf, size_t count)
>   {
> diff --git a/include/linux/mdev.h b/include/linux/mdev.h
> index 327ce3e5c6b5f..d28ddf0f561a0 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: */
> +	char sysfs_name[32];
> +
> +	/* set by the core, can be used drivers */
> +	struct mdev_parent *parent;
> +
> +	/* internal only */
> +	struct kobject kobj;
> +	struct kobject *devices_kobj;
> +};
> +
>   /* embedded into the struct device that the mdev devices hang off */
>   struct mdev_parent {
>   	struct device *dev;
>   	struct mdev_driver *mdev_driver;
>   	struct kset *mdev_types_kset;
> -	struct list_head type_list;
>   	/* Synchronize device creation/removal with parent unregistration */
>   	struct rw_semaphore unreg_sem;
> +	struct mdev_type **types;
> +	unsigned int nr_types;
>   };
>   
>   static inline struct mdev_device *to_mdev_device(struct device *dev)
> @@ -38,8 +51,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev)
>   	return container_of(dev, struct mdev_device, dev);
>   }
>   
> -unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
> -unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
>   struct device *mtype_get_parent_dev(struct mdev_type *mtype);
>   
>   /* interface for exporting mdev supported type attributes */
> @@ -66,15 +77,13 @@ struct mdev_type_attribute mdev_type_attr_##_name =		\
>    * struct mdev_driver - Mediated device driver
>    * @probe: called when new device created
>    * @remove: called when device removed
> - * @supported_type_groups: Attributes to define supported types. It is mandatory
> - *			to provide supported types.
> + * @types_attrs: attributes to the type kobjects.
>    * @driver: device driver structure
> - *
>    **/
>   struct mdev_driver {
>   	int (*probe)(struct mdev_device *dev);
>   	void (*remove)(struct mdev_device *dev);
> -	struct attribute_group **supported_type_groups;
> +	const struct attribute * const *types_attrs;
>   	struct device_driver driver;
>   };
>   
> @@ -86,7 +95,8 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
>   extern struct bus_type mdev_bus_type;
>   
>   int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
> -		struct mdev_driver *mdev_driver);
> +		struct mdev_driver *mdev_driver, struct mdev_type **types,
> +		unsigned int nr_types);
>   void mdev_unregister_parent(struct mdev_parent *parent);
>   
>   int mdev_register_driver(struct mdev_driver *drv);
> diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
> index 30b3643b3b389..1069f561cb012 100644
> --- a/samples/vfio-mdev/mbochs.c
> +++ b/samples/vfio-mdev/mbochs.c
> @@ -99,23 +99,27 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
>   #define MBOCHS_TYPE_2 "medium"
>   #define MBOCHS_TYPE_3 "large"
>   
> -static const struct mbochs_type {
> +static struct mbochs_type {
> +	struct mdev_type type;
>   	const char *name;
>   	u32 mbytes;
>   	u32 max_x;
>   	u32 max_y;
>   } mbochs_types[] = {
>   	{
> +		.type.sysfs_name	= MBOCHS_TYPE_1,
>   		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
>   		.mbytes = 4,
>   		.max_x  = 800,
>   		.max_y  = 600,
>   	}, {
> +		.type.sysfs_name	= MBOCHS_TYPE_2,
>   		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
>   		.mbytes = 16,
>   		.max_x  = 1920,
>   		.max_y  = 1440,
>   	}, {
> +		.type.sysfs_name	= MBOCHS_TYPE_3,
>   		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
>   		.mbytes = 64,
>   		.max_x  = 0,
> @@ -123,6 +127,11 @@ static const struct mbochs_type {
>   	},
>   };
>   
> +static struct mdev_type *mbochs_mdev_types[] = {
> +	&mbochs_types[0].type,
> +	&mbochs_types[1].type,
> +	&mbochs_types[2].type,
> +};
>   
>   static dev_t		mbochs_devt;
>   static struct class	*mbochs_class;
> @@ -508,8 +517,8 @@ static int mbochs_reset(struct mdev_state *mdev_state)
>   static int mbochs_probe(struct mdev_device *mdev)
>   {
>   	int avail_mbytes = atomic_read(&mbochs_avail_mbytes);
> -	const struct mbochs_type *type =
> -		&mbochs_types[mdev_get_type_group_id(mdev)];
> +	struct mbochs_type *type =
> +		container_of(mdev->type, struct mbochs_type, type);
>   	struct device *dev = mdev_dev(mdev);
>   	struct mdev_state *mdev_state;
>   	int ret = -ENOMEM;
> @@ -1328,8 +1337,8 @@ static const struct attribute_group *mdev_dev_groups[] = {
>   static ssize_t name_show(struct mdev_type *mtype,
>   			 struct mdev_type_attribute *attr, char *buf)
>   {
> -	const struct mbochs_type *type =
> -		&mbochs_types[mtype_get_type_group_id(mtype)];
> +	struct mbochs_type *type =
> +		container_of(mtype, struct mbochs_type, type);
>   
>   	return sprintf(buf, "%s\n", type->name);
>   }
> @@ -1338,8 +1347,8 @@ static MDEV_TYPE_ATTR_RO(name);
>   static ssize_t description_show(struct mdev_type *mtype,
>   				struct mdev_type_attribute *attr, char *buf)
>   {
> -	const struct mbochs_type *type =
> -		&mbochs_types[mtype_get_type_group_id(mtype)];
> +	struct mbochs_type *type =
> +		container_of(mtype, struct mbochs_type, type);
>   
>   	return sprintf(buf, "virtual display, %d MB video memory\n",
>   		       type ? type->mbytes  : 0);
> @@ -1350,8 +1359,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
>   {
> -	const struct mbochs_type *type =
> -		&mbochs_types[mtype_get_type_group_id(mtype)];
> +	struct mbochs_type *type =
> +		container_of(mtype, struct mbochs_type, type);
>   	int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes;
>   
>   	return sprintf(buf, "%d\n", count);
> @@ -1365,7 +1374,7 @@ static ssize_t device_api_show(struct mdev_type *mtype,
>   }
>   static MDEV_TYPE_ATTR_RO(device_api);
>   
> -static struct attribute *mdev_types_attrs[] = {
> +static const struct attribute *mdev_types_attrs[] = {
>   	&mdev_type_attr_name.attr,
>   	&mdev_type_attr_description.attr,
>   	&mdev_type_attr_device_api.attr,
> @@ -1373,28 +1382,6 @@ static struct attribute *mdev_types_attrs[] = {
>   	NULL,
>   };
>   
> -static struct attribute_group mdev_type_group1 = {
> -	.name  = MBOCHS_TYPE_1,
> -	.attrs = mdev_types_attrs,
> -};
> -
> -static struct attribute_group mdev_type_group2 = {
> -	.name  = MBOCHS_TYPE_2,
> -	.attrs = mdev_types_attrs,
> -};
> -
> -static struct attribute_group mdev_type_group3 = {
> -	.name  = MBOCHS_TYPE_3,
> -	.attrs = mdev_types_attrs,
> -};
> -
> -static struct attribute_group *mdev_type_groups[] = {
> -	&mdev_type_group1,
> -	&mdev_type_group2,
> -	&mdev_type_group3,
> -	NULL,
> -};
> -
>   static const struct vfio_device_ops mbochs_dev_ops = {
>   	.close_device = mbochs_close_device,
>   	.read = mbochs_read,
> @@ -1412,7 +1399,7 @@ static struct mdev_driver mbochs_driver = {
>   	},
>   	.probe = mbochs_probe,
>   	.remove	= mbochs_remove,
> -	.supported_type_groups = mdev_type_groups,
> +	.types_attrs = mdev_types_attrs,
>   };
>   
>   static const struct file_operations vd_fops = {
> @@ -1457,7 +1444,9 @@ static int __init mbochs_dev_init(void)
>   	if (ret)
>   		goto err_class;
>   
> -	ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
> +	ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver,
> +				   mbochs_mdev_types,
> +				   ARRAY_SIZE(mbochs_mdev_types));
>   	if (ret)
>   		goto err_device;
>   
> diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
> index 132bb055628a6..40b1c8a58157c 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,
> @@ -78,6 +82,12 @@ static const struct mdpy_type {
>   		.height = 1080,
>   	},
>   };
> +	

trailing spaces.

> +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;
> @@ -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;

-- 
Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 01/13] vfio/mdev: make mdev.h standalone includable
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
@ 2022-06-14  9:50   ` Tian, Kevin
  2022-06-15 19:12   ` Kirti Wankhede
  2022-06-23 19:39   ` [PATCH 1/13] " Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14  9:50 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: linux-s390, intel-gvt-dev, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> 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: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
@ 2022-06-14  9:54   ` Tian, Kevin
  2022-06-15 19:29   ` Kirti Wankhede
  2022-06-23 20:59   ` [PATCH 2/13] " Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14  9:54 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: linux-s390, intel-gvt-dev, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> Simplify mdev_{un}register_device by requiring the caller to pass in
> a structure allocate as part of the parent device structure.  This
> removes the need for a list of parents and the separate mdev_parent
> refcount as we can simplify rely on the reference to the parent device.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
  2022-06-14  6:14   ` Yi Liu
@ 2022-06-14 10:06   ` Tian, Kevin
  2022-06-15  6:28     ` Christoph Hellwig
  2022-06-15 19:55   ` Kirti Wankhede
  2022-06-23 21:27   ` [PATCH 3/13] " Jason Gunthorpe
  3 siblings, 1 reply; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:06 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: linux-s390, intel-gvt-dev, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> @@ -131,6 +131,13 @@ 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) {
> +		kfree(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)
> @@ -150,19 +157,21 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
>  						   high_avail /
> vgpu_types[i].high_mm);

there is a memory leak a few lines above:

if (vgpu_types[i].weight < 1 ||
	vgpu_types[i].weight > VGPU_MAX_WEIGHT)
	return -EINVAL;

both old code and this patch forgot to free the buffers upon error.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code
  2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
@ 2022-06-14 10:10   ` Tian, Kevin
  2022-06-15 20:24   ` Kirti Wankhede
  2022-06-23 21:30   ` [PATCH 9/13] " Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:10 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: linux-s390, intel-gvt-dev, Jason Gunthorpe, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> 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>, with one nit:

>  /**
>   * 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
>   **/

Use same indent here.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 10/13] vfio/mdev: consolidate all the name sysfs into the core code
  2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
@ 2022-06-14 10:11   ` Tian, Kevin
  2022-06-15 20:31   ` Kirti Wankhede
  2022-06-23 21:32   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:11 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: kvm, linux-s390, intel-gvt-dev

> From: Christoph Hellwig <hch@lst.de>
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> 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: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 11/13] vfio/mdev: consolidate all the available_instance sysfs into the core code
  2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
@ 2022-06-14 10:14   ` Tian, Kevin
  2022-06-14 10:29     ` Tian, Kevin
  2022-06-15 20:37   ` Kirti Wankhede
  2022-06-23 21:36   ` Jason Gunthorpe
  2 siblings, 1 reply; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:14 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: linux-s390, intel-gvt-dev, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> Every driver just print a number, simply add a method to the mdev_driver
> to return it and provide a standard sysfs show function.

I didn't get why not simply adding a field to mdev_type?


^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 11/13] vfio/mdev: consolidate all the available_instance sysfs into the core code
  2022-06-14 10:14   ` Tian, Kevin
@ 2022-06-14 10:29     ` Tian, Kevin
  0 siblings, 0 replies; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:29 UTC (permalink / raw)
  To: Tian, Kevin, Christoph Hellwig, Kirti Wankhede, Tony Krowiak,
	Halil Pasic, Jason Herne, Eric Farman, Matthew Rosato,
	Zhenyu Wang, Wang, Zhi A, Alex Williamson
  Cc: linux-s390, intel-gvt-dev, kvm

> From: Tian, Kevin
> Sent: Tuesday, June 14, 2022 6:14 PM
> 
> > From: Christoph Hellwig
> > Sent: Tuesday, June 14, 2022 12:54 PM
> >
> > Every driver just print a number, simply add a method to the mdev_driver
> > to return it and provide a standard sysfs show function.
> 
> I didn't get why not simply adding a field to mdev_type?

Please ignore this comment. It's a dumb fact that available instances
is dynamic especially when shared resources may exist between
different types which cannot be generalized in the core.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>


^ permalink raw reply	[flat|nested] 59+ messages in thread

* RE: [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core
  2022-06-14  4:54 ` [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
@ 2022-06-14 10:32   ` Tian, Kevin
  2022-06-15  6:29     ` Christoph Hellwig
  0 siblings, 1 reply; 59+ messages in thread
From: Tian, Kevin @ 2022-06-14 10:32 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: linux-s390, intel-gvt-dev, Jason Gunthorpe, kvm

> From: Christoph Hellwig
> Sent: Tuesday, June 14, 2022 12:54 PM
> 
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> 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_type. Implement it using correct locking, fixing mdpy.
> 
> Drivers provide a the value in the mdev_driver at registration time and
> the core code provides a standard sysfs attribute to return the
> available_instances.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [count instances per-parent instead of per-type]

per-parent counting works only if the parent doesn't have overlapping
instances between types. This is probably worth a clarification in doc.

> @@ -135,6 +136,7 @@ static void mdev_device_release(struct device *dev)
> 
>  	mutex_lock(&mdev_list_lock);
>  	list_del(&mdev->next);
> +	mdev->type->parent->available_instances++;

	if (!drv->get_available)
		mdev->type->parent->available_instances++;

Otherwise this looks good to me:

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-15  6:28     ` Christoph Hellwig
@ 2022-06-15  6:11       ` Zhenyu Wang
  0 siblings, 0 replies; 59+ messages in thread
From: Zhenyu Wang @ 2022-06-15  6:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Tian, Kevin, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Wang,
	Zhi A, Alex Williamson, linux-s390, intel-gvt-dev, kvm

[-- Attachment #1: Type: text/plain, Size: 1077 bytes --]

On 2022.06.15 08:28:40 +0200, Christoph Hellwig wrote:
> On Tue, Jun 14, 2022 at 10:06:16AM +0000, Tian, Kevin wrote:
> > > +	gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types),
> > > +			     GFP_KERNEL);
> > > +	if (!gvt->mdev_types) {
> > > +		kfree(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)
> > > @@ -150,19 +157,21 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
> > >  						   high_avail /
> > > vgpu_types[i].high_mm);
> > 
> > there is a memory leak a few lines above:
> > 
> > if (vgpu_types[i].weight < 1 ||
> > 	vgpu_types[i].weight > VGPU_MAX_WEIGHT)
> > 	return -EINVAL;
> > 
> > both old code and this patch forgot to free the buffers upon error.

Sorry about that! It should be my original fault...

> 
> Yeah.  I'll add a patch to the beginning of the series to fix the
> existing leak and will then make sure to not leak the new allocation
> either.

Thanks a lot!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-14 10:06   ` Tian, Kevin
@ 2022-06-15  6:28     ` Christoph Hellwig
  2022-06-15  6:11       ` Zhenyu Wang
  0 siblings, 1 reply; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-15  6:28 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Wang,
	Zhi A, Alex Williamson, linux-s390, intel-gvt-dev, kvm

On Tue, Jun 14, 2022 at 10:06:16AM +0000, Tian, Kevin wrote:
> > +	gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types),
> > +			     GFP_KERNEL);
> > +	if (!gvt->mdev_types) {
> > +		kfree(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)
> > @@ -150,19 +157,21 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
> >  						   high_avail /
> > vgpu_types[i].high_mm);
> 
> there is a memory leak a few lines above:
> 
> if (vgpu_types[i].weight < 1 ||
> 	vgpu_types[i].weight > VGPU_MAX_WEIGHT)
> 	return -EINVAL;
> 
> both old code and this patch forgot to free the buffers upon error.

Yeah.  I'll add a patch to the beginning of the series to fix the
existing leak and will then make sure to not leak the new allocation
either.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core
  2022-06-14 10:32   ` Tian, Kevin
@ 2022-06-15  6:29     ` Christoph Hellwig
  0 siblings, 0 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-15  6:29 UTC (permalink / raw)
  To: Tian, Kevin
  Cc: Christoph Hellwig, Kirti Wankhede, Tony Krowiak, Halil Pasic,
	Jason Herne, Eric Farman, Matthew Rosato, Zhenyu Wang, Wang,
	Zhi A, Alex Williamson, linux-s390, intel-gvt-dev,
	Jason Gunthorpe, kvm

On Tue, Jun 14, 2022 at 10:32:11AM +0000, Tian, Kevin wrote:
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > [count instances per-parent instead of per-type]
> 
> per-parent counting works only if the parent doesn't have overlapping
> instances between types. This is probably worth a clarification in doc.

Yes.  Two cases right now just have a single type, and the third wants
this per-parent counting.  The original patch from Jason actually got
this wrong.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 01/13] vfio/mdev: make mdev.h standalone includable
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
  2022-06-14  9:50   ` Tian, Kevin
@ 2022-06-15 19:12   ` Kirti Wankhede
  2022-06-23 19:39   ` [PATCH 1/13] " Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 19:12 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 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: Kirti Wankhede <kwankhede@nvidia.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
  2022-06-14  9:54   ` Tian, Kevin
@ 2022-06-15 19:29   ` Kirti Wankhede
  2022-06-23 20:18     ` Jason Gunthorpe
  2022-06-23 20:59   ` [PATCH 2/13] " Jason Gunthorpe
  2 siblings, 1 reply; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 19:29 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Dheeraj Nigam, Tarun Gupta



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
<snip>


>   /*
> - * 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.
>    * 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;
> -

Hold the reference for device here once rather than helding multiple 
times while adding sysfs for each mdev_types below. See more below

> -	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;
>

Here device reference is held and release multiple times for each 
mdev_type. It should be held once from mdev_register_parent() and 
released from mdev_unregister_parent().

Thanks,
Kirti

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
  2022-06-14  6:14   ` Yi Liu
  2022-06-14 10:06   ` Tian, Kevin
@ 2022-06-15 19:55   ` Kirti Wankhede
  2022-06-19  7:42     ` Christoph Hellwig
  2022-06-23 21:27   ` [PATCH 3/13] " Jason Gunthorpe
  3 siblings, 1 reply; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 19:55 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
<snip>

    /*
>    * Used in mdev_type_attribute sysfs functions to return the parent struct
>    * device
> @@ -85,19 +65,19 @@ 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
>    *
>    * 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;
> +	int i;
>   
>   	memset(parent, 0, sizeof(*parent));
>   	init_rwsem(&parent->unreg_sem);
> @@ -110,9 +90,23 @@ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
>   			return -ENOMEM;
>   	}
>   
> -	ret = parent_create_sysfs_files(parent);
> -	if (ret)
> +	parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
> +					       NULL, &parent->dev->kobj);
> +	if (!parent->mdev_types_kset)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < nr_types; i++) {
> +		ret = mdev_type_add(parent, types[i]);
> +		if (ret)
> +			break;
> +	}

Above code should be in parent_create_sysfs_files(), all sysfs related 
stuff should be placed in mdev_sysfs.c

> +	parent->types = types;
> +	parent->nr_types = i;
> +
> +	if (ret) {
> +		mdev_unregister_parent(parent);
>   		return ret;
> +	}
>   
>   	ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
>   	if (ret)
> @@ -132,13 +126,17 @@ void mdev_unregister_parent(struct mdev_parent *parent)
>   {
>   	char *env_string = "MDEV_STATE=unregistered";
>   	char *envp[] = { env_string, NULL };
> +	int i;
>   
>   	dev_info(parent->dev, "MDEV: Unregistering\n");
>   
> +	for (i = 0; i < parent->nr_types; i++)
> +		mdev_type_remove(parent->types[i]);
> +									
>   	down_write(&parent->unreg_sem);
>   	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);
> +	kset_unregister(parent->mdev_types_kset);
>   	up_write(&parent->unreg_sem);
>

Same as above, parent_remove_sysfs_files() can be updated accordingly 
instead of moving it here.

Rest looks fine to me.

Thanks,
Kirti


^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files
  2022-06-14  4:54 ` [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files Christoph Hellwig
@ 2022-06-15 20:03   ` Kirti Wankhede
  2022-06-19  7:37     ` Christoph Hellwig
  0 siblings, 1 reply; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:03 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian,
	Neo Jia, Tarun Gupta, Dheeraj Nigam


Does this change really required? When mdev was implemented we tried to 
keep all sysfs related stuff in mdev_sysfs.c file and I would still like 
to stick to that approach.

Thanks.
Kirti

On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> Just fold these two trivial helpers into their only callers.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> ---
>   drivers/vfio/mdev/mdev_core.c    | 12 ++++++++++--
>   drivers/vfio/mdev/mdev_private.h |  3 ---
>   drivers/vfio/mdev/mdev_sysfs.c   | 28 ----------------------------
>   3 files changed, 10 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
> index 71c7f4e521a74..fe4230b21993d 100644
> --- a/drivers/vfio/mdev/mdev_core.c
> +++ b/drivers/vfio/mdev/mdev_core.c
> @@ -44,7 +44,8 @@ static void mdev_device_remove_common(struct mdev_device *mdev)
>   {
>   	struct mdev_parent *parent = mdev->type->parent;
>   
> -	mdev_remove_sysfs_files(mdev);
> +	sysfs_remove_link(&mdev->dev.kobj, "mdev_type");
> +	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
>   	device_del(&mdev->dev);
>   	lockdep_assert_held(&parent->unreg_sem);
>   	/* Balances with device_initialize() */
> @@ -212,16 +213,23 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
>   	if (ret)
>   		goto out_del;
>   
> -	ret = mdev_create_sysfs_files(mdev);
> +	ret = sysfs_create_link(type->devices_kobj, &mdev->dev.kobj,
> +				dev_name(&mdev->dev));
>   	if (ret)
>   		goto out_del;
>   
> +	ret = sysfs_create_link(&mdev->dev.kobj, &type->kobj, "mdev_type");
> +	if (ret)
> +		goto out_remove_type_link;
> +
>   	mdev->active = true;
>   	dev_dbg(&mdev->dev, "MDEV: created\n");
>   	up_read(&parent->unreg_sem);
>   
>   	return 0;
>   
> +out_remove_type_link:
> +	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
>   out_del:
>   	device_del(&mdev->dev);
>   out_unlock:
> diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
> index 6980f504018f3..346b9ec320466 100644
> --- a/drivers/vfio/mdev/mdev_private.h
> +++ b/drivers/vfio/mdev/mdev_private.h
> @@ -20,9 +20,6 @@ extern const struct attribute_group *mdev_device_groups[];
>   #define to_mdev_type(_kobj)		\
>   	container_of(_kobj, struct mdev_type, kobj)
>   
> -int  mdev_create_sysfs_files(struct mdev_device *mdev);
> -void mdev_remove_sysfs_files(struct mdev_device *mdev);
> -
>   int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type);
>   void mdev_type_remove(struct mdev_type *type);
>   
> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
> index 09745e8e120f9..dd81b91afcf7d 100644
> --- a/drivers/vfio/mdev/mdev_sysfs.c
> +++ b/drivers/vfio/mdev/mdev_sysfs.c
> @@ -170,31 +170,3 @@ const struct attribute_group *mdev_device_groups[] = {
>   	&mdev_device_group,
>   	NULL
>   };
> -
> -int mdev_create_sysfs_files(struct mdev_device *mdev)
> -{
> -	struct mdev_type *type = mdev->type;
> -	struct kobject *kobj = &mdev->dev.kobj;
> -	int ret;
> -
> -	ret = sysfs_create_link(type->devices_kobj, kobj, dev_name(&mdev->dev));
> -	if (ret)
> -		return ret;
> -
> -	ret = sysfs_create_link(kobj, &type->kobj, "mdev_type");
> -	if (ret)
> -		goto type_link_failed;
> -	return ret;
> -
> -type_link_failed:
> -	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
> -	return ret;
> -}
> -
> -void mdev_remove_sysfs_files(struct mdev_device *mdev)
> -{
> -	struct kobject *kobj = &mdev->dev.kobj;
> -
> -	sysfs_remove_link(kobj, "mdev_type");
> -	sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
> -}

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 05/13] vfio/mdev: remove mdev_from_dev
  2022-06-14  4:54 ` [PATCH 05/13] vfio/mdev: remove mdev_from_dev Christoph Hellwig
@ 2022-06-15 20:06   ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:06 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian,
	Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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 fe4230b21993d..49a4a26787ce6 100644
> --- a/drivers/vfio/mdev/mdev_core.c
> +++ b/drivers/vfio/mdev/mdev_core.c
> @@ -54,10 +54,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 d28ddf0f561a0..409e86d343a05 100644
> --- a/include/linux/mdev.h
> +++ b/include/linux/mdev.h
> @@ -107,9 +107,5 @@ static inline struct device *mdev_dev(struct mdev_device *mdev)
>   {
>   	return &mdev->dev;
>   }
> -static inline struct mdev_device *mdev_from_dev(struct device *dev)
> -{
> -	return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL;
> -}
>   
>   #endif /* MDEV_H */

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 06/13] vfio/mdev: unexport mdev_bus_type
  2022-06-14  4:54 ` [PATCH 06/13] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
@ 2022-06-15 20:08   ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:08 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian,
	Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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 346b9ec320466..62a98b78d929d 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 409e86d343a05..dd11c142bf887 100644
> --- a/include/linux/mdev.h
> +++ b/include/linux/mdev.h
> @@ -92,8 +92,6 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
>   	return &mdev->uuid;
>   }
>   
> -extern struct bus_type mdev_bus_type;
> -
>   int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
>   		struct mdev_driver *mdev_driver, struct mdev_type **types,
>   		unsigned int nr_types);

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 07/13] vfio/mdev: remove mdev_parent_dev
  2022-06-14  4:54 ` [PATCH 07/13] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
@ 2022-06-15 20:11   ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:11 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian,
	Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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 599008bdc1dcb..27247b3bdcb57 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -202,9 +202,6 @@ Directories and files under the sysfs for Each Physical Device
>   
>   	sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
>   
> -  (or using mdev_parent_dev(mdev) to arrive at the parent device outside
> -  of the core mdev code)
> -
>   * device_api
>   
>     This attribute should show which device API is being created, for example,
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 1c6b7e8bec4fb..136f9c0df48b9 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -1549,7 +1549,7 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
>   
>   static int intel_vgpu_probe(struct mdev_device *mdev)
>   {
> -	struct device *pdev = mdev_parent_dev(mdev);
> +	struct device *pdev = mdev->type->parent->dev;
>   	struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
>   	struct intel_vgpu_type *type =
>   		container_of(mdev->type, struct intel_vgpu_type, type);
> diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
> index 49a4a26787ce6..479ae5ed6c392 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 dd11c142bf887..83c85a0247f25 100644
> --- a/include/linux/mdev.h
> +++ b/include/linux/mdev.h
> @@ -100,7 +100,6 @@ void mdev_unregister_parent(struct mdev_parent *parent);
>   int mdev_register_driver(struct mdev_driver *drv);
>   void mdev_unregister_driver(struct mdev_driver *drv);
>   
> -struct device *mdev_parent_dev(struct mdev_device *mdev);
>   static inline struct device *mdev_dev(struct mdev_device *mdev)
>   {
>   	return &mdev->dev;

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev
  2022-06-14  4:54 ` [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
@ 2022-06-15 20:13   ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:13 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Kevin Tian,
	Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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>

> ---
>   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 25b8d42a522ac..43d53736dfe3c 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -88,8 +88,7 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
>   {
> -	struct vfio_ccw_private *private =
> -		dev_get_drvdata(mtype_get_parent_dev(mtype));
> +	struct vfio_ccw_private *private = dev_get_drvdata(mtype->parent->dev);
>   
>   	return sprintf(buf, "%d\n", atomic_read(&private->avail));
>   }
> diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
> index 479ae5ed6c392..20513b7f6b5eb 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 83c85a0247f25..ecf964d34f2ca 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;

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code
  2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
  2022-06-14 10:10   ` Tian, Kevin
@ 2022-06-15 20:24   ` Kirti Wankhede
  2022-06-23 21:30   ` [PATCH 9/13] " Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:24 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe, Neo Jia,
	Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 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: 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               | 11 ++----
>   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, 38 insertions(+), 68 deletions(-)
> 
> diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
> index 27247b3bdcb57..e9913bfb4393b 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -204,7 +204,7 @@ Directories and files under the sysfs for Each Physical Device
>   
>   * device_api
>   
> -  This attribute should show which device API is being created, for example,
> +  This attribute shows which device API is being created, for example,
>     "vfio-pci" for a PCI device.
>   
>   * available_instances
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 136f9c0df48b9..44a418d897377 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -123,12 +123,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   	return sprintf(buf, "%u\n", type->avail_instance);
>   }
>   
> -static ssize_t device_api_show(struct mdev_type *mtype,
> -			       struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
> -}
> -
>   static ssize_t description_show(struct mdev_type *mtype,
>   				struct mdev_type_attribute *attr, char *buf)
>   {
> @@ -151,13 +145,11 @@ static ssize_t name_show(struct mdev_type *mtype,
>   }
>   
>   static MDEV_TYPE_ATTR_RO(available_instances);
> -static MDEV_TYPE_ATTR_RO(device_api);
>   static MDEV_TYPE_ATTR_RO(description);
>   static MDEV_TYPE_ATTR_RO(name);
>   
>   static const struct attribute *gvt_type_attrs[] = {
>   	&mdev_type_attr_available_instances.attr,
> -	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_description.attr,
>   	&mdev_type_attr_name.attr,
>   	NULL,
> @@ -1587,6 +1579,7 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
>   }
>   
>   static struct mdev_driver intel_vgpu_mdev_driver = {
> +	.device_api	= VFIO_DEVICE_API_PCI_STRING,
>   	.driver = {
>   		.name		= "intel_vgpu_mdev",
>   		.owner		= THIS_MODULE,
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index 43d53736dfe3c..730d87a96a305 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -77,13 +77,6 @@ static ssize_t name_show(struct mdev_type *mtype,
>   }
>   static MDEV_TYPE_ATTR_RO(name);
>   
> -static ssize_t device_api_show(struct mdev_type *mtype,
> -			       struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
> -}
> -static MDEV_TYPE_ATTR_RO(device_api);
> -
>   static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
> @@ -96,7 +89,6 @@ static MDEV_TYPE_ATTR_RO(available_instances);
>   
>   static const struct attribute *mdev_types_attrs[] = {
>   	&mdev_type_attr_name.attr,
> -	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
> @@ -636,6 +628,7 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
>   };
>   
>   struct mdev_driver vfio_ccw_mdev_driver = {
> +	.device_api = VFIO_DEVICE_API_CCW_STRING,
>   	.driver = {
>   		.name = "vfio_ccw_mdev",
>   		.owner = THIS_MODULE,
> @@ -648,7 +641,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
>   
>   int vfio_ccw_mdev_reg(struct subchannel *sch)
>   {
> -	sprintf(sch->mdev_type.sysfs_name, "io");
> +	strcat(sch->mdev_type.sysfs_name, "io");
>   	sch->mdev_types[0] = &sch->mdev_type;
>   	return mdev_register_parent(&sch->parent, &sch->dev,
>   				    &vfio_ccw_mdev_driver, sch->mdev_types,
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index ff25858b2ebbe..da21fd60877fb 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -529,17 +529,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   
>   static MDEV_TYPE_ATTR_RO(available_instances);
>   
> -static ssize_t device_api_show(struct mdev_type *mtype,
> -			       struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "%s\n", VFIO_DEVICE_API_AP_STRING);
> -}
> -
> -static MDEV_TYPE_ATTR_RO(device_api);
> -
>   static const struct attribute *vfio_ap_mdev_type_attrs[] = {
>   	&mdev_type_attr_name.attr,
> -	&mdev_type_attr_device_api.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
> @@ -1454,6 +1445,7 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
>   };
>   
>   static struct mdev_driver vfio_ap_matrix_driver = {
> +	.device_api = VFIO_DEVICE_API_AP_STRING,
>   	.driver = {
>   		.name = "vfio_ap_mdev",
>   		.owner = THIS_MODULE,
> diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
> index 5b3c94f4fb13d..60e8b9f6474e8 100644
> --- a/drivers/vfio/mdev/mdev_driver.c
> +++ b/drivers/vfio/mdev/mdev_driver.c
> @@ -55,8 +55,10 @@ struct bus_type mdev_bus_type = {
>    **/
>   int mdev_register_driver(struct mdev_driver *drv)
>   {
> -	if (!drv->types_attrs)
> +	if (!drv->types_attrs || !drv->device_api)
>   		return -EINVAL;
> +
> +	/* initialize common driver fields */
>   	drv->driver.bus = &mdev_bus_type;
>   	return driver_register(&drv->driver);
>   }
> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
> index dd81b91afcf7d..20763f1aa9f5a 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);
> @@ -84,8 +105,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,
>   };
>   
>   int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
> @@ -100,10 +122,6 @@ int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
>   	if (ret)
>   		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;
> @@ -118,8 +136,6 @@ 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;
> @@ -130,7 +146,6 @@ 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 ecf964d34f2ca..81e11e18b3e41 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 40b1c8a58157c..401a9a622673c 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] 59+ messages in thread

* Re: [PATCH 10/13] vfio/mdev: consolidate all the name sysfs into the core code
  2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
  2022-06-14 10:11   ` Tian, Kevin
@ 2022-06-15 20:31   ` Kirti Wankhede
  2022-06-23 21:32   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:31 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 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.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>

> ---
>   .../driver-api/vfio-mediated-device.rst       |  2 +-
>   drivers/gpu/drm/i915/gvt/kvmgt.c              |  8 -------
>   drivers/s390/cio/vfio_ccw_ops.c               |  9 +-------
>   drivers/s390/crypto/vfio_ap_ops.c             |  9 --------
>   drivers/vfio/mdev/mdev_sysfs.c                | 11 ++++++++++
>   include/linux/mdev.h                          |  1 +
>   samples/vfio-mdev/mbochs.c                    | 20 ++++--------------
>   samples/vfio-mdev/mdpy.c                      | 21 +++++--------------
>   samples/vfio-mdev/mtty.c                      | 18 ++++------------
>   9 files changed, 27 insertions(+), 72 deletions(-)
> 
> diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
> index e9913bfb4393b..87d207744db79 100644
> --- a/Documentation/driver-api/vfio-mediated-device.rst
> +++ b/Documentation/driver-api/vfio-mediated-device.rst
> @@ -219,7 +219,7 @@ Directories and files under the sysfs for Each Physical Device
>   
>   * name
>   
> -  This attribute should show human readable name. This is optional attribute.
> +  This attribute shows a human readable name.
>   
>   * description
>   
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 44a418d897377..191e64ef70acf 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->weight);
>   }
>   
> -static ssize_t name_show(struct mdev_type *mtype,
> -			 struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "%s\n", mtype->sysfs_name);
> -}
> -
>   static MDEV_TYPE_ATTR_RO(available_instances);
>   static MDEV_TYPE_ATTR_RO(description);
> -static MDEV_TYPE_ATTR_RO(name);
>   
>   static const struct attribute *gvt_type_attrs[] = {
>   	&mdev_type_attr_available_instances.attr,
>   	&mdev_type_attr_description.attr,
> -	&mdev_type_attr_name.attr,
>   	NULL,
>   };
>   
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index 730d87a96a305..35389f4b67dc5 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
> @@ -70,13 +70,6 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
>   	return NOTIFY_DONE;
>   }
>   
> -static ssize_t name_show(struct mdev_type *mtype,
> -			 struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
> -}
> -static MDEV_TYPE_ATTR_RO(name);
> -
>   static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
> @@ -88,7 +81,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   static MDEV_TYPE_ATTR_RO(available_instances);
>   
>   static const struct attribute *mdev_types_attrs[] = {
> -	&mdev_type_attr_name.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
> @@ -642,6 +634,7 @@ struct mdev_driver vfio_ccw_mdev_driver = {
>   int vfio_ccw_mdev_reg(struct subchannel *sch)
>   {
>   	strcat(sch->mdev_type.sysfs_name, "io");
> +	strcat(sch->mdev_type.pretty_name, "I/O subchannel (Non-QDIO)");
>   	sch->mdev_types[0] = &sch->mdev_type;
>   	return mdev_register_parent(&sch->parent, &sch->dev,
>   				    &vfio_ccw_mdev_driver, sch->mdev_types,
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index da21fd60877fb..d6b2e819a615e 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -511,14 +511,6 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev)
>   	atomic_inc(&matrix_dev->available_instances);
>   }
>   
> -static ssize_t name_show(struct mdev_type *mtype,
> -			 struct mdev_type_attribute *attr, char *buf)
> -{
> -	return sprintf(buf, "%s\n", VFIO_AP_MDEV_NAME_HWVIRT);
> -}
> -
> -static MDEV_TYPE_ATTR_RO(name);
> -
>   static ssize_t available_instances_show(struct mdev_type *mtype,
>   					struct mdev_type_attribute *attr,
>   					char *buf)
> @@ -530,7 +522,6 @@ static ssize_t available_instances_show(struct mdev_type *mtype,
>   static MDEV_TYPE_ATTR_RO(available_instances);
>   
>   static const struct attribute *vfio_ap_mdev_type_attrs[] = {
> -	&mdev_type_attr_name.attr,
>   	&mdev_type_attr_available_instances.attr,
>   	NULL,
>   };
> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
> index 20763f1aa9f5a..8384e2992c706 100644
> --- a/drivers/vfio/mdev/mdev_sysfs.c
> +++ b/drivers/vfio/mdev/mdev_sysfs.c
> @@ -81,9 +81,20 @@ 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)
> +{
> +	if (!mtype->pretty_name[0])
> +		return sprintf(buf, "%s\n", mtype->sysfs_name);
> +	return sprintf(buf, "%s\n", mtype->pretty_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 81e11e18b3e41..64ca2ba806ed3 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: */
>   	char sysfs_name[32];
> +	char pretty_name[32]; /* optional */
>   
>   	/* 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 401a9a622673c..1b2117772192f 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] 59+ messages in thread

* Re: [PATCH 11/13] vfio/mdev: consolidate all the available_instance sysfs into the core code
  2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
  2022-06-14 10:14   ` Tian, Kevin
@ 2022-06-15 20:37   ` Kirti Wankhede
  2022-06-23 21:36   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:37 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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: Kirti Wankhede <kwankhede@nvidia.com>


^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 12/13] vfio/mdev: consolidate all the description sysfs into the core code
  2022-06-14  4:54 ` [PATCH 12/13] vfio/mdev: consolidate all the description " Christoph Hellwig
@ 2022-06-15 20:52   ` Kirti Wankhede
  2022-06-23 21:37   ` Jason Gunthorpe
  1 sibling, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-15 20:52 UTC (permalink / raw)
  To: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson
  Cc: kvm, linux-s390, intel-gvt-dev, Neo Jia, Tarun Gupta, Dheeraj Nigam



On 6/14/2022 10:24 AM, Christoph Hellwig wrote:
> 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: Kirti Wankhede <kwankhede@nvidia.com>

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files
  2022-06-15 20:03   ` Kirti Wankhede
@ 2022-06-19  7:37     ` Christoph Hellwig
  0 siblings, 0 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-19  7:37 UTC (permalink / raw)
  To: Kirti Wankhede
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Jason Gunthorpe,
	Kevin Tian, Neo Jia, Tarun Gupta, Dheeraj Nigam

On Thu, Jun 16, 2022 at 01:33:30AM +0530, Kirti Wankhede wrote:
>
> Does this change really required? When mdev was implemented we tried to 
> keep all sysfs related stuff in mdev_sysfs.c file and I would still like to 
> stick to that approach.

It isn't strictly required, but it removes a lot of pointless boilerplate
code.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 03/13] vfio/mdev: simplify mdev_type handling
  2022-06-15 19:55   ` Kirti Wankhede
@ 2022-06-19  7:42     ` Christoph Hellwig
  0 siblings, 0 replies; 59+ messages in thread
From: Christoph Hellwig @ 2022-06-19  7:42 UTC (permalink / raw)
  To: Kirti Wankhede
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Tarun Gupta, Dheeraj Nigam

On Thu, Jun 16, 2022 at 01:25:25AM +0530, Kirti Wankhede wrote:
>> +	parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
>> +					       NULL, &parent->dev->kobj);
>> +	if (!parent->mdev_types_kset)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < nr_types; i++) {
>> +		ret = mdev_type_add(parent, types[i]);
>> +		if (ret)
>> +			break;
>> +	}
>
> Above code should be in parent_create_sysfs_files(), all sysfs related 
> stuff should be placed in mdev_sysfs.c

Yes, it could. But why?  This is core logic of the interface and has
nothing to do with sysfs.

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 1/13] vfio/mdev: make mdev.h standalone includable
  2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
  2022-06-14  9:50   ` Tian, Kevin
  2022-06-15 19:12   ` Kirti Wankhede
@ 2022-06-23 19:39   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 19:39 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:16AM +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: Kevin Tian <kevin.tian@intel.com>
> ---
>  drivers/gpu/drm/i915/gvt/kvmgt.c      | 2 --
>  drivers/s390/cio/vfio_ccw_drv.c       | 2 --
>  drivers/s390/crypto/vfio_ap_private.h | 1 -
>  drivers/vfio/mdev/mdev_core.c         | 2 --
>  drivers/vfio/mdev/mdev_driver.c       | 1 -
>  drivers/vfio/mdev/mdev_sysfs.c        | 2 --
>  include/linux/mdev.h                  | 3 +++
>  samples/vfio-mdev/mbochs.c            | 1 -
>  samples/vfio-mdev/mdpy.c              | 1 -
>  samples/vfio-mdev/mtty.c              | 2 --
>  10 files changed, 3 insertions(+), 14 deletions(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-15 19:29   ` Kirti Wankhede
@ 2022-06-23 20:18     ` Jason Gunthorpe
  2022-06-24 12:29       ` Kirti Wankhede
  0 siblings, 1 reply; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 20:18 UTC (permalink / raw)
  To: Kirti Wankhede
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta

On Thu, Jun 16, 2022 at 12:59:47AM +0530, Kirti Wankhede wrote:

> > @@ -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;
> > 
> 
> Here device reference is held and release multiple times for each mdev_type.
> It should be held once from mdev_register_parent() and released from
> mdev_unregister_parent().

It doesn't make any sense to put a paired references in the
register/unregister on the struct device - the caller is already
required to hold a reference until unregister completes.

The reason this is here is because the type->parent is used in a few
places and is put back in release:

@@ -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);
 }

If this was a simple sysfs kobj with only a show/store we wouldn't
need to do anything as the natural kobj parentage holds a ref up to
the struct device - but this kobj is used internally, ie dependent
from mdev_device_create(), independently of the normal sysfs
life-cycle so that doesn't protect enough either.

Perhaps after this series things could be reworked to use the parent
instead of the type in more places and perhaps take a device reference
on the parent not the kobj in mdev_device_create() (which is screwy
already), but at least this patch is correct as is.

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 2/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
  2022-06-14  9:54   ` Tian, Kevin
  2022-06-15 19:29   ` Kirti Wankhede
@ 2022-06-23 20:59   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 20:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:17AM +0200, Christoph Hellwig wrote:
> Simplify mdev_{un}register_device by requiring the caller to pass in
> a structure allocate as part of the parent device structure.  This
> removes the need for a list of parents and the separate mdev_parent
> refcount as we can simplify rely on the reference to the parent device.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> ---
>  .../driver-api/vfio-mediated-device.rst       |  12 +-
>  Documentation/s390/vfio-ap.rst                |   2 +-
>  Documentation/s390/vfio-ccw.rst               |   2 +-
>  drivers/gpu/drm/i915/gvt/gvt.h                |   2 +
>  drivers/gpu/drm/i915/gvt/kvmgt.c              |   5 +-
>  drivers/s390/cio/cio.h                        |   2 +
>  drivers/s390/cio/vfio_ccw_ops.c               |   6 +-
>  drivers/s390/crypto/vfio_ap_ops.c             |   5 +-
>  drivers/s390/crypto/vfio_ap_private.h         |   1 +
>  drivers/vfio/mdev/mdev_core.c                 | 116 +++---------------
>  drivers/vfio/mdev/mdev_private.h              |  23 ----
>  drivers/vfio/mdev/mdev_sysfs.c                |   4 +-
>  include/linux/mdev.h                          |  15 ++-
>  samples/vfio-mdev/mbochs.c                    |   5 +-
>  samples/vfio-mdev/mdpy.c                      |   5 +-
>  samples/vfio-mdev/mtty.c                      |   6 +-
>  16 files changed, 65 insertions(+), 146 deletions(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/13] vfio/mdev: simplify mdev_type handling
  2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
                     ` (2 preceding siblings ...)
  2022-06-15 19:55   ` Kirti Wankhede
@ 2022-06-23 21:27   ` Jason Gunthorpe
  2022-06-24 12:32     ` Kirti Wankhede
  3 siblings, 1 reply; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 21:27 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:18AM +0200, Christoph Hellwig wrote:

> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
> index b71ffc5594870..09745e8e120f9 100644
> --- a/drivers/vfio/mdev/mdev_sysfs.c
> +++ b/drivers/vfio/mdev/mdev_sysfs.c
> @@ -80,8 +80,6 @@ static void mdev_type_release(struct kobject *kobj)
>  	struct mdev_type *type = to_mdev_type(kobj);
>  
>  	pr_debug("Releasing group %s\n", kobj->name);
> -	/* Pairs with the get in add_mdev_supported_type() */
> -	put_device(type->parent->dev);

I couldn't figure out why is it now OK to delete this? 

It still looks required because mdev_core.c continues to use
mdev-type->parent in various places and that pointer was being
protected by the

   kobject_get(&type->kobj);

in mdev_device_create() through the above kref..

eg after the whole series is applied this looks troubled:

	/* Pairs with the get in mdev_device_create() */
	kobject_put(&mdev->type->kobj);

	mutex_lock(&mdev_list_lock);
	list_del(&mdev->next);
	mdev->type->parent->available_instances++;
        ^^^^^^^^^^^^^^^^^^^^^

As there is now nothing keeping parent or type alive?

I think what would be good here is to directly
get_device(type->parent->dev) in mdev_device_create() and put in
mdev_device_release() then it is really clear how parent and
parent->dev are kept alive.

It looks like we also have to keep the type around and ref'd too for
the sysfs manipulation.

But overall I think this is fine

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 9/13] vfio/mdev: consolidate all the device_api sysfs into the core code
  2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
  2022-06-14 10:10   ` Tian, Kevin
  2022-06-15 20:24   ` Kirti Wankhede
@ 2022-06-23 21:30   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 21:30 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:24AM +0200, 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: Kirti Wankhede <kwankhede@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>, with one nit:
                                               ^^^^^^^^^^^^^^^^

Script error?

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 10/13] vfio/mdev: consolidate all the name sysfs into the core code
  2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
  2022-06-14 10:11   ` Tian, Kevin
  2022-06-15 20:31   ` Kirti Wankhede
@ 2022-06-23 21:32   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 21:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:25AM +0200, 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.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> ---
>  .../driver-api/vfio-mediated-device.rst       |  2 +-
>  drivers/gpu/drm/i915/gvt/kvmgt.c              |  8 -------
>  drivers/s390/cio/vfio_ccw_ops.c               |  9 +-------
>  drivers/s390/crypto/vfio_ap_ops.c             |  9 --------
>  drivers/vfio/mdev/mdev_sysfs.c                | 11 ++++++++++
>  include/linux/mdev.h                          |  1 +
>  samples/vfio-mdev/mbochs.c                    | 20 ++++--------------
>  samples/vfio-mdev/mdpy.c                      | 21 +++++--------------
>  samples/vfio-mdev/mtty.c                      | 18 ++++------------
>  9 files changed, 27 insertions(+), 72 deletions(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 11/13] vfio/mdev: consolidate all the available_instance sysfs into the core code
  2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
  2022-06-14 10:14   ` Tian, Kevin
  2022-06-15 20:37   ` Kirti Wankhede
@ 2022-06-23 21:36   ` Jason Gunthorpe
  2 siblings, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 21:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:26AM +0200, Christoph Hellwig wrote:
> 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: 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               | 44 ++-----------------
>  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(+), 105 deletions(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 12/13] vfio/mdev: consolidate all the description sysfs into the core code
  2022-06-14  4:54 ` [PATCH 12/13] vfio/mdev: consolidate all the description " Christoph Hellwig
  2022-06-15 20:52   ` Kirti Wankhede
@ 2022-06-23 21:37   ` Jason Gunthorpe
  1 sibling, 0 replies; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-23 21:37 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Kirti Wankhede, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev

On Tue, Jun 14, 2022 at 06:54:27AM +0200, Christoph Hellwig wrote:
> 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: 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(-)

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-23 20:18     ` Jason Gunthorpe
@ 2022-06-24 12:29       ` Kirti Wankhede
  2022-06-24 12:33         ` Jason Gunthorpe
  0 siblings, 1 reply; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-24 12:29 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta



On 6/24/2022 1:48 AM, Jason Gunthorpe wrote:
> On Thu, Jun 16, 2022 at 12:59:47AM +0530, Kirti Wankhede wrote:
> 
>>> @@ -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;
>>>
>>
>> Here device reference is held and release multiple times for each mdev_type.
>> It should be held once from mdev_register_parent() and released from
>> mdev_unregister_parent().
> 
> It doesn't make any sense to put a paired references in the
> register/unregister on the struct device - the caller is already
> required to hold a reference until unregister completes.
>

then this need to be documented in the comment above.


> The reason this is here is because the type->parent is used in a few
> places and is put back in release:
> 
> @@ -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);
>   }
> 
> If this was a simple sysfs kobj with only a show/store we wouldn't
> need to do anything as the natural kobj parentage holds a ref up to
> the struct device - but this kobj is used internally, ie dependent
> from mdev_device_create(), independently of the normal sysfs
> life-cycle so that doesn't protect enough either.
> 


Life span of 'type' is from mdev_register_device to 
mdev_unregister_device. If device/parent is being unregistered then only 
types are removed, so referencing 'type' from mdev_device_create() is 
still safe. Therefore, parent device's reference should be held and 
release from register-unregister call.


Thanks,
Kirti

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 3/13] vfio/mdev: simplify mdev_type handling
  2022-06-23 21:27   ` [PATCH 3/13] " Jason Gunthorpe
@ 2022-06-24 12:32     ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-24 12:32 UTC (permalink / raw)
  To: Jason Gunthorpe, Christoph Hellwig
  Cc: Tony Krowiak, Halil Pasic, Jason Herne, Eric Farman,
	Matthew Rosato, Zhenyu Wang, Zhi Wang, Alex Williamson, kvm,
	linux-s390, intel-gvt-dev



On 6/24/2022 2:57 AM, Jason Gunthorpe wrote:
> On Tue, Jun 14, 2022 at 06:54:18AM +0200, Christoph Hellwig wrote:
> 
>> diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
>> index b71ffc5594870..09745e8e120f9 100644
>> --- a/drivers/vfio/mdev/mdev_sysfs.c
>> +++ b/drivers/vfio/mdev/mdev_sysfs.c
>> @@ -80,8 +80,6 @@ static void mdev_type_release(struct kobject *kobj)
>>   	struct mdev_type *type = to_mdev_type(kobj);
>>   
>>   	pr_debug("Releasing group %s\n", kobj->name);
>> -	/* Pairs with the get in add_mdev_supported_type() */
>> -	put_device(type->parent->dev);
> 
> I couldn't figure out why is it now OK to delete this?
> 
> It still looks required because mdev_core.c continues to use
> mdev-type->parent in various places and that pointer was being
> protected by the
> 
>     kobject_get(&type->kobj);
> 
> in mdev_device_create() through the above kref..
> 
> eg after the whole series is applied this looks troubled:
> 
> 	/* Pairs with the get in mdev_device_create() */
> 	kobject_put(&mdev->type->kobj);
> 
> 	mutex_lock(&mdev_list_lock);
> 	list_del(&mdev->next);
> 	mdev->type->parent->available_instances++;
>          ^^^^^^^^^^^^^^^^^^^^^
> 
> As there is now nothing keeping parent or type alive?
> 
> I think what would be good here is to directly
> get_device(type->parent->dev) in mdev_device_create() and put in
> mdev_device_release() then it is really clear how parent and
> parent->dev are kept alive.
> 
> It looks like we also have to keep the type around and ref'd too for
> the sysfs manipulation.
> 
> But overall I think this is fine
> 

See my reply on [PATCH 2/13].

Thanks,
Kirti



> Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-24 12:29       ` Kirti Wankhede
@ 2022-06-24 12:33         ` Jason Gunthorpe
  2022-06-24 12:53           ` Kirti Wankhede
  0 siblings, 1 reply; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-24 12:33 UTC (permalink / raw)
  To: Kirti Wankhede
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta

On Fri, Jun 24, 2022 at 05:59:58PM +0530, Kirti Wankhede wrote:

> > The reason this is here is because the type->parent is used in a few
> > places and is put back in release:
> > 
> > @@ -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);
> >   }
> > 
> > If this was a simple sysfs kobj with only a show/store we wouldn't
> > need to do anything as the natural kobj parentage holds a ref up to
> > the struct device - but this kobj is used internally, ie dependent
> > from mdev_device_create(), independently of the normal sysfs
> > life-cycle so that doesn't protect enough either.
> > 
> 
> 
> Life span of 'type' is from mdev_register_device to mdev_unregister_device.
> If device/parent is being unregistered then only types are removed, so
> referencing 'type' from mdev_device_create() is still safe. Therefore,
> parent device's reference should be held and release from
> register-unregister call.

No, I've already explained this.

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-24 12:33         ` Jason Gunthorpe
@ 2022-06-24 12:53           ` Kirti Wankhede
  2022-06-24 13:05             ` Jason Gunthorpe
  0 siblings, 1 reply; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-24 12:53 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta



On 6/24/2022 6:03 PM, Jason Gunthorpe wrote:
> On Fri, Jun 24, 2022 at 05:59:58PM +0530, Kirti Wankhede wrote:
> 
>>> The reason this is here is because the type->parent is used in a few
>>> places and is put back in release:
>>>
>>> @@ -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);
>>>    }
>>>
>>> If this was a simple sysfs kobj with only a show/store we wouldn't
>>> need to do anything as the natural kobj parentage holds a ref up to
>>> the struct device - but this kobj is used internally, ie dependent
>>> from mdev_device_create(), independently of the normal sysfs
>>> life-cycle so that doesn't protect enough either.
>>>
>>
>>
>> Life span of 'type' is from mdev_register_device to mdev_unregister_device.
>> If device/parent is being unregistered then only types are removed, so
>> referencing 'type' from mdev_device_create() is still safe. Therefore,
>> parent device's reference should be held and release from
>> register-unregister call.
> 
> No, I've already explained this.

Its not correct.

kobject_init_and_add(&type->kobj, ...) which called from
mdev_register_parent()
     -> parent_create_sysfs_files() holds reference for type->kobj

This is released from
  mdev_unregister_parent()
      -> parent_remove_sysfs_files()
          -> kset_unregister()

In the next patch [3/13] of this series, these calltraces are changed as
mdev_register_parent()
     -> mdev_type_add()
         -> kobject_init_and_add(&type->kobj, ...) holds reference for 
type->kobj

which is released from

mdev_unregister_parent()
     -> mdev_type_remove()
         -> kobject_put(&type->kobj)

Thanks,
Kirti

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-24 12:53           ` Kirti Wankhede
@ 2022-06-24 13:05             ` Jason Gunthorpe
  2022-06-24 13:14               ` Kirti Wankhede
  0 siblings, 1 reply; 59+ messages in thread
From: Jason Gunthorpe @ 2022-06-24 13:05 UTC (permalink / raw)
  To: Kirti Wankhede
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta

On Fri, Jun 24, 2022 at 06:23:48PM +0530, Kirti Wankhede wrote:
> 
> 
> On 6/24/2022 6:03 PM, Jason Gunthorpe wrote:
> > On Fri, Jun 24, 2022 at 05:59:58PM +0530, Kirti Wankhede wrote:
> > 
> > > > The reason this is here is because the type->parent is used in a few
> > > > places and is put back in release:
> > > > 
> > > > @@ -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);
> > > >    }
> > > > 
> > > > If this was a simple sysfs kobj with only a show/store we wouldn't
> > > > need to do anything as the natural kobj parentage holds a ref up to
> > > > the struct device - but this kobj is used internally, ie dependent
> > > > from mdev_device_create(), independently of the normal sysfs
> > > > life-cycle so that doesn't protect enough either.
> > > > 
> > > 
> > > 
> > > Life span of 'type' is from mdev_register_device to mdev_unregister_device.
> > > If device/parent is being unregistered then only types are removed, so
> > > referencing 'type' from mdev_device_create() is still safe. Therefore,
> > > parent device's reference should be held and release from
> > > register-unregister call.
> > 
> > No, I've already explained this.
> 
> Its not correct.
> 
> kobject_init_and_add(&type->kobj, ...) which called from
> mdev_register_parent()
>     -> parent_create_sysfs_files() holds reference for type->kobj
          -> add_mdev_supported_type_groups()
               -> add_mdev_supported_type()
                   -> kobject_init_and_add(&type->kobj)

> This is released from
>  mdev_unregister_parent()
>      -> parent_remove_sysfs_files()
>          -> kset_unregister()

It is not kset_unregister() that puts back.
           -> remove_mdev_supported_type()
	       -> kobject_put(&type->kobj) // pairs with kobject_init_and_add

So what is the issue? This is a properly paired usage of the ref.

> In the next patch [3/13] of this series, these calltraces are changed as
> mdev_register_parent()
>     -> mdev_type_add()
>         -> kobject_init_and_add(&type->kobj, ...) holds reference for
> type->kobj
> 
> which is released from
> 
> mdev_unregister_parent()
>     -> mdev_type_remove()
>         -> kobject_put(&type->kobj)

This is the same logic? What is the problem?

Jason

^ permalink raw reply	[flat|nested] 59+ messages in thread

* Re: [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure
  2022-06-24 13:05             ` Jason Gunthorpe
@ 2022-06-24 13:14               ` Kirti Wankhede
  0 siblings, 0 replies; 59+ messages in thread
From: Kirti Wankhede @ 2022-06-24 13:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christoph Hellwig, Tony Krowiak, Halil Pasic, Jason Herne,
	Eric Farman, Matthew Rosato, Zhenyu Wang, Zhi Wang,
	Alex Williamson, kvm, linux-s390, intel-gvt-dev, Neo Jia,
	Dheeraj Nigam, Tarun Gupta



On 6/24/2022 6:35 PM, Jason Gunthorpe wrote:
> On Fri, Jun 24, 2022 at 06:23:48PM +0530, Kirti Wankhede wrote:
>>
>>
>> On 6/24/2022 6:03 PM, Jason Gunthorpe wrote:
>>> On Fri, Jun 24, 2022 at 05:59:58PM +0530, Kirti Wankhede wrote:
>>>
>>>>> The reason this is here is because the type->parent is used in a few
>>>>> places and is put back in release:
>>>>>
>>>>> @@ -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);
>>>>>     }
>>>>>
>>>>> If this was a simple sysfs kobj with only a show/store we wouldn't
>>>>> need to do anything as the natural kobj parentage holds a ref up to
>>>>> the struct device - but this kobj is used internally, ie dependent
>>>>> from mdev_device_create(), independently of the normal sysfs
>>>>> life-cycle so that doesn't protect enough either.
>>>>>
>>>>
>>>>
>>>> Life span of 'type' is from mdev_register_device to mdev_unregister_device.
>>>> If device/parent is being unregistered then only types are removed, so
>>>> referencing 'type' from mdev_device_create() is still safe. Therefore,
>>>> parent device's reference should be held and release from
>>>> register-unregister call.
>>>
>>> No, I've already explained this.
>>
>> Its not correct.
>>
>> kobject_init_and_add(&type->kobj, ...) which called from
>> mdev_register_parent()
>>      -> parent_create_sysfs_files() holds reference for type->kobj
>            -> add_mdev_supported_type_groups()
>                 -> add_mdev_supported_type()
>                     -> kobject_init_and_add(&type->kobj)
> 
>> This is released from
>>   mdev_unregister_parent()
>>       -> parent_remove_sysfs_files()
>>           -> kset_unregister()
> 
> It is not kset_unregister() that puts back.
>             -> remove_mdev_supported_type()
> 	       -> kobject_put(&type->kobj) // pairs with kobject_init_and_add
> 

that's correct, my bad.

> So what is the issue? This is a properly paired usage of the ref.
> 
>> In the next patch [3/13] of this series, these calltraces are changed as
>> mdev_register_parent()
>>      -> mdev_type_add()
>>          -> kobject_init_and_add(&type->kobj, ...) holds reference for
>> type->kobj
>>
>> which is released from
>>
>> mdev_unregister_parent()
>>      -> mdev_type_remove()
>>          -> kobject_put(&type->kobj)
> 
> This is the same logic? What is the problem?
> 

Pasting here your comment:
 >>>>> the struct device - but this kobj is used internally, ie dependent
 >>>>> from mdev_device_create(), independently of the normal sysfs
 >>>>> life-cycle so that doesn't protect enough either.

Since there references are held, its safe.

Thanks,
Kirti


^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2022-06-24 13:14 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-14  4:54 simplify the mdev interface v2 Christoph Hellwig
2022-06-14  4:54 ` [PATCH 01/13] vfio/mdev: make mdev.h standalone includable Christoph Hellwig
2022-06-14  9:50   ` Tian, Kevin
2022-06-15 19:12   ` Kirti Wankhede
2022-06-23 19:39   ` [PATCH 1/13] " Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 02/13] vfio/mdev: embedd struct mdev_parent in the parent data structure Christoph Hellwig
2022-06-14  9:54   ` Tian, Kevin
2022-06-15 19:29   ` Kirti Wankhede
2022-06-23 20:18     ` Jason Gunthorpe
2022-06-24 12:29       ` Kirti Wankhede
2022-06-24 12:33         ` Jason Gunthorpe
2022-06-24 12:53           ` Kirti Wankhede
2022-06-24 13:05             ` Jason Gunthorpe
2022-06-24 13:14               ` Kirti Wankhede
2022-06-23 20:59   ` [PATCH 2/13] " Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 03/13] vfio/mdev: simplify mdev_type handling Christoph Hellwig
2022-06-14  6:14   ` Yi Liu
2022-06-14 10:06   ` Tian, Kevin
2022-06-15  6:28     ` Christoph Hellwig
2022-06-15  6:11       ` Zhenyu Wang
2022-06-15 19:55   ` Kirti Wankhede
2022-06-19  7:42     ` Christoph Hellwig
2022-06-23 21:27   ` [PATCH 3/13] " Jason Gunthorpe
2022-06-24 12:32     ` Kirti Wankhede
2022-06-14  4:54 ` [PATCH 04/13] vfio/mdev: remove mdev_{create,remove}_sysfs_files Christoph Hellwig
2022-06-15 20:03   ` Kirti Wankhede
2022-06-19  7:37     ` Christoph Hellwig
2022-06-14  4:54 ` [PATCH 05/13] vfio/mdev: remove mdev_from_dev Christoph Hellwig
2022-06-15 20:06   ` Kirti Wankhede
2022-06-14  4:54 ` [PATCH 06/13] vfio/mdev: unexport mdev_bus_type Christoph Hellwig
2022-06-15 20:08   ` Kirti Wankhede
2022-06-14  4:54 ` [PATCH 07/13] vfio/mdev: remove mdev_parent_dev Christoph Hellwig
2022-06-15 20:11   ` Kirti Wankhede
2022-06-14  4:54 ` [PATCH 08/13] vfio/mdev: remove mtype_get_parent_dev Christoph Hellwig
2022-06-15 20:13   ` Kirti Wankhede
2022-06-14  4:54 ` [PATCH 09/13] vfio/mdev: consolidate all the device_api sysfs into the core code Christoph Hellwig
2022-06-14 10:10   ` Tian, Kevin
2022-06-15 20:24   ` Kirti Wankhede
2022-06-23 21:30   ` [PATCH 9/13] " Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 10/13] vfio/mdev: consolidate all the name " Christoph Hellwig
2022-06-14 10:11   ` Tian, Kevin
2022-06-15 20:31   ` Kirti Wankhede
2022-06-23 21:32   ` Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 11/13] vfio/mdev: consolidate all the available_instance " Christoph Hellwig
2022-06-14 10:14   ` Tian, Kevin
2022-06-14 10:29     ` Tian, Kevin
2022-06-15 20:37   ` Kirti Wankhede
2022-06-23 21:36   ` Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 12/13] vfio/mdev: consolidate all the description " Christoph Hellwig
2022-06-15 20:52   ` Kirti Wankhede
2022-06-23 21:37   ` Jason Gunthorpe
2022-06-14  4:54 ` [PATCH 13/13] vfio/mdev: add mdev available instance checking to the core Christoph Hellwig
2022-06-14 10:32   ` Tian, Kevin
2022-06-15  6:29     ` Christoph Hellwig
2022-06-14  5:03 ` simplify the mdev interface v2 Yi Liu
2022-06-14  5:17   ` Christoph Hellwig
2022-06-14  5:30     ` Yi Liu
2022-06-14  5:44       ` Christoph Hellwig
2022-06-14  5:47         ` Yi Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.