All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/34] Convert DRM to XArray
@ 2019-02-21 18:41 Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 01/34] drm: Convert drm_minors_idr " Matthew Wilcox
                   ` (34 more replies)
  0 siblings, 35 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

I intend to remove the IDR and the radix tree interfaces from Linux.
Converting each user from either the IDR or radix tree interface varies
from the trivial 1:1 replacement to a complete rewrite of the locking.
Despite the best efforts of our automated testers (who have caught many
of my mistakes), I cannot claim that my conversions of code are free
from bugs.

Please check these patches over carefully and test them; there may be
off-by-one errors, locking mistakes, or various other failures on my part.
The patches are based on the latest XArray API which can be found here:
http://git.infradead.org/users/willy/linux-dax.git/shortlog/refs/heads/xarray
which I intend to submit during the upcoming merge window.

Substantive interface changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 - The IDR and radix tree required callers to handle their own locking.
   The XArray embeds a spinlock which is taken for modifications to
   the data structure; plain lookups occur under the RCU read lock or
   under the spinlock.
 - You can take the spinlock yourself (xa_lock() and friends) to protect
   related data.
 - idr_alloc() returned -ENOSPC, radix_tree_insert() returned -EEXIST.
   xa_insert() and xa_alloc() return -EBUSY.
 - The search keys which the radix tree calls "tags", the XArray calls
   "marks".
 - There is no preloading in the XArray API.  If your locking is
   exceptionally complicated, you may need to use xa_reserve(), but
   there are only 6 callers of xa_reserve(), so it's quite uncommon.
 - The radix tree provided GFP flags as part of the tree definition;
   the XArray (like the IDR) passes GFP flags at the point of allocation.
 - radix_tree_insert() of a NULL pointer was not well-specified.  The
   XArray treats it as reserving the entry (it reads back as NULL but
   a subsequent xa_insert() to that slot will fail).
 - xa_alloc_cyclic() returns 1 if the allocation wraps, unlike
   idr_alloc_cyclic() which provides no indication.
 - There is no equivalent to idr_for_each(); the xa_for_each() iterator
   is similar to idr_for_each_entry().
 - idr_replace() has no exact equivalent.  Some users relied on its exact
   semantics of only storing if the entry was non-NULL, but all users of
   idr_replace() were able to use xa_store().
 - The family of radix tree gang lookup functions have been replaced with
   xa_extract().

Matthew Wilcox (34):
  drm: Convert drm_minors_idr to XArray
  drm: Convert aux_idr to XArray
  drm: Convert object_name_idr to XArray
  drm: Convert object_idr to XArray
  drm: Convert syncobj_idr to XArray
  drm: Convert magic_map to XArray
  drm: Convert lessee_idr to XArray
  drm: Remove linked lists for lessees
  drm: Convert ctx_idr to XArray
  drm: Convert tile_idr to XArray
  drm: Convert crtc_idr to XArray
  drm/agp: Convert bo_list_handles to XArray
  drm/amdgpu: Convert ctx_handles to XArray
  drm/amdgpu: Convert pasid_idr to XArray
  drm/amdkfd: Convert event_idr to XArray
  drm/amdkfd: Convert alloc_idr to XArray
  drm/etnaviv: Convert fence_idr to XArray
  drm/i915: Convert handles_vma to XArray
  drm/i915: Convert spt_tree to XArray
  drm/i915: Convert page_track_tree to XArray
  drm/i915: Convert get_page to XArray
  drm/i915: Convert object_idr to IDA
  drm/i915: Convert context_idr to XArray
  drm/i915: Convert metrics_idr to XArray
  drm/i915: Convert vgpus_idr to XArray
  drm/qxl: Convert release_idr to XArray
  drm/qxl: Convert surf_id_idr to XArray
  drm/tegra: Convert contexts IDR to XArray
  drm/vc4: Convert perfmon IDR to XArray
  drm/sis: Convert object_idr to XArray
  drm/vgem: Convert fence_idr to XArray
  drm/via: Convert object_idr to XArray
  drm/vmwgfx: Convert base IDR to XArray
  drm/vmwgfx: Convert res_idr to XArray

 Documentation/gpu/todo.rst                    |   3 -
 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c   |  22 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c       |  42 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h       |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c       |  23 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c     |   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c        |  66 ++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h        |   3 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c         |  12 +-
 drivers/gpu/drm/amd/amdkfd/kfd_events.c       |  71 +++----
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |   4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_process.c      |  32 ++-
 drivers/gpu/drm/drm_auth.c                    |  27 +--
 drivers/gpu/drm/drm_connector.c               |  27 +--
 drivers/gpu/drm/drm_context.c                 |  42 ++--
 drivers/gpu/drm/drm_debugfs.c                 |  19 +-
 drivers/gpu/drm/drm_dp_aux_dev.c              |  41 ++--
 drivers/gpu/drm/drm_drv.c                     |  49 ++---
 drivers/gpu/drm/drm_gem.c                     |  78 +++----
 drivers/gpu/drm/drm_lease.c                   | 201 ++++++++----------
 drivers/gpu/drm/drm_mode_config.c             |   6 +-
 drivers/gpu/drm/drm_mode_object.c             |  47 ++--
 drivers/gpu/drm/drm_syncobj.c                 |  64 ++----
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |  16 +-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c         |   5 +-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h         |   3 +-
 drivers/gpu/drm/etnaviv/etnaviv_sched.c       |   8 +-
 drivers/gpu/drm/i915/gvt/display.c            |   5 +-
 drivers/gpu/drm/i915/gvt/dmabuf.c             |   7 +-
 drivers/gpu/drm/i915/gvt/gtt.c                |  18 +-
 drivers/gpu/drm/i915/gvt/gtt.h                |   2 +-
 drivers/gpu/drm/i915/gvt/gvt.c                |   4 +-
 drivers/gpu/drm/i915/gvt/gvt.h                |   9 +-
 drivers/gpu/drm/i915/gvt/kvmgt.c              |   2 +-
 drivers/gpu/drm/i915/gvt/page_track.c         |   6 +-
 drivers/gpu/drm/i915/gvt/sched_policy.c       |   2 +-
 drivers/gpu/drm/i915/gvt/vgpu.c               |  24 +--
 drivers/gpu/drm/i915/i915_debugfs.c           |  48 +++--
 drivers/gpu/drm/i915/i915_drv.h               |   9 +-
 drivers/gpu/drm/i915/i915_gem.c               |  40 ++--
 drivers/gpu/drm/i915/i915_gem_context.c       |  43 ++--
 drivers/gpu/drm/i915/i915_gem_context.h       |   6 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c    |   6 +-
 drivers/gpu/drm/i915/i915_gem_object.h        |   6 +-
 drivers/gpu/drm/i915/i915_perf.c              |  39 ++--
 .../gpu/drm/i915/selftests/i915_gem_context.c |   7 +-
 drivers/gpu/drm/i915/selftests/mock_context.c |   2 +-
 drivers/gpu/drm/msm/msm_gem_submit.c          |  12 +-
 drivers/gpu/drm/qxl/qxl_cmd.c                 |  60 ++----
 drivers/gpu/drm/qxl/qxl_drv.h                 |   6 +-
 drivers/gpu/drm/qxl/qxl_kms.c                 |   8 +-
 drivers/gpu/drm/qxl/qxl_release.c             |  54 ++---
 drivers/gpu/drm/sis/sis_drv.c                 |   4 +-
 drivers/gpu/drm/sis/sis_drv.h                 |   2 +-
 drivers/gpu/drm/sis/sis_mm.c                  |  17 +-
 drivers/gpu/drm/tegra/drm.c                   |  35 ++-
 drivers/gpu/drm/v3d/v3d_gem.c                 |  17 +-
 drivers/gpu/drm/vc4/vc4_drv.h                 |   2 +-
 drivers/gpu/drm/vc4/vc4_gem.c                 |   6 +-
 drivers/gpu/drm/vc4/vc4_perfmon.c             |  33 ++-
 drivers/gpu/drm/vgem/vgem_drv.h               |   3 +-
 drivers/gpu/drm/vgem/vgem_fence.c             |  43 ++--
 drivers/gpu/drm/via/via_drv.h                 |   2 +-
 drivers/gpu/drm/via/via_map.c                 |   4 +-
 drivers/gpu/drm/via/via_mm.c                  |  11 +-
 drivers/gpu/drm/vmwgfx/ttm_object.c           |  29 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c           |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h           |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c      |  31 +--
 include/drm/drm_auth.h                        |  11 +-
 include/drm/drm_device.h                      |   4 +-
 include/drm/drm_file.h                        |  15 +-
 include/drm/drm_mode_config.h                 |  18 +-
 75 files changed, 673 insertions(+), 983 deletions(-)

-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 01/34] drm: Convert drm_minors_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-22  9:11   ` Daniel Vetter
  2019-02-21 18:41 ` [PATCH 02/34] drm: Convert aux_idr " Matthew Wilcox
                   ` (33 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Divide all the indices by 64 to save memory.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_drv.c | 49 ++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 12e5e2be7890..17ed29f49060 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -64,8 +64,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
 module_param_named(debug, drm_debug, int, 0600);
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+static DEFINE_XARRAY_FLAGS(drm_minors, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -109,7 +108,6 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
 	struct drm_minor *minor;
-	unsigned long flags;
 	int r;
 
 	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
@@ -118,22 +116,12 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 
 	minor->type = type;
 	minor->dev = dev;
+	minor->index = 64 * type;
 
-	idr_preload(GFP_KERNEL);
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	r = idr_alloc(&drm_minors_idr,
-		      NULL,
-		      64 * type,
-		      64 * (type + 1),
-		      GFP_NOWAIT);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
-	idr_preload_end();
-
+	r = xa_insert_irq(&drm_minors, minor->index / 64, NULL, GFP_KERNEL);
 	if (r < 0)
 		goto err_free;
 
-	minor->index = r;
-
 	minor->kdev = drm_sysfs_minor_alloc(minor);
 	if (IS_ERR(minor->kdev)) {
 		r = PTR_ERR(minor->kdev);
@@ -144,9 +132,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 	return 0;
 
 err_index:
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_erase_irq(&drm_minors, minor->index / 64);
 err_free:
 	kfree(minor);
 	return r;
@@ -164,9 +150,9 @@ static void drm_minor_free(struct drm_device *dev, unsigned int type)
 
 	put_device(minor->kdev);
 
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_lock_irqsave(&drm_minors, flags);
+	__xa_erase(&drm_minors, minor->index / 64);
+	xa_unlock_irqrestore(&drm_minors, flags);
 
 	kfree(minor);
 	*slot = NULL;
@@ -195,9 +181,9 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type)
 		goto err_debugfs;
 
 	/* replace NULL with @minor so lookups will succeed from now on */
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_replace(&drm_minors_idr, minor, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_lock_irqsave(&drm_minors, flags);
+	__xa_store(&drm_minors, minor->index / 64, minor, 0);
+	xa_unlock_irqrestore(&drm_minors, flags);
 
 	DRM_DEBUG("new minor registered %d\n", minor->index);
 	return 0;
@@ -217,9 +203,9 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
 		return;
 
 	/* replace @minor with NULL so lookups will fail from now on */
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_replace(&drm_minors_idr, NULL, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_lock_irqsave(&drm_minors, flags);
+	__xa_store(&drm_minors, minor->index / 64, NULL, 0);
+	xa_unlock_irqrestore(&drm_minors, flags);
 
 	device_del(minor->kdev);
 	dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -240,11 +226,11 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id)
 	struct drm_minor *minor;
 	unsigned long flags;
 
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	minor = idr_find(&drm_minors_idr, minor_id);
+	xa_lock_irqsave(&drm_minors, flags);
+	minor = xa_load(&drm_minors, minor_id / 64);
 	if (minor)
 		drm_dev_get(minor->dev);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_unlock_irqrestore(&drm_minors, flags);
 
 	if (!minor) {
 		return ERR_PTR(-ENODEV);
@@ -958,7 +944,7 @@ static void drm_core_exit(void)
 	unregister_chrdev(DRM_MAJOR, "drm");
 	debugfs_remove(drm_debugfs_root);
 	drm_sysfs_destroy();
-	idr_destroy(&drm_minors_idr);
+	WARN_ON(!xa_empty(&drm_minors));
 	drm_connector_ida_destroy();
 }
 
@@ -967,7 +953,6 @@ static int __init drm_core_init(void)
 	int ret;
 
 	drm_connector_ida_init();
-	idr_init(&drm_minors_idr);
 
 	ret = drm_sysfs_init();
 	if (ret < 0) {
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 02/34] drm: Convert aux_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 01/34] drm: Convert drm_minors_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-25 17:57   ` Ville Syrjälä
  2019-02-21 18:41 ` [PATCH 03/34] drm: Convert object_name_idr " Matthew Wilcox
                   ` (32 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_dp_aux_dev.c | 41 +++++++++++++-------------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c b/drivers/gpu/drm/drm_dp_aux_dev.c
index 0e4f25d63fd2..393a32976900 100644
--- a/drivers/gpu/drm/drm_dp_aux_dev.c
+++ b/drivers/gpu/drm/drm_dp_aux_dev.c
@@ -49,8 +49,7 @@ struct drm_dp_aux_dev {
 
 #define DRM_AUX_MINORS	256
 #define AUX_MAX_OFFSET	(1 << 20)
-static DEFINE_IDR(aux_idr);
-static DEFINE_MUTEX(aux_idr_mutex);
+static DEFINE_XARRAY_ALLOC(aux_xa);
 static struct class *drm_dp_aux_dev_class;
 static int drm_dev_major = -1;
 
@@ -58,19 +57,21 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
 {
 	struct drm_dp_aux_dev *aux_dev = NULL;
 
-	mutex_lock(&aux_idr_mutex);
-	aux_dev = idr_find(&aux_idr, index);
+	xa_lock(&aux_xa);
+	aux_dev = xa_load(&aux_xa, index);
 	if (!kref_get_unless_zero(&aux_dev->refcount))
 		aux_dev = NULL;
-	mutex_unlock(&aux_idr_mutex);
+	xa_unlock(&aux_xa);
 
 	return aux_dev;
 }
 
 static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
 {
+	static u32 next;
+
 	struct drm_dp_aux_dev *aux_dev;
-	int index;
+	int err;
 
 	aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
 	if (!aux_dev)
@@ -79,15 +80,12 @@ static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
 	atomic_set(&aux_dev->usecount, 1);
 	kref_init(&aux_dev->refcount);
 
-	mutex_lock(&aux_idr_mutex);
-	index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
-				 GFP_KERNEL);
-	mutex_unlock(&aux_idr_mutex);
-	if (index < 0) {
+	err = xa_alloc_cyclic(&aux_xa, &aux_dev->index, aux_dev,
+			XA_LIMIT(0, DRM_AUX_MINORS), &next, GFP_KERNEL);
+	if (err < 0) {
 		kfree(aux_dev);
-		return ERR_PTR(index);
+		return ERR_PTR(err);
 	}
-	aux_dev->index = index;
 
 	return aux_dev;
 }
@@ -246,22 +244,19 @@ static const struct file_operations auxdev_fops = {
 
 static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
 {
-	struct drm_dp_aux_dev *iter, *aux_dev = NULL;
-	int id;
+	struct drm_dp_aux_dev *aux_dev;
+	unsigned long id;
 
 	/* don't increase kref count here because this function should only be
 	 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
 	 * least one reference - the one that drm_dp_aux_register_devnode
 	 * created
 	 */
-	mutex_lock(&aux_idr_mutex);
-	idr_for_each_entry(&aux_idr, iter, id) {
-		if (iter->aux == aux) {
-			aux_dev = iter;
+	xa_for_each(&aux_xa, id, aux_dev) {
+		if (aux_dev->aux == aux)
 			break;
-		}
 	}
-	mutex_unlock(&aux_idr_mutex);
+
 	return aux_dev;
 }
 
@@ -274,9 +269,7 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
 	if (!aux_dev) /* attach must have failed */
 		return;
 
-	mutex_lock(&aux_idr_mutex);
-	idr_remove(&aux_idr, aux_dev->index);
-	mutex_unlock(&aux_idr_mutex);
+	xa_erase(&aux_xa, aux_dev->index);
 
 	atomic_dec(&aux_dev->usecount);
 	wait_var_event(&aux_dev->usecount, !atomic_read(&aux_dev->usecount));
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 03/34] drm: Convert object_name_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 01/34] drm: Convert drm_minors_idr " Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 02/34] drm: Convert aux_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-22  9:17   ` Daniel Vetter
  2019-02-21 18:41 ` [PATCH 04/34] drm: Convert object_idr " Matthew Wilcox
                   ` (31 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Leave the object_name_lock in place for now as I'm not certain it can be
removed safely.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_debugfs.c | 19 ++++++-------------
 drivers/gpu/drm/drm_gem.c     | 11 +++++------
 include/drm/drm_device.h      |  2 +-
 3 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index f8468eae0503..2bf08f293331 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -106,27 +106,20 @@ static int drm_clients_info(struct seq_file *m, void *data)
 	return 0;
 }
 
-static int drm_gem_one_name_info(int id, void *ptr, void *data)
-{
-	struct drm_gem_object *obj = ptr;
-	struct seq_file *m = data;
-
-	seq_printf(m, "%6d %8zd %7d %8d\n",
-		   obj->name, obj->size,
-		   obj->handle_count,
-		   kref_read(&obj->refcount));
-	return 0;
-}
-
 static int drm_gem_name_info(struct seq_file *m, void *data)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_device *dev = node->minor->dev;
+	struct drm_gem_object *obj;
+	unsigned long index;
 
 	seq_printf(m, "  name     size handles refcount\n");
 
 	mutex_lock(&dev->object_name_lock);
-	idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m);
+	xa_for_each(&dev->object_names, index, obj) {
+		seq_printf(m, "%6d %8zd %7d %8d\n", obj->name, obj->size,
+				obj->handle_count, kref_read(&obj->refcount));
+	}
 	mutex_unlock(&dev->object_name_lock);
 
 	return 0;
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8b55ece97967..0a52a958cffe 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -98,7 +98,7 @@ drm_gem_init(struct drm_device *dev)
 	struct drm_vma_offset_manager *vma_offset_manager;
 
 	mutex_init(&dev->object_name_lock);
-	idr_init_base(&dev->object_name_idr, 1);
+	xa_init_flags(&dev->object_names, XA_FLAGS_ALLOC1);
 
 	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);
 	if (!vma_offset_manager) {
@@ -205,7 +205,7 @@ static void drm_gem_object_handle_free(struct drm_gem_object *obj)
 
 	/* Remove any name for this object */
 	if (obj->name) {
-		idr_remove(&dev->object_name_idr, obj->name);
+		xa_erase(&dev->object_names, obj->name);
 		obj->name = 0;
 	}
 }
@@ -714,11 +714,10 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
 	}
 
 	if (!obj->name) {
-		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_KERNEL);
+		ret = xa_alloc(&dev->object_names, &obj->name, obj,
+				xa_limit_32b, GFP_KERNEL);
 		if (ret < 0)
 			goto err;
-
-		obj->name = ret;
 	}
 
 	args->name = (uint64_t) obj->name;
@@ -754,7 +753,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
 		return -EOPNOTSUPP;
 
 	mutex_lock(&dev->object_name_lock);
-	obj = idr_find(&dev->object_name_idr, (int) args->name);
+	obj = xa_load(&dev->object_names, (int) args->name);
 	if (obj) {
 		drm_gem_object_get(obj);
 	} else {
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 42411b3ea0c8..52e271b97de8 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -219,7 +219,7 @@ struct drm_device {
 	/** \name GEM information */
 	/*@{ */
 	struct mutex object_name_lock;
-	struct idr object_name_idr;
+	struct xarray object_names;
 	struct drm_vma_offset_manager *vma_offset_manager;
 	/*@} */
 	int switch_power_state;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 04/34] drm: Convert object_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (2 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 03/34] drm: Convert object_name_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 05/34] drm: Convert syncobj_idr " Matthew Wilcox
                   ` (30 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c       | 23 +++----
 drivers/gpu/drm/drm_gem.c                     | 67 +++++++------------
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  | 12 ++--
 drivers/gpu/drm/i915/i915_debugfs.c           | 20 +++---
 drivers/gpu/drm/i915/i915_gem_object.h        |  2 +-
 .../gpu/drm/i915/selftests/i915_gem_context.c |  7 +-
 drivers/gpu/drm/msm/msm_gem_submit.c          | 12 ++--
 drivers/gpu/drm/v3d/v3d_gem.c                 | 17 +++--
 drivers/gpu/drm/vc4/vc4_gem.c                 |  6 +-
 include/drm/drm_file.h                        |  9 +--
 10 files changed, 77 insertions(+), 98 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index f4f00217546e..8c415fdfd828 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -98,16 +98,14 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
 
 	list_for_each_entry(file, &ddev->filelist, lhead) {
 		struct drm_gem_object *gobj;
-		int handle;
+		unsigned long handle;
 
 		WARN_ONCE(1, "Still active user space clients!\n");
-		spin_lock(&file->table_lock);
-		idr_for_each_entry(&file->object_idr, gobj, handle) {
+		xa_for_each(&file->objects, handle, gobj) {
 			WARN_ONCE(1, "And also active allocations!\n");
 			drm_gem_object_put_unlocked(gobj);
 		}
-		idr_destroy(&file->object_idr);
-		spin_unlock(&file->table_lock);
+		xa_destroy(&file->objects);
 	}
 
 	mutex_unlock(&ddev->filelist_mutex);
@@ -784,12 +782,10 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
 		seq_printf((m), " " #flag);		\
 	}
 
-static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
+static int amdgpu_debugfs_gem_bo_info(unsigned int id,
+		struct drm_gem_object *gobj, struct seq_file *m)
 {
-	struct drm_gem_object *gobj = ptr;
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
-	struct seq_file *m = data;
-
 	struct dma_buf_attachment *attachment;
 	struct dma_buf *dma_buf;
 	unsigned domain;
@@ -851,6 +847,8 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
 
 	list_for_each_entry(file, &dev->filelist, lhead) {
 		struct task_struct *task;
+		struct drm_gem_object *gobj;
+		unsigned long index;
 
 		/*
 		 * Although we have a valid reference on file->pid, that does
@@ -864,9 +862,10 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
 			   task ? task->comm : "<unknown>");
 		rcu_read_unlock();
 
-		spin_lock(&file->table_lock);
-		idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m);
-		spin_unlock(&file->table_lock);
+		xa_lock(&file->objects);
+		xa_for_each(&file->objects, index, gobj)
+			amdgpu_debugfs_gem_bo_info(index, gobj, m);
+		xa_unlock(&file->objects);
 	}
 
 	mutex_unlock(&dev->filelist_mutex);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 0a52a958cffe..dc0d3cc3bb35 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -251,10 +251,9 @@ drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
  * handle references on objects.
  */
 static int
-drm_gem_object_release_handle(int id, void *ptr, void *data)
+drm_gem_object_release_handle(struct drm_gem_object *obj,
+		struct drm_file *file_priv)
 {
-	struct drm_file *file_priv = data;
-	struct drm_gem_object *obj = ptr;
 	struct drm_device *dev = obj->dev;
 
 	if (obj->funcs && obj->funcs->close)
@@ -285,23 +284,17 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 {
 	struct drm_gem_object *obj;
 
-	spin_lock(&filp->table_lock);
-
 	/* Check if we currently have a reference on the object */
-	obj = idr_replace(&filp->object_idr, NULL, handle);
-	spin_unlock(&filp->table_lock);
-	if (IS_ERR_OR_NULL(obj))
-		return -EINVAL;
-
-	/* Release driver's reference and decrement refcount. */
-	drm_gem_object_release_handle(handle, obj, filp);
+	obj = xa_store(&filp->objects, handle, NULL, 0);
+	if (obj) {
+		/* Release driver's reference and decrement refcount. */
+		drm_gem_object_release_handle(obj, filp);
+	}
 
 	/* And finally make the handle available for future allocations. */
-	spin_lock(&filp->table_lock);
-	idr_remove(&filp->object_idr, handle);
-	spin_unlock(&filp->table_lock);
+	xa_erase(&filp->objects, handle);
 
-	return 0;
+	return obj ? 0 : -EINVAL;
 }
 EXPORT_SYMBOL(drm_gem_handle_delete);
 
@@ -390,24 +383,14 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
 	if (obj->handle_count++ == 0)
 		drm_gem_object_get(obj);
 
-	/*
-	 * Get the user-visible handle using idr.  Preload and perform
-	 * allocation under our spinlock.
-	 */
-	idr_preload(GFP_KERNEL);
-	spin_lock(&file_priv->table_lock);
-
-	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
-
-	spin_unlock(&file_priv->table_lock);
-	idr_preload_end();
-
+	/* Get the user-visible handle */
+	ret = xa_alloc(&file_priv->objects, &handle, obj, xa_limit_31b,
+			GFP_KERNEL);
 	mutex_unlock(&dev->object_name_lock);
+
 	if (ret < 0)
 		goto err_unref;
 
-	handle = ret;
-
 	ret = drm_vma_node_allow(&obj->vma_node, file_priv);
 	if (ret)
 		goto err_remove;
@@ -428,9 +411,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
 err_revoke:
 	drm_vma_node_revoke(&obj->vma_node, file_priv);
 err_remove:
-	spin_lock(&file_priv->table_lock);
-	idr_remove(&file_priv->object_idr, handle);
-	spin_unlock(&file_priv->table_lock);
+	xa_erase(&file_priv->objects, handle);
 err_unref:
 	drm_gem_object_handle_put_unlocked(obj);
 	return ret;
@@ -644,14 +625,12 @@ drm_gem_object_lookup(struct drm_file *filp, u32 handle)
 {
 	struct drm_gem_object *obj;
 
-	spin_lock(&filp->table_lock);
-
+	xa_lock(&filp->objects);
 	/* Check if we currently have a reference on the object */
-	obj = idr_find(&filp->object_idr, handle);
+	obj = xa_load(&filp->objects, handle);
 	if (obj)
 		drm_gem_object_get(obj);
-
-	spin_unlock(&filp->table_lock);
+	xa_unlock(&filp->objects);
 
 	return obj;
 }
@@ -784,8 +763,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
 void
 drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
 {
-	idr_init_base(&file_private->object_idr, 1);
-	spin_lock_init(&file_private->table_lock);
+	xa_init_flags(&file_private->objects, XA_FLAGS_ALLOC1);
 }
 
 /**
@@ -800,9 +778,12 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
 void
 drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 {
-	idr_for_each(&file_private->object_idr,
-		     &drm_gem_object_release_handle, file_private);
-	idr_destroy(&file_private->object_idr);
+	unsigned long index;
+	struct drm_gem_object *obj;
+
+	xa_for_each(&file_private->objects, index, obj)
+		     drm_gem_object_release_handle(obj, file_private);
+	xa_destroy(&file_private->objects);
 }
 
 /**
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 30875f8f2933..98f803510e0a 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -65,7 +65,7 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
 	unsigned i;
 	int ret = 0;
 
-	spin_lock(&file->table_lock);
+	xa_lock(&file->objects);
 
 	for (i = 0, bo = submit_bos; i < nr_bos; i++, bo++) {
 		struct drm_gem_object *obj;
@@ -79,9 +79,9 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
 		submit->bos[i].flags = bo->flags;
 
 		/* normally use drm_gem_object_lookup(), but for bulk lookup
-		 * all under single table_lock just hit object_idr directly:
+		 * all under the lock just hit objects directly:
 		 */
-		obj = idr_find(&file->object_idr, bo->handle);
+		obj = xa_load(&file->objects, bo->handle);
 		if (!obj) {
 			DRM_ERROR("invalid handle %u at index %u\n",
 				  bo->handle, i);
@@ -90,8 +90,8 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
 		}
 
 		/*
-		 * Take a refcount on the object. The file table lock
-		 * prevents the object_idr's refcount on this being dropped.
+		 * Take a refcount on the object. The lock
+		 * prevents the objects' refcount on this being dropped.
 		 */
 		drm_gem_object_get(obj);
 
@@ -100,7 +100,7 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
 
 out_unlock:
 	submit->nr_bos = i;
-	spin_unlock(&file->table_lock);
+	xa_unlock(&file->objects);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 40a61ef9aac1..030263870ba6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -304,10 +304,9 @@ struct file_stats {
 	u64 active, inactive;
 };
 
-static int per_file_stats(int id, void *ptr, void *data)
+static
+int per_file_stats(struct drm_i915_gem_object *obj, struct file_stats *stats)
 {
-	struct drm_i915_gem_object *obj = ptr;
-	struct file_stats *stats = data;
 	struct i915_vma *vma;
 
 	lockdep_assert_held(&obj->base.dev->struct_mutex);
@@ -370,7 +369,7 @@ static void print_batch_pool_stats(struct seq_file *m,
 			list_for_each_entry(obj,
 					    &engine->batch_pool.cache_list[j],
 					    batch_pool_link)
-				per_file_stats(0, obj, &stats);
+				per_file_stats(obj, &stats);
 		}
 	}
 
@@ -387,9 +386,9 @@ static int per_file_ctx_stats(int idx, void *ptr, void *data)
 		struct intel_context *ce = to_intel_context(ctx, engine);
 
 		if (ce->state)
-			per_file_stats(0, ce->state->obj, data);
+			per_file_stats(ce->state->obj, data);
 		if (ce->ring)
-			per_file_stats(0, ce->ring->vma->obj, data);
+			per_file_stats(ce->ring->vma->obj, data);
 	}
 
 	return 0;
@@ -521,17 +520,20 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	print_context_stats(m, dev_priv);
 	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
 		struct file_stats stats;
+		struct drm_i915_gem_object *obj;
 		struct drm_i915_file_private *file_priv = file->driver_priv;
 		struct i915_request *request;
 		struct task_struct *task;
+		unsigned long index;
 
 		mutex_lock(&dev->struct_mutex);
 
 		memset(&stats, 0, sizeof(stats));
 		stats.file_priv = file->driver_priv;
-		spin_lock(&file->table_lock);
-		idr_for_each(&file->object_idr, per_file_stats, &stats);
-		spin_unlock(&file->table_lock);
+		xa_lock(&file->objects);
+		xa_for_each(&file->objects, index, obj)
+			per_file_stats(obj, &stats);
+		xa_unlock(&file->objects);
 		/*
 		 * Although we have a valid reference on file->pid, that does
 		 * not guarantee that the task_struct who called get_pid() is
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index a6dd7c46de0d..7f6493229f50 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -310,7 +310,7 @@ i915_gem_object_lookup_rcu(struct drm_file *file, u32 handle)
 #ifdef CONFIG_LOCKDEP
 	WARN_ON(debug_locks && !lock_is_held(&rcu_lock_map));
 #endif
-	return idr_find(&file->object_idr, handle);
+	return xa_load(&file->objects, handle);
 }
 
 static inline struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 7d82043aff10..5e30bef22a8c 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -492,14 +492,15 @@ static int cpu_check(struct drm_i915_gem_object *obj, unsigned int max)
 static int file_add_object(struct drm_file *file,
 			    struct drm_i915_gem_object *obj)
 {
-	int err;
+	int err, id;
 
 	GEM_BUG_ON(obj->base.handle_count);
 
 	/* tie the object to the drm_file for easy reaping */
-	err = idr_alloc(&file->object_idr, &obj->base, 1, 0, GFP_KERNEL);
+	err = xa_alloc(&file->objects, &id, &obj->base, xa_limit_32b,
+			GFP_KERNEL);
 	if (err < 0)
-		return  err;
+		return err;
 
 	i915_gem_object_get(obj);
 	obj->base.handle_count++;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 12b983fc0b56..707d16e27e13 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -88,7 +88,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
 	unsigned i;
 	int ret = 0;
 
-	spin_lock(&file->table_lock);
+	xa_lock(&file->objects);
 	pagefault_disable();
 
 	for (i = 0; i < args->nr_bos; i++) {
@@ -105,12 +105,12 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
 
 		if (copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo))) {
 			pagefault_enable();
-			spin_unlock(&file->table_lock);
+			xa_unlock(&file->objects);
 			if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) {
 				ret = -EFAULT;
 				goto out;
 			}
-			spin_lock(&file->table_lock);
+			xa_lock(&file->objects);
 			pagefault_disable();
 		}
 
@@ -129,9 +129,9 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
 		submit->bos[i].iova  = submit_bo.presumed;
 
 		/* normally use drm_gem_object_lookup(), but for bulk lookup
-		 * all under single table_lock just hit object_idr directly:
+		 * all under single lock just hit objects directly:
 		 */
-		obj = idr_find(&file->object_idr, submit_bo.handle);
+		obj = xa_load(&file->objects, submit_bo.handle);
 		if (!obj) {
 			DRM_ERROR("invalid handle %u at index %u\n", submit_bo.handle, i);
 			ret = -EINVAL;
@@ -156,7 +156,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
 
 out_unlock:
 	pagefault_enable();
-	spin_unlock(&file->table_lock);
+	xa_unlock(&file->objects);
 
 out:
 	submit->nr_bos = i;
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index 05ca6319065e..44eca1a99cc5 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -362,21 +362,21 @@ v3d_cl_lookup_bos(struct drm_device *dev,
 		goto fail;
 	}
 
-	spin_lock(&file_priv->table_lock);
+	xa_lock(&file_priv->objects);
 	for (i = 0; i < exec->bo_count; i++) {
-		struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
+		struct drm_gem_object *bo = xa_load(&file_priv->objects,
 						     handles[i]);
 		if (!bo) {
 			DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
 				  i, handles[i]);
 			ret = -ENOENT;
-			spin_unlock(&file_priv->table_lock);
+			xa_unlock(&file_priv->objects);
 			goto fail;
 		}
 		drm_gem_object_get(bo);
 		exec->bo[i] = to_v3d_bo(bo);
 	}
-	spin_unlock(&file_priv->table_lock);
+	xa_unlock(&file_priv->objects);
 
 fail:
 	kvfree(handles);
@@ -671,26 +671,25 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
 	job->args = *args;
 	job->v3d = v3d;
 
-	spin_lock(&file_priv->table_lock);
+	xa_lock(&file_priv->objects);
 	for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) {
 		struct drm_gem_object *bo;
 
 		if (!args->bo_handles[bo_count])
 			break;
 
-		bo = idr_find(&file_priv->object_idr,
-			      args->bo_handles[bo_count]);
+		bo = xa_load(&file_priv->objects, args->bo_handles[bo_count]);
 		if (!bo) {
 			DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
 				  bo_count, args->bo_handles[bo_count]);
 			ret = -ENOENT;
-			spin_unlock(&file_priv->table_lock);
+			xa_unlock(&file_priv->objects);
 			goto fail;
 		}
 		drm_gem_object_get(bo);
 		job->bo[bo_count] = to_v3d_bo(bo);
 	}
-	spin_unlock(&file_priv->table_lock);
+	xa_unlock(&file_priv->objects);
 
 	ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx);
 	if (ret)
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index aea2b8dfec17..8715573957e9 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -759,9 +759,9 @@ vc4_cl_lookup_bos(struct drm_device *dev,
 		goto fail;
 	}
 
-	spin_lock(&file_priv->table_lock);
+	xa_lock(&file_priv->objects);
 	for (i = 0; i < exec->bo_count; i++) {
-		struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
+		struct drm_gem_object *bo = xa_load(&file_priv->objects,
 						     handles[i]);
 		if (!bo) {
 			DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
@@ -773,7 +773,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
 		drm_gem_object_get(bo);
 		exec->bo[i] = (struct drm_gem_cma_object *)bo;
 	}
-	spin_unlock(&file_priv->table_lock);
+	xa_unlock(&file_priv->objects);
 
 	if (ret)
 		goto fail_put_bo;
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 84ac79219e4c..685f3cd9d071 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -240,15 +240,12 @@ struct drm_file {
 	struct drm_minor *minor;
 
 	/**
-	 * @object_idr:
+	 * @objects:
 	 *
 	 * Mapping of mm object handles to object pointers. Used by the GEM
-	 * subsystem. Protected by @table_lock.
+	 * subsystem.
 	 */
-	struct idr object_idr;
-
-	/** @table_lock: Protects @object_idr. */
-	spinlock_t table_lock;
+	struct xarray objects;
 
 	/** @syncobj_idr: Mapping of sync object handles to object pointers. */
 	struct idr syncobj_idr;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 05/34] drm: Convert syncobj_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (3 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 04/34] drm: Convert object_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 06/34] drm: Convert magic_map " Matthew Wilcox
                   ` (29 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_syncobj.c | 64 +++++++++++------------------------
 include/drm/drm_file.h        |  6 ++--
 2 files changed, 22 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index db30a0e89db8..3b63b1eeec80 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -69,14 +69,12 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 {
 	struct drm_syncobj *syncobj;
 
-	spin_lock(&file_private->syncobj_table_lock);
-
-	/* Check if we currently have a reference on the object */
-	syncobj = idr_find(&file_private->syncobj_idr, handle);
+	/* Get a reference on the object */
+	xa_lock(&file_private->syncobjs);
+	syncobj = xa_load(&file_private->syncobjs, handle);
 	if (syncobj)
 		drm_syncobj_get(syncobj);
-
-	spin_unlock(&file_private->syncobj_table_lock);
+	xa_unlock(&file_private->syncobjs);
 
 	return syncobj;
 }
@@ -288,23 +286,16 @@ int drm_syncobj_get_handle(struct drm_file *file_private,
 {
 	int ret;
 
-	/* take a reference to put in the idr */
+	/* take a reference to put in the XArray */
 	drm_syncobj_get(syncobj);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&file_private->syncobj_table_lock);
-	ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
-	spin_unlock(&file_private->syncobj_table_lock);
+	ret = xa_alloc(&file_private->syncobjs, handle, syncobj, xa_limit_31b,
+			GFP_KERNEL);
 
-	idr_preload_end();
-
-	if (ret < 0) {
+	if (ret < 0)
 		drm_syncobj_put(syncobj);
-		return ret;
-	}
 
-	*handle = ret;
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(drm_syncobj_get_handle);
 
@@ -328,9 +319,7 @@ static int drm_syncobj_destroy(struct drm_file *file_private,
 {
 	struct drm_syncobj *syncobj;
 
-	spin_lock(&file_private->syncobj_table_lock);
-	syncobj = idr_remove(&file_private->syncobj_idr, handle);
-	spin_unlock(&file_private->syncobj_table_lock);
+	syncobj = xa_erase(&file_private->syncobjs, handle);
 
 	if (!syncobj)
 		return -EINVAL;
@@ -419,16 +408,10 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
 	syncobj = file->private_data;
 	drm_syncobj_get(syncobj);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&file_private->syncobj_table_lock);
-	ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
-	spin_unlock(&file_private->syncobj_table_lock);
-	idr_preload_end();
+	ret = xa_alloc(&file_private->syncobjs, handle, syncobj, xa_limit_31b,
+			GFP_KERNEL);
 
-	if (ret > 0) {
-		*handle = ret;
-		ret = 0;
-	} else
+	if (ret < 0)
 		drm_syncobj_put(syncobj);
 
 	fput(file);
@@ -498,17 +481,7 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private,
 void
 drm_syncobj_open(struct drm_file *file_private)
 {
-	idr_init_base(&file_private->syncobj_idr, 1);
-	spin_lock_init(&file_private->syncobj_table_lock);
-}
-
-static int
-drm_syncobj_release_handle(int id, void *ptr, void *data)
-{
-	struct drm_syncobj *syncobj = ptr;
-
-	drm_syncobj_put(syncobj);
-	return 0;
+	xa_init_flags(&file_private->syncobjs, XA_FLAGS_ALLOC1);
 }
 
 /**
@@ -522,9 +495,12 @@ drm_syncobj_release_handle(int id, void *ptr, void *data)
 void
 drm_syncobj_release(struct drm_file *file_private)
 {
-	idr_for_each(&file_private->syncobj_idr,
-		     &drm_syncobj_release_handle, file_private);
-	idr_destroy(&file_private->syncobj_idr);
+	struct drm_syncobj *syncobj;
+	unsigned long index;
+
+	xa_for_each(&file_private->syncobjs, index, syncobj)
+		drm_syncobj_put(syncobj);
+	xa_destroy(&file_private->syncobjs);
 }
 
 int
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 685f3cd9d071..c10dca3c4cda 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -247,10 +247,8 @@ struct drm_file {
 	 */
 	struct xarray objects;
 
-	/** @syncobj_idr: Mapping of sync object handles to object pointers. */
-	struct idr syncobj_idr;
-	/** @syncobj_table_lock: Protects @syncobj_idr. */
-	spinlock_t syncobj_table_lock;
+	/** @syncobjs: Mapping of sync object handles to object pointers. */
+	struct xarray syncobjs;
 
 	/** @filp: Pointer to the core file structure. */
 	struct file *filp;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 06/34] drm: Convert magic_map to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (4 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 05/34] drm: Convert syncobj_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 07/34] drm: Convert lessee_idr " Matthew Wilcox
                   ` (28 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_auth.c | 18 ++++++++----------
 include/drm/drm_auth.h     |  5 ++---
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 1669c42c40ed..268189e9e2e0 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -62,17 +62,16 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
 
 	mutex_lock(&dev->master_mutex);
 	if (!file_priv->magic) {
-		ret = idr_alloc(&file_priv->master->magic_map, file_priv,
-				1, 0, GFP_KERNEL);
-		if (ret >= 0)
-			file_priv->magic = ret;
+		ret = xa_alloc(&file_priv->master->magic_map,
+				&file_priv->magic, file_priv,
+				xa_limit_31b, GFP_KERNEL);
 	}
 	auth->magic = file_priv->magic;
 	mutex_unlock(&dev->master_mutex);
 
 	DRM_DEBUG("%u\n", auth->magic);
 
-	return ret < 0 ? ret : 0;
+	return ret;
 }
 
 int drm_authmagic(struct drm_device *dev, void *data,
@@ -84,10 +83,10 @@ int drm_authmagic(struct drm_device *dev, void *data,
 	DRM_DEBUG("%u\n", auth->magic);
 
 	mutex_lock(&dev->master_mutex);
-	file = idr_find(&file_priv->master->magic_map, auth->magic);
+	file = xa_load(&file_priv->master->magic_map, auth->magic);
 	if (file) {
 		file->authenticated = 1;
-		idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
+		xa_store(&file_priv->master->magic_map, auth->magic, NULL, 0);
 	}
 	mutex_unlock(&dev->master_mutex);
 
@@ -105,7 +104,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
 	kref_init(&master->refcount);
 	spin_lock_init(&master->lock.spinlock);
 	init_waitqueue_head(&master->lock.lock_queue);
-	idr_init(&master->magic_map);
+	xa_init_flags(&master->magic_map, XA_FLAGS_ALLOC1);
 	master->dev = dev;
 
 	/* initialize the tree of output resource lessees */
@@ -269,7 +268,7 @@ void drm_master_release(struct drm_file *file_priv)
 
 	mutex_lock(&dev->master_mutex);
 	if (file_priv->magic)
-		idr_remove(&file_priv->master->magic_map, file_priv->magic);
+		xa_erase(&file_priv->master->magic_map, file_priv->magic);
 
 	if (!drm_is_current_master(file_priv))
 		goto out;
@@ -348,7 +347,6 @@ static void drm_master_destroy(struct kref *kref)
 
 	drm_legacy_master_rmmaps(dev, master);
 
-	idr_destroy(&master->magic_map);
 	idr_destroy(&master->leases);
 	idr_destroy(&master->lessee_idr);
 
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index 86bff9841b54..c719fe375967 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -76,10 +76,9 @@ struct drm_master {
 	 */
 	int unique_len;
 	/**
-	 * @magic_map: Map of used authentication tokens. Protected by
-	 * &drm_device.master_mutex.
+	 * @magic_map: Map of used authentication tokens.
 	 */
-	struct idr magic_map;
+	struct xarray magic_map;
 	struct drm_lock_data lock;
 	void *driver_priv;
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 07/34] drm: Convert lessee_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (5 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 06/34] drm: Convert magic_map " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 08/34] drm: Remove linked lists for lessees Matthew Wilcox
                   ` (27 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_auth.c  |  3 +--
 drivers/gpu/drm/drm_lease.c | 15 ++++++---------
 include/drm/drm_auth.h      |  2 +-
 3 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 268189e9e2e0..28767f55b30b 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -113,7 +113,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
 	INIT_LIST_HEAD(&master->lessees);
 	INIT_LIST_HEAD(&master->lessee_list);
 	idr_init(&master->leases);
-	idr_init(&master->lessee_idr);
+	xa_init_flags(&master->lessee_xa, XA_FLAGS_ALLOC1);
 
 	return master;
 }
@@ -348,7 +348,6 @@ static void drm_master_destroy(struct kref *kref)
 	drm_legacy_master_rmmaps(dev, master);
 
 	idr_destroy(&master->leases);
-	idr_destroy(&master->lessee_idr);
 
 	kfree(master->unique);
 	kfree(master);
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 99cba8ea5d82..c02587443b61 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -54,7 +54,7 @@ static struct drm_master*
 _drm_find_lessee(struct drm_master *master, int lessee_id)
 {
 	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
-	return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
+	return xa_load(&drm_lease_owner(master)->lessee_xa, lessee_id);
 }
 
 /**
@@ -203,7 +203,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
 	int error;
 	struct drm_master *lessee;
 	int object;
-	int id;
 	void *entry;
 
 	DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
@@ -232,13 +231,11 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
 	}
 
 	/* Insert the new lessee into the tree */
-	id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
-	if (id < 0) {
-		error = id;
+	error = xa_alloc(&drm_lease_owner(lessor)->lessee_xa,
+			&lessee->lessee_id, lessee, xa_limit_32b, GFP_KERNEL);
+	if (error < 0)
 		goto out_lessee;
-	}
 
-	lessee->lessee_id = id;
 	lessee->lessor = drm_master_get(lessor);
 	list_add_tail(&lessee->lessee_list, &lessor->lessees);
 
@@ -279,10 +276,10 @@ void drm_lease_destroy(struct drm_master *master)
 	 */
 	WARN_ON(!list_empty(&master->lessees));
 
-	/* Remove this master from the lessee idr in the owner */
+	/* Remove this master from the lessee array in the owner */
 	if (master->lessee_id != 0) {
 		DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
-		idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
+		xa_erase(&drm_lease_owner(master)->lessee_xa, master->lessee_id);
 	}
 
 	/* Remove this master from any lessee list it may be on */
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index c719fe375967..f1e092406caa 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -93,7 +93,7 @@ struct drm_master {
 	struct list_head lessee_list;
 	struct list_head lessees;
 	struct idr leases;
-	struct idr lessee_idr;
+	struct xarray lessee_xa;
 };
 
 struct drm_master *drm_master_get(struct drm_master *master);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 08/34] drm: Remove linked lists for lessees
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (6 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 07/34] drm: Convert lessee_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 09/34] drm: Convert ctx_idr to XArray Matthew Wilcox
                   ` (26 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

These are already tracked in the XArray so we do not need to also keep
a doubly-linked list.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_auth.c  |  4 +--
 drivers/gpu/drm/drm_lease.c | 58 ++++++++++++++++++-------------------
 include/drm/drm_auth.h      |  4 +--
 3 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 28767f55b30b..1813507f9b9c 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -110,10 +110,8 @@ struct drm_master *drm_master_create(struct drm_device *dev)
 	/* initialize the tree of output resource lessees */
 	master->lessor = NULL;
 	master->lessee_id = 0;
-	INIT_LIST_HEAD(&master->lessees);
-	INIT_LIST_HEAD(&master->lessee_list);
 	idr_init(&master->leases);
-	xa_init_flags(&master->lessee_xa, XA_FLAGS_ALLOC1);
+	xa_init_flags(&master->lessees, XA_FLAGS_ALLOC1);
 
 	return master;
 }
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index c02587443b61..47830f9ec616 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -20,9 +20,6 @@
 #include <drm/drm_auth.h>
 #include <drm/drm_crtc_helper.h>
 
-#define drm_for_each_lessee(lessee, lessor) \
-	list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
-
 static uint64_t drm_lease_idr_object;
 
 /**
@@ -54,7 +51,7 @@ static struct drm_master*
 _drm_find_lessee(struct drm_master *master, int lessee_id)
 {
 	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
-	return xa_load(&drm_lease_owner(master)->lessee_xa, lessee_id);
+	return xa_load(&drm_lease_owner(master)->lessees, lessee_id);
 }
 
 /**
@@ -90,9 +87,10 @@ static int _drm_lease_held_master(struct drm_master *master, int id)
 static bool _drm_has_leased(struct drm_master *master, int id)
 {
 	struct drm_master *lessee;
+	unsigned long index;
 
 	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
-	drm_for_each_lessee(lessee, master)
+	xa_for_each(&master->lessees, index, lessee)
 		if (_drm_lease_held_master(lessee, id))
 			return true;
 	return false;
@@ -231,13 +229,12 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
 	}
 
 	/* Insert the new lessee into the tree */
-	error = xa_alloc(&drm_lease_owner(lessor)->lessee_xa,
-			&lessee->lessee_id, lessee, xa_limit_32b, GFP_KERNEL);
+	error = xa_alloc(&drm_lease_owner(lessor)->lessees, &lessee->lessee_id,
+			lessee, xa_limit_32b, GFP_KERNEL);
 	if (error < 0)
 		goto out_lessee;
 
 	lessee->lessor = drm_master_get(lessor);
-	list_add_tail(&lessee->lessee_list, &lessor->lessees);
 
 	/* Move the leases over */
 	lessee->leases = *leases;
@@ -271,20 +268,13 @@ void drm_lease_destroy(struct drm_master *master)
 
 	DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
 
-	/* This master is referenced by all lessees, hence it cannot be destroyed
-	 * until all of them have been
-	 */
-	WARN_ON(!list_empty(&master->lessees));
+	WARN_ON(!xa_empty(&master->lessees));
 
 	/* Remove this master from the lessee array in the owner */
 	if (master->lessee_id != 0) {
 		DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
-		xa_erase(&drm_lease_owner(master)->lessee_xa, master->lessee_id);
+		xa_erase(&drm_lease_owner(master)->lessees, master->lessee_id);
 	}
-
-	/* Remove this master from any lessee list it may be on */
-	list_del(&master->lessee_list);
-
 	mutex_unlock(&dev->mode_config.idr_mutex);
 
 	if (master->lessor) {
@@ -313,27 +303,34 @@ static void _drm_lease_revoke(struct drm_master *top)
 	 * the tree is fully connected, we can do this without recursing
 	 */
 	for (;;) {
+		struct drm_master *tmp;
+		unsigned long index = 0;
+
 		DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
 
 		/* Evacuate the lease */
 		idr_for_each_entry(&master->leases, entry, object)
 			idr_remove(&master->leases, object);
 
-		/* Depth-first list walk */
+		/* Depth-first tree walk */
+		tmp = xa_find(&master->lessees, &index, ULONG_MAX, XA_PRESENT);
 
 		/* Down */
-		if (!list_empty(&master->lessees)) {
-			master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
-		} else {
-			/* Up */
-			while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
-				master = master->lessor;
-
-			if (master == top)
+		if (tmp) {
+			master = tmp;
+			continue;
+		}
+		/* Over */
+		while (master != top) {
+			index = master->lessee_id;
+			tmp = xa_find_after(&master->lessor->lessees, &index,
+					ULONG_MAX, XA_PRESENT);
+			if (tmp) {
+				master = tmp;
 				break;
-
-			/* Over */
-			master = list_next_entry(master, lessee_list);
+			}
+			/* Up */
+			master = master->lessor;
 		}
 	}
 }
@@ -612,6 +609,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
 	__u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
 	__u32 count_lessees = arg->count_lessees;
 	struct drm_master *lessor = lessor_priv->master, *lessee;
+	unsigned long index;
 	int count;
 	int ret = 0;
 
@@ -627,7 +625,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
 	mutex_lock(&dev->mode_config.idr_mutex);
 
 	count = 0;
-	drm_for_each_lessee(lessee, lessor) {
+	xa_for_each(&lessor->lessees, index, lessee) {
 		/* Only list un-revoked leases */
 		if (!idr_is_empty(&lessee->leases)) {
 			if (count_lessees > count) {
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index f1e092406caa..fbb58264538b 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -90,10 +90,8 @@ struct drm_master {
 
 	struct drm_master *lessor;
 	int	lessee_id;
-	struct list_head lessee_list;
-	struct list_head lessees;
 	struct idr leases;
-	struct xarray lessee_xa;
+	struct xarray lessees;
 };
 
 struct drm_master *drm_master_get(struct drm_master *master);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 09/34] drm: Convert ctx_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (7 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 08/34] drm: Remove linked lists for lessees Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 10/34] drm: Convert tile_idr " Matthew Wilcox
                   ` (25 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_context.c | 42 +++++++++++++++--------------------
 include/drm/drm_device.h      |  2 +-
 2 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 506663c69b0a..b498e311cf57 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -48,8 +48,7 @@ struct drm_ctx_list {
  * \param ctx_handle context handle.
  *
  * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
- * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
- * lock.
+ * in drm_device::ctxts.
  */
 void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
 {
@@ -57,9 +56,7 @@ void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
 	    !drm_core_check_feature(dev, DRIVER_LEGACY))
 		return;
 
-	mutex_lock(&dev->struct_mutex);
-	idr_remove(&dev->ctx_idr, ctx_handle);
-	mutex_unlock(&dev->struct_mutex);
+	xa_erase(&dev->ctxts, ctx_handle);
 }
 
 /**
@@ -68,18 +65,17 @@ void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
  * \param dev DRM device.
  * \return (non-negative) context handle on success or a negative number on failure.
  *
- * Allocate a new idr from drm_device::ctx_idr while holding the
- * drm_device::struct_mutex lock.
+ * Allocate a new id from drm_device::ctxts.
  */
 static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
 {
-	int ret;
+	int ret, id;
 
-	mutex_lock(&dev->struct_mutex);
-	ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
-			GFP_KERNEL);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
+	ret = xa_alloc(&dev->ctxts, &id, NULL,
+			XA_LIMIT(DRM_RESERVED_CONTEXTS, INT_MAX), GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	return id;
 }
 
 /**
@@ -87,7 +83,7 @@ static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
  *
  * \param dev DRM device.
  *
- * Initialise the drm_device::ctx_idr
+ * Initialise the drm_device::ctxts
  */
 void drm_legacy_ctxbitmap_init(struct drm_device * dev)
 {
@@ -95,7 +91,7 @@ void drm_legacy_ctxbitmap_init(struct drm_device * dev)
 	    !drm_core_check_feature(dev, DRIVER_LEGACY))
 		return;
 
-	idr_init(&dev->ctx_idr);
+	xa_init_flags(&dev->ctxts, XA_FLAGS_ALLOC);
 }
 
 /**
@@ -103,8 +99,8 @@ void drm_legacy_ctxbitmap_init(struct drm_device * dev)
  *
  * \param dev DRM device.
  *
- * Free all idr members using drm_ctx_sarea_free helper function
- * while holding the drm_device::struct_mutex lock.
+ * Free all memory used by the ctxts data structure.  Does not free the
+ * pointers in that data structures.
  */
 void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
 {
@@ -112,9 +108,7 @@ void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
 	    !drm_core_check_feature(dev, DRIVER_LEGACY))
 		return;
 
-	mutex_lock(&dev->struct_mutex);
-	idr_destroy(&dev->ctx_idr);
-	mutex_unlock(&dev->struct_mutex);
+	xa_destroy(&dev->ctxts);
 }
 
 /**
@@ -166,7 +160,7 @@ void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
  * \param arg user argument pointing to a drm_ctx_priv_map structure.
  * \return zero on success or a negative number on failure.
  *
- * Gets the map from drm_device::ctx_idr with the handle specified and
+ * Gets the map from drm_device::ctxts with the handle specified and
  * returns its handle.
  */
 int drm_legacy_getsareactx(struct drm_device *dev, void *data,
@@ -182,7 +176,7 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data,
 
 	mutex_lock(&dev->struct_mutex);
 
-	map = idr_find(&dev->ctx_idr, request->ctx_id);
+	map = xa_load(&dev->ctxts, request->ctx_id);
 	if (!map) {
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
@@ -215,7 +209,7 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data,
  * \return zero on success or a negative number on failure.
  *
  * Searches the mapping specified in \p arg and update the entry in
- * drm_device::ctx_idr with it.
+ * drm_device::ctxts with it.
  */
 int drm_legacy_setsareactx(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
@@ -243,7 +237,7 @@ int drm_legacy_setsareactx(struct drm_device *dev, void *data,
 	if (!map)
 		goto bad;
 
-	if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
+	if (xa_is_err(xa_store(&dev->ctxts, request->ctx_id, map, GFP_KERNEL)))
 		goto bad;
 
 	mutex_unlock(&dev->struct_mutex);
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 52e271b97de8..b3b025b76f3e 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -115,7 +115,7 @@ struct drm_device {
 	struct list_head ctxlist;	/**< Linked list of context handles */
 	struct mutex ctxlist_mutex;	/**< For ctxlist */
 
-	struct idr ctx_idr;
+	struct xarray ctxts;
 
 	struct list_head vmalist;	/**< List of vmas (for debugging) */
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 10/34] drm: Convert tile_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (8 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 09/34] drm: Convert ctx_idr to XArray Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 11/34] drm: Convert crtc_idr " Matthew Wilcox
                   ` (24 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/drm_connector.c   | 27 +++++++++++----------------
 drivers/gpu/drm/drm_mode_config.c |  3 +--
 include/drm/drm_mode_config.h     | 12 ++++++------
 3 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da8ae80c2750..682eb79b721a 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2019,9 +2019,7 @@ static void drm_tile_group_free(struct kref *kref)
 {
 	struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
 	struct drm_device *dev = tg->dev;
-	mutex_lock(&dev->mode_config.idr_mutex);
-	idr_remove(&dev->mode_config.tile_idr, tg->id);
-	mutex_unlock(&dev->mode_config.idr_mutex);
+	xa_erase(&dev->mode_config.tiles, tg->id);
 	kfree(tg);
 }
 
@@ -2053,18 +2051,18 @@ struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
 					       char topology[8])
 {
 	struct drm_tile_group *tg;
-	int id;
-	mutex_lock(&dev->mode_config.idr_mutex);
-	idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
+	unsigned long id;
+
+	xa_lock(&dev->mode_config.tiles);
+	xa_for_each(&dev->mode_config.tiles, id, tg) {
 		if (!memcmp(tg->group_data, topology, 8)) {
 			if (!kref_get_unless_zero(&tg->refcount))
 				tg = NULL;
-			mutex_unlock(&dev->mode_config.idr_mutex);
-			return tg;
+			break;
 		}
 	}
-	mutex_unlock(&dev->mode_config.idr_mutex);
-	return NULL;
+	xa_unlock(&dev->mode_config.tiles);
+	return tg;
 }
 EXPORT_SYMBOL(drm_mode_get_tile_group);
 
@@ -2093,16 +2091,13 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
 	memcpy(tg->group_data, topology, 8);
 	tg->dev = dev;
 
-	mutex_lock(&dev->mode_config.idr_mutex);
-	ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
-	if (ret >= 0) {
-		tg->id = ret;
-	} else {
+	ret = xa_alloc(&dev->mode_config.tiles, &tg->id, tg, xa_limit_32b,
+			GFP_KERNEL);
+	if (ret < 0) {
 		kfree(tg);
 		tg = ERR_PTR(ret);
 	}
 
-	mutex_unlock(&dev->mode_config.idr_mutex);
 	return tg;
 }
 EXPORT_SYMBOL(drm_mode_create_tile_group);
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 703bfce975bb..609b30d7dcb1 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -394,7 +394,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
 	INIT_LIST_HEAD(&dev->mode_config.plane_list);
 	idr_init(&dev->mode_config.crtc_idr);
-	idr_init(&dev->mode_config.tile_idr);
+	xa_init_flags(&dev->mode_config.tiles, XA_FLAGS_ALLOC1);
 	ida_init(&dev->mode_config.connector_ida);
 	spin_lock_init(&dev->mode_config.connector_list_lock);
 
@@ -495,7 +495,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 	}
 
 	ida_destroy(&dev->mode_config.connector_ida);
-	idr_destroy(&dev->mode_config.tile_idr);
 	idr_destroy(&dev->mode_config.crtc_idr);
 	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
 }
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 572274ccbec7..fea334d99201 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -391,8 +391,8 @@ struct drm_mode_config {
 	/**
 	 * @idr_mutex:
 	 *
-	 * Mutex for KMS ID allocation and management. Protects both @crtc_idr
-	 * and @tile_idr.
+	 * Mutex for KMS ID allocation and management. Protects the
+	 * objects in @objects.
 	 */
 	struct mutex idr_mutex;
 
@@ -405,12 +405,12 @@ struct drm_mode_config {
 	struct idr crtc_idr;
 
 	/**
-	 * @tile_idr:
+	 * @tiles:
 	 *
-	 * Use this idr for allocating new IDs for tiled sinks like use in some
-	 * high-res DP MST screens.
+	 * Use this for allocating new IDs for tiled sinks like those
+	 * used in some high-res DP MST screens.
 	 */
-	struct idr tile_idr;
+	struct xarray tiles;
 
 	/** @fb_lock: Mutex to protect fb the global @fb_list and @num_fb. */
 	struct mutex fb_lock;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 11/34] drm: Convert crtc_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (9 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 10/34] drm: Convert tile_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-22  9:40   ` Daniel Vetter
  2019-02-21 18:41 ` [PATCH 12/34] drm/agp: Convert bo_list_handles " Matthew Wilcox
                   ` (23 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

 - Rename it to 'objects', as requested in todo.rst
 - Also convert leases IDR to XArray as the two are occasionally used by
   the same code (see drm_mode_get_lease_ioctl())
 - Refactor drm_mode_create_lease_ioctl() to create the new drm_master
   early to avoid creating an XArray on the stack and reparenting it
   afterwards.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 Documentation/gpu/todo.rst        |   3 -
 drivers/gpu/drm/drm_auth.c        |   4 +-
 drivers/gpu/drm/drm_lease.c       | 136 ++++++++++++++----------------
 drivers/gpu/drm/drm_mode_config.c |   3 +-
 drivers/gpu/drm/drm_mode_object.c |  47 +++++------
 include/drm/drm_auth.h            |   2 +-
 include/drm/drm_mode_config.h     |   6 +-
 7 files changed, 90 insertions(+), 111 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 14191b64446d..41da7b06195c 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -354,9 +354,6 @@ KMS cleanups
 
 Some of these date from the very introduction of KMS in 2008 ...
 
-- drm_mode_config.crtc_idr is misnamed, since it contains all KMS object. Should
-  be renamed to drm_mode_config.object_idr.
-
 - drm_display_mode doesn't need to be derived from drm_mode_object. That's
   leftovers from older (never merged into upstream) KMS designs where modes
   where set using their ID, including support to add/remove modes.
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 1813507f9b9c..c6967f0b095d 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -110,7 +110,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
 	/* initialize the tree of output resource lessees */
 	master->lessor = NULL;
 	master->lessee_id = 0;
-	idr_init(&master->leases);
+	xa_init(&master->leases);
 	xa_init_flags(&master->lessees, XA_FLAGS_ALLOC1);
 
 	return master;
@@ -345,7 +345,7 @@ static void drm_master_destroy(struct kref *kref)
 
 	drm_legacy_master_rmmaps(dev, master);
 
-	idr_destroy(&master->leases);
+	xa_destroy(&master->leases);
 
 	kfree(master->unique);
 	kfree(master);
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 47830f9ec616..1e88f406c738 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -20,8 +20,6 @@
 #include <drm/drm_auth.h>
 #include <drm/drm_crtc_helper.h>
 
-static uint64_t drm_lease_idr_object;
-
 /**
  * drm_lease_owner - return ancestor owner drm_master
  * @master: drm_master somewhere within tree of lessees and lessors
@@ -69,7 +67,7 @@ static int _drm_lease_held_master(struct drm_master *master, int id)
 {
 	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
 	if (master->lessor)
-		return idr_find(&master->leases, id) != NULL;
+		return xa_load(&master->leases, id) != NULL;
 	return true;
 }
 
@@ -183,7 +181,7 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
 /*
  * drm_lease_create - create a new drm_master with leased objects (idr_mutex not held)
  * @lessor: lease holder (or owner) of objects
- * @leases: objects to lease to the new drm_master
+ * @lessee: leaser of objects
  *
  * Uses drm_master_create to allocate a new drm_master, then checks to
  * make sure all of the desired objects can be leased, atomically
@@ -195,35 +193,30 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
  *	ERR_PTR(-EEXIST)	same object specified more than once in the provided list
  *	ERR_PTR(-ENOMEM)	allocation failed
  */
-static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
+static struct drm_master *drm_lease_create(struct drm_master *lessor,
+		struct drm_master *lessee)
 {
 	struct drm_device *dev = lessor->dev;
 	int error;
-	struct drm_master *lessee;
-	int object;
 	void *entry;
+	unsigned long index;
 
 	DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
 
-	lessee = drm_master_create(lessor->dev);
-	if (!lessee) {
-		DRM_DEBUG_LEASE("drm_master_create failed\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
 	mutex_lock(&dev->mode_config.idr_mutex);
 
-	idr_for_each_entry(leases, entry, object) {
+	xa_for_each(&lessee->leases, index, entry) {
 		error = 0;
-		if (!idr_find(&dev->mode_config.crtc_idr, object))
+		if (!xa_load(&dev->mode_config.objects, index))
 			error = -ENOENT;
-		else if (!_drm_lease_held_master(lessor, object))
+		else if (!_drm_lease_held_master(lessor, index))
 			error = -EACCES;
-		else if (_drm_has_leased(lessor, object))
+		else if (_drm_has_leased(lessor, index))
 			error = -EBUSY;
 
 		if (error != 0) {
-			DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
+			DRM_DEBUG_LEASE("object %d failed %d\n", (u32)index,
+					error);
 			goto out_lessee;
 		}
 	}
@@ -236,8 +229,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
 
 	lessee->lessor = drm_master_get(lessor);
 
-	/* Move the leases over */
-	lessee->leases = *leases;
 	DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
 
 	mutex_unlock(&dev->mode_config.idr_mutex);
@@ -246,8 +237,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
 out_lessee:
 	mutex_unlock(&dev->mode_config.idr_mutex);
 
-	drm_master_put(&lessee);
-
 	return ERR_PTR(error);
 }
 
@@ -292,8 +281,6 @@ void drm_lease_destroy(struct drm_master *master)
  */
 static void _drm_lease_revoke(struct drm_master *top)
 {
-	int object;
-	void *entry;
 	struct drm_master *master = top;
 
 	lockdep_assert_held(&top->dev->mode_config.idr_mutex);
@@ -309,8 +296,7 @@ static void _drm_lease_revoke(struct drm_master *top)
 		DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
 
 		/* Evacuate the lease */
-		idr_for_each_entry(&master->leases, entry, object)
-			idr_remove(&master->leases, object);
+		xa_destroy(&master->leases);
 
 		/* Depth-first tree walk */
 		tmp = xa_find(&master->lessees, &index, ULONG_MAX, XA_PRESENT);
@@ -378,11 +364,9 @@ static int validate_lease(struct drm_device *dev,
 	return 0;
 }
 
-static int fill_object_idr(struct drm_device *dev,
-			   struct drm_file *lessor_priv,
-			   struct idr *leases,
-			   int object_count,
-			   u32 *object_ids)
+static int fill_object_array(struct drm_device *dev,
+		struct drm_file *lessor_priv, struct xarray *leases,
+		int object_count, u32 *object_ids)
 {
 	struct drm_mode_object **objects;
 	u32 o;
@@ -431,14 +415,14 @@ static int fill_object_idr(struct drm_device *dev,
 		DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
 
 		/*
-		 * We're using an IDR to hold the set of leased
+		 * We're using an array to hold the set of leased
 		 * objects, but we don't need to point at the object's
-		 * data structure from the lease as the main crtc_idr
+		 * data structure from the lease as the main object array
 		 * will be used to actually find that. Instead, all we
 		 * really want is a 'leased/not-leased' result, for
 		 * which any non-NULL pointer will work fine.
 		 */
-		ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
+		ret = xa_insert(leases, object_id, xa_mk_value(0), GFP_KERNEL);
 		if (ret < 0) {
 			DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
 					object_id, ret);
@@ -446,19 +430,21 @@ static int fill_object_idr(struct drm_device *dev,
 		}
 		if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
 			struct drm_crtc *crtc = obj_to_crtc(obj);
-			ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
+			ret = xa_insert(leases, crtc->primary->base.id,
+					xa_mk_value(0), GFP_KERNEL);
 			if (ret < 0) {
 				DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
 						object_id, ret);
 				goto out_free_objects;
 			}
-			if (crtc->cursor) {
-				ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
-				if (ret < 0) {
-					DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
-							object_id, ret);
-					goto out_free_objects;
-				}
+			if (!crtc->cursor)
+				continue;
+			ret = xa_insert(leases, crtc->cursor->base.id,
+					xa_mk_value(0), GFP_KERNEL);
+			if (ret < 0) {
+				DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
+						object_id, ret);
+				goto out_free_objects;
 			}
 		}
 	}
@@ -490,9 +476,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	struct drm_mode_create_lease *cl = data;
 	size_t object_count;
 	int ret = 0;
-	struct idr leases;
 	struct drm_master *lessor = lessor_priv->master;
-	struct drm_master *lessee = NULL;
+	struct drm_master *lessee;
 	struct file *lessee_file = NULL;
 	struct file *lessor_file = lessor_priv->filp;
 	struct drm_file *lessee_priv;
@@ -520,37 +505,42 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 		return -EINVAL;
 	}
 
-	object_count = cl->object_count;
+	lessee = drm_master_create(lessor->dev);
+	if (!lessee) {
+		DRM_DEBUG_LEASE("drm_master_create failed\n");
+		return -ENOMEM;
+	}
 
-	object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), object_count * sizeof(__u32));
-	if (IS_ERR(object_ids))
-		return PTR_ERR(object_ids);
+	object_count = cl->object_count;
 
-	idr_init(&leases);
+	object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
+			array_size(object_count, sizeof(__u32)));
+	if (IS_ERR(object_ids)) {
+		ret = PTR_ERR(object_ids);
+		goto out_lessee;
+	}
 
-	/* fill and validate the object idr */
-	ret = fill_object_idr(dev, lessor_priv, &leases,
+	/* fill and validate the object array */
+	ret = fill_object_array(dev, lessor_priv, &lessee->leases,
 			      object_count, object_ids);
 	kfree(object_ids);
 	if (ret) {
 		DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret);
-		idr_destroy(&leases);
-		return ret;
+		goto out_lessee;
 	}
 
 	/* Allocate a file descriptor for the lease */
-	fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
-	if (fd < 0) {
-		idr_destroy(&leases);
-		return fd;
-	}
+	ret = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+	if (ret < 0)
+		goto out_lessee;
+	fd = ret;
 
 	DRM_DEBUG_LEASE("Creating lease\n");
-	lessee = drm_lease_create(lessor, &leases);
+	lessee = drm_lease_create(lessor, lessee);
 
 	if (IS_ERR(lessee)) {
 		ret = PTR_ERR(lessee);
-		goto out_leases;
+		goto out_fd;
 	}
 
 	/* Clone the lessor file to create a new file for us */
@@ -558,7 +548,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	lessee_file = file_clone_open(lessor_file);
 	if (IS_ERR(lessee_file)) {
 		ret = PTR_ERR(lessee_file);
-		goto out_lessee;
+		goto out_fd;
 	}
 
 	lessee_priv = lessee_file->private_data;
@@ -579,13 +569,11 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
 	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
 	return 0;
 
+out_fd:
+	put_unused_fd(fd);
 out_lessee:
 	drm_master_put(&lessee);
 
-out_leases:
-	put_unused_fd(fd);
-	idr_destroy(&leases);
-
 	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
 	return ret;
 }
@@ -627,7 +615,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
 	count = 0;
 	xa_for_each(&lessor->lessees, index, lessee) {
 		/* Only list un-revoked leases */
-		if (!idr_is_empty(&lessee->leases)) {
+		if (!xa_empty(&lessee->leases)) {
 			if (count_lessees > count) {
 				DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
 				ret = put_user(lessee->lessee_id, lessee_ids + count);
@@ -663,10 +651,10 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
 	__u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
 	__u32 count_objects = arg->count_objects;
 	struct drm_master *lessee = lessee_priv->master;
-	struct idr *object_idr;
+	struct xarray *objects;
 	int count;
 	void *entry;
-	int object;
+	unsigned long index;
 	int ret = 0;
 
 	if (arg->pad)
@@ -682,16 +670,16 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
 
 	if (lessee->lessor == NULL)
 		/* owner can use all objects */
-		object_idr = &lessee->dev->mode_config.crtc_idr;
+		objects = &lessee->dev->mode_config.objects;
 	else
-		/* lessee can only use allowed object */
-		object_idr = &lessee->leases;
+		/* lessee can only use allowed objects */
+		objects = &lessee->leases;
 
 	count = 0;
-	idr_for_each_entry(object_idr, entry, object) {
+	xa_for_each(objects, index, entry) {
 		if (count_objects > count) {
-			DRM_DEBUG_LEASE("adding object %d\n", object);
-			ret = put_user(object, object_ids + count);
+			DRM_DEBUG_LEASE("adding object %d\n", (u32)index);
+			ret = put_user((u32)index, object_ids + count);
 			if (ret)
 				break;
 		}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 609b30d7dcb1..10c616e0f591 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -393,7 +393,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	INIT_LIST_HEAD(&dev->mode_config.property_list);
 	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
 	INIT_LIST_HEAD(&dev->mode_config.plane_list);
-	idr_init(&dev->mode_config.crtc_idr);
+	xa_init_flags(&dev->mode_config.objects, XA_FLAGS_ALLOC1);
 	xa_init_flags(&dev->mode_config.tiles, XA_FLAGS_ALLOC1);
 	ida_init(&dev->mode_config.connector_ida);
 	spin_lock_init(&dev->mode_config.connector_list_lock);
@@ -495,7 +495,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 	}
 
 	ida_destroy(&dev->mode_config.connector_ida);
-	idr_destroy(&dev->mode_config.crtc_idr);
 	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 004191d01772..686fba472abf 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -37,24 +37,23 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
 {
 	int ret;
 
-	mutex_lock(&dev->mode_config.idr_mutex);
-	ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL,
-			1, 0, GFP_KERNEL);
-	if (ret >= 0) {
-		/*
-		 * Set up the object linking under the protection of the idr
-		 * lock so that other users can't see inconsistent state.
-		 */
-		obj->id = ret;
-		obj->type = obj_type;
-		if (obj_free_cb) {
-			obj->free_cb = obj_free_cb;
-			kref_init(&obj->refcount);
-		}
+	/*
+	 * Initialise the object before putting the object in the array
+	 * so that other users can't see inconsistent state.  The ID is
+	 * initialised before the object is inserted into the array with
+	 * a write barrier so even RCU-protected walkers can't see an
+	 * uninitialised ID.
+	 */
+	obj->type = obj_type;
+	if (obj_free_cb) {
+		obj->free_cb = obj_free_cb;
+		kref_init(&obj->refcount);
 	}
-	mutex_unlock(&dev->mode_config.idr_mutex);
 
-	return ret < 0 ? ret : 0;
+	ret = xa_alloc(&dev->mode_config.objects, &obj->id,
+			register_obj ? obj : NULL, xa_limit_31b, GFP_KERNEL);
+
+	return ret;
 }
 
 /**
@@ -78,9 +77,7 @@ int drm_mode_object_add(struct drm_device *dev,
 void drm_mode_object_register(struct drm_device *dev,
 			      struct drm_mode_object *obj)
 {
-	mutex_lock(&dev->mode_config.idr_mutex);
-	idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
-	mutex_unlock(&dev->mode_config.idr_mutex);
+	xa_store(&dev->mode_config.objects, obj->id, obj, 0);
 }
 
 /**
@@ -97,12 +94,10 @@ void drm_mode_object_register(struct drm_device *dev,
 void drm_mode_object_unregister(struct drm_device *dev,
 				struct drm_mode_object *object)
 {
-	mutex_lock(&dev->mode_config.idr_mutex);
 	if (object->id) {
-		idr_remove(&dev->mode_config.crtc_idr, object->id);
+		xa_erase(&dev->mode_config.objects, object->id);
 		object->id = 0;
 	}
-	mutex_unlock(&dev->mode_config.idr_mutex);
 }
 
 /**
@@ -128,10 +123,10 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
 					       struct drm_file *file_priv,
 					       uint32_t id, uint32_t type)
 {
-	struct drm_mode_object *obj = NULL;
+	struct drm_mode_object *obj;
 
-	mutex_lock(&dev->mode_config.idr_mutex);
-	obj = idr_find(&dev->mode_config.crtc_idr, id);
+	xa_lock(&dev->mode_config.objects);
+	obj = xa_load(&dev->mode_config.objects, id);
 	if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
 		obj = NULL;
 	if (obj && obj->id != id)
@@ -145,7 +140,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
 		if (!kref_get_unless_zero(&obj->refcount))
 			obj = NULL;
 	}
-	mutex_unlock(&dev->mode_config.idr_mutex);
+	xa_unlock(&dev->mode_config.objects);
 
 	return obj;
 }
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index fbb58264538b..88c8bbf14916 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -90,7 +90,7 @@ struct drm_master {
 
 	struct drm_master *lessor;
 	int	lessee_id;
-	struct idr leases;
+	struct xarray leases;
 	struct xarray lessees;
 };
 
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index fea334d99201..64bdf66d878c 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -397,12 +397,12 @@ struct drm_mode_config {
 	struct mutex idr_mutex;
 
 	/**
-	 * @crtc_idr:
+	 * @objects:
 	 *
-	 * Main KMS ID tracking object. Use this idr for all IDs, fb, crtc,
+	 * Main KMS ID tracking object. Use this array for all IDs, fb, crtc,
 	 * connector, modes - just makes life easier to have only one.
 	 */
-	struct idr crtc_idr;
+	struct xarray objects;
 
 	/**
 	 * @tiles:
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 12/34] drm/agp: Convert bo_list_handles to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (10 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 11/34] drm: Convert crtc_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-25 16:06   ` Christian König
  2019-02-21 18:41 ` [PATCH 13/34] drm/amdgpu: Convert ctx_handles " Matthew Wilcox
                   ` (22 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  3 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 22 ++++++++-------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c     | 10 ++++------
 3 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index bcef6ea4bcf9..6a704aaa7dbe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -406,8 +406,7 @@ struct amdgpu_fpriv {
 	struct amdgpu_vm	vm;
 	struct amdgpu_bo_va	*prt_va;
 	struct amdgpu_bo_va	*csa_va;
-	struct mutex		bo_list_lock;
-	struct idr		bo_list_handles;
+	struct xarray		bo_list_handles;
 	struct amdgpu_ctx_mgr	ctx_mgr;
 };
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 5c79da8e1150..76439a52a6b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -153,9 +153,7 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
 {
 	struct amdgpu_bo_list *list;
 
-	mutex_lock(&fpriv->bo_list_lock);
-	list = idr_remove(&fpriv->bo_list_handles, id);
-	mutex_unlock(&fpriv->bo_list_lock);
+	list = xa_erase(&fpriv->bo_list_handles, id);
 	if (list)
 		kref_put(&list->refcount, amdgpu_bo_list_free);
 }
@@ -164,7 +162,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
 		       struct amdgpu_bo_list **result)
 {
 	rcu_read_lock();
-	*result = idr_find(&fpriv->bo_list_handles, id);
+	*result = xa_load(&fpriv->bo_list_handles, id);
 
 	if (*result && kref_get_unless_zero(&(*result)->refcount)) {
 		rcu_read_unlock();
@@ -278,15 +276,13 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 		if (r)
 			goto error_free;
 
-		mutex_lock(&fpriv->bo_list_lock);
-		r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
-		mutex_unlock(&fpriv->bo_list_lock);
+		r = xa_alloc(&fpriv->bo_list_handles, &handle, list,
+				xa_limit_31b, GFP_KERNEL);
 		if (r < 0) {
 			amdgpu_bo_list_put(list);
 			return r;
 		}
 
-		handle = r;
 		break;
 
 	case AMDGPU_BO_LIST_OP_DESTROY:
@@ -300,13 +296,11 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 		if (r)
 			goto error_free;
 
-		mutex_lock(&fpriv->bo_list_lock);
-		old = idr_replace(&fpriv->bo_list_handles, list, handle);
-		mutex_unlock(&fpriv->bo_list_lock);
-
-		if (IS_ERR(old)) {
+		old = xa_store(&fpriv->bo_list_handles, handle, list,
+				GFP_KERNEL);
+		if (xa_is_err(old)) {
 			amdgpu_bo_list_put(list);
-			r = PTR_ERR(old);
+			r = xa_err(old);
 			goto error_free;
 		}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index bc62bf41b7e9..1a5bf3a4f5d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -986,8 +986,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 			goto error_vm;
 	}
 
-	mutex_init(&fpriv->bo_list_lock);
-	idr_init(&fpriv->bo_list_handles);
+	xa_init_flags(&fpriv->bo_list_handles, XA_FLAGS_ALLOC1);
 
 	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr);
 
@@ -1026,7 +1025,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 	struct amdgpu_bo_list *list;
 	struct amdgpu_bo *pd;
 	unsigned int pasid;
-	int handle;
+	unsigned long handle;
 
 	if (!fpriv)
 		return;
@@ -1058,11 +1057,10 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 		amdgpu_pasid_free_delayed(pd->tbo.resv, pasid);
 	amdgpu_bo_unref(&pd);
 
-	idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
+	xa_for_each(&fpriv->bo_list_handles, handle, list)
 		amdgpu_bo_list_put(list);
 
-	idr_destroy(&fpriv->bo_list_handles);
-	mutex_destroy(&fpriv->bo_list_lock);
+	xa_destroy(&fpriv->bo_list_handles);
 
 	kfree(fpriv);
 	file_priv->driver_priv = NULL;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 13/34] drm/amdgpu: Convert ctx_handles to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (11 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 12/34] drm/agp: Convert bo_list_handles " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-25 16:07   ` Christian König
  2019-02-21 18:41 ` [PATCH 14/34] drm/amdgpu: Convert pasid_idr " Matthew Wilcox
                   ` (21 subsequent siblings)
  34 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h       |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c   | 42 ++++++++---------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c |  4 +--
 4 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 6a704aaa7dbe..c2650f143ba7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -164,7 +164,7 @@ extern int amdgpu_si_support;
 extern int amdgpu_cik_support;
 #endif
 
-#define AMDGPU_VM_MAX_NUM_CTX			4096
+#define AMDGPU_VM_CTX_LIMIT			XA_LIMIT(0, 4095)
 #define AMDGPU_SG_THRESHOLD			(256*1024*1024)
 #define AMDGPU_DEFAULT_GTT_SIZE_MB		3072ULL /* 3GB by default */
 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index d85184b5b35c..bddc28b1c9ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -248,17 +248,17 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
 		return -ENOMEM;
 
 	mutex_lock(&mgr->lock);
-	r = idr_alloc(&mgr->ctx_handles, ctx, 1, AMDGPU_VM_MAX_NUM_CTX, GFP_KERNEL);
+	r = xa_alloc(&mgr->ctx_handles, id, ctx, AMDGPU_VM_CTX_LIMIT,
+			GFP_KERNEL);
 	if (r < 0) {
 		mutex_unlock(&mgr->lock);
 		kfree(ctx);
 		return r;
 	}
 
-	*id = (uint32_t)r;
 	r = amdgpu_ctx_init(adev, priority, filp, ctx);
 	if (r) {
-		idr_remove(&mgr->ctx_handles, *id);
+		xa_erase(&mgr->ctx_handles, *id);
 		*id = 0;
 		kfree(ctx);
 	}
@@ -290,7 +290,7 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
 	struct amdgpu_ctx *ctx;
 
 	mutex_lock(&mgr->lock);
-	ctx = idr_remove(&mgr->ctx_handles, id);
+	ctx = xa_erase(&mgr->ctx_handles, id);
 	if (ctx)
 		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
 	mutex_unlock(&mgr->lock);
@@ -310,7 +310,7 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
 
 	mgr = &fpriv->ctx_mgr;
 	mutex_lock(&mgr->lock);
-	ctx = idr_find(&mgr->ctx_handles, id);
+	ctx = xa_load(&mgr->ctx_handles, id);
 	if (!ctx) {
 		mutex_unlock(&mgr->lock);
 		return -EINVAL;
@@ -345,7 +345,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
 
 	mgr = &fpriv->ctx_mgr;
 	mutex_lock(&mgr->lock);
-	ctx = idr_find(&mgr->ctx_handles, id);
+	ctx = xa_load(&mgr->ctx_handles, id);
 	if (!ctx) {
 		mutex_unlock(&mgr->lock);
 		return -EINVAL;
@@ -419,7 +419,7 @@ struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
 	mgr = &fpriv->ctx_mgr;
 
 	mutex_lock(&mgr->lock);
-	ctx = idr_find(&mgr->ctx_handles, id);
+	ctx = xa_load(&mgr->ctx_handles, id);
 	if (ctx)
 		kref_get(&ctx->refcount);
 	mutex_unlock(&mgr->lock);
@@ -533,22 +533,18 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
 {
 	mutex_init(&mgr->lock);
-	idr_init(&mgr->ctx_handles);
+	xa_init_flags(&mgr->ctx_handles, XA_FLAGS_ALLOC1);
 }
 
 void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
 {
 	unsigned num_entities = amdgput_ctx_total_num_entities();
 	struct amdgpu_ctx *ctx;
-	struct idr *idp;
-	uint32_t id, i;
+	unsigned long id, i;
 	long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
 
-	idp = &mgr->ctx_handles;
-
 	mutex_lock(&mgr->lock);
-	idr_for_each_entry(idp, ctx, id) {
-
+	xa_for_each(&mgr->ctx_handles, id, ctx) {
 		if (!ctx->adev) {
 			mutex_unlock(&mgr->lock);
 			return;
@@ -568,13 +564,9 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
 {
 	unsigned num_entities = amdgput_ctx_total_num_entities();
 	struct amdgpu_ctx *ctx;
-	struct idr *idp;
-	uint32_t id, i;
-
-	idp = &mgr->ctx_handles;
-
-	idr_for_each_entry(idp, ctx, id) {
+	unsigned long id, i;
 
+	xa_for_each(&mgr->ctx_handles, id, ctx) {
 		if (!ctx->adev)
 			return;
 
@@ -591,18 +583,14 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
 {
 	struct amdgpu_ctx *ctx;
-	struct idr *idp;
-	uint32_t id;
+	unsigned long id;
 
 	amdgpu_ctx_mgr_entity_fini(mgr);
 
-	idp = &mgr->ctx_handles;
-
-	idr_for_each_entry(idp, ctx, id) {
+	xa_for_each(&mgr->ctx_handles, id, ctx) {
 		if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
 			DRM_ERROR("ctx %p is still alive\n", ctx);
 	}
-
-	idr_destroy(&mgr->ctx_handles);
+	xa_destroy(&mgr->ctx_handles);
 	mutex_destroy(&mgr->lock);
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
index b3b012c0a7da..011b1f15308a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
@@ -55,7 +55,7 @@ struct amdgpu_ctx_mgr {
 	struct amdgpu_device	*adev;
 	struct mutex		lock;
 	/* protected by lock */
-	struct idr		ctx_handles;
+	struct xarray		ctx_handles;
 };
 
 extern const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM];
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
index 1cafe8d83a4d..278b4bd98dcc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
@@ -57,14 +57,14 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
 	struct drm_file *file;
 	struct amdgpu_fpriv *fpriv;
 	struct amdgpu_ctx *ctx;
-	uint32_t id;
+	unsigned long id;
 
 	if (!filp)
 		return -EINVAL;
 
 	file = filp->private_data;
 	fpriv = file->driver_priv;
-	idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
+	xa_for_each(&fpriv->ctx_mgr.ctx_handles, id, ctx)
 		amdgpu_ctx_priority_override(ctx, priority);
 
 	fput(filp);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 14/34] drm/amdgpu: Convert pasid_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (12 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 13/34] drm/amdgpu: Convert ctx_handles " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 15/34] drm/amdkfd: Convert event_idr " Matthew Wilcox
                   ` (20 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 66 +++++++++-----------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  3 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  | 12 ++---
 3 files changed, 29 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index d2ea5ce2cefb..d094ec7433f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3032,12 +3032,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	amdgpu_bo_unreserve(vm->root.base.bo);
 
 	if (pasid) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1,
-			      GFP_ATOMIC);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+		r = xa_insert_irq(&adev->vm_manager.vms, pasid, vm, GFP_KERNEL);
 		if (r < 0)
 			goto error_free_root;
 
@@ -3047,6 +3042,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	vm->fault_hash = init_fault_hash();
 	if (!vm->fault_hash) {
 		r = -ENOMEM;
+		if (pasid)
+			xa_erase_irq(&adev->vm_manager.vms, pasid);
 		goto error_free_root;
 	}
 
@@ -3104,16 +3101,9 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
 	}
 
 	if (pasid) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1,
-			      GFP_ATOMIC);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
-
-		if (r == -ENOSPC)
+		r = xa_insert_irq(&adev->vm_manager.vms, pasid, vm, GFP_KERNEL);
+		if (r < 0)
 			goto unreserve_bo;
-		r = 0;
 	}
 
 	/* Check if PD needs to be reinitialized and do it before
@@ -3124,7 +3114,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
 			       adev->vm_manager.root_level,
 			       pte_support_ats);
 		if (r)
-			goto free_idr;
+			goto erase;
 	}
 
 	/* Update VM state */
@@ -3137,11 +3127,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
 		  "CPU update of VM recommended only for large BAR system\n");
 
 	if (vm->pasid) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+		xa_erase_irq(&adev->vm_manager.vms, vm->pasid);
 
 		/* Free the original amdgpu allocated pasid
 		 * Will be replaced with kfd allocated pasid
@@ -3158,14 +3144,9 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
 
 	goto unreserve_bo;
 
-free_idr:
-	if (pasid) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		idr_remove(&adev->vm_manager.pasid_idr, pasid);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
-	}
+erase:
+	if (pasid)
+		xa_erase_irq(&adev->vm_manager.vms, pasid);
 unreserve_bo:
 	amdgpu_bo_unreserve(vm->root.base.bo);
 	return r;
@@ -3184,9 +3165,9 @@ void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 	if (vm->pasid) {
 		unsigned long flags;
 
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+		xa_lock_irqsave(&adev->vm_manager.vms, flags);
+		__xa_erase(&adev->vm_manager.vms, vm->pasid);
+		xa_unlock_irqrestore(&adev->vm_manager.vms, flags);
 	}
 	vm->pasid = 0;
 }
@@ -3217,9 +3198,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 	if (vm->pasid) {
 		unsigned long flags;
 
-		spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
-		idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
-		spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+		xa_lock_irqsave(&adev->vm_manager.vms, flags);
+		__xa_erase(&adev->vm_manager.vms, vm->pasid);
+		xa_unlock_irqrestore(&adev->vm_manager.vms, flags);
 	}
 
 	kfree(vm->fault_hash);
@@ -3299,8 +3280,8 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
 	adev->vm_manager.vm_update_mode = 0;
 #endif
 
-	idr_init(&adev->vm_manager.pasid_idr);
-	spin_lock_init(&adev->vm_manager.pasid_lock);
+	xa_init_flags(&adev->vm_manager.vms,
+			XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
 }
 
 /**
@@ -3312,8 +3293,7 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
  */
 void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
 {
-	WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr));
-	idr_destroy(&adev->vm_manager.pasid_idr);
+	WARN_ON(!xa_empty(&adev->vm_manager.vms));
 
 	amdgpu_vmid_mgr_fini(adev);
 }
@@ -3364,13 +3344,11 @@ void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid,
 {
 	struct amdgpu_vm *vm;
 
-	spin_lock(&adev->vm_manager.pasid_lock);
-
-	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
+	xa_lock(&adev->vm_manager.vms);
+	vm = xa_load(&adev->vm_manager.vms, pasid);
 	if (vm)
 		*task_info = vm->task_info;
-
-	spin_unlock(&adev->vm_manager.pasid_lock);
+	xa_unlock(&adev->vm_manager.vms);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index e8dcfd59fc93..84b466eee449 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -281,8 +281,7 @@ struct amdgpu_vm_manager {
 	/* PASID to VM mapping, will be used in interrupt context to
 	 * look up VM of a page fault
 	 */
-	struct idr				pasid_idr;
-	spinlock_t				pasid_lock;
+	struct xarray				vms;
 };
 
 #define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index bacdaef77b6c..c0e6503b7965 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -268,11 +268,11 @@ static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev,
 		return true;
 
 	/* Track retry faults in per-VM fault FIFO. */
-	spin_lock(&adev->vm_manager.pasid_lock);
-	vm = idr_find(&adev->vm_manager.pasid_idr, entry->pasid);
+	xa_lock(&adev->vm_manager.vms);
+	vm = xa_load(&adev->vm_manager.vms, entry->pasid);
 	if (!vm) {
 		/* VM not found, process it normally */
-		spin_unlock(&adev->vm_manager.pasid_lock);
+		xa_unlock(&adev->vm_manager.vms);
 		return true;
 	}
 
@@ -283,7 +283,7 @@ static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev,
 	 * ignore further page faults
 	 */
 	if (r != 0) {
-		spin_unlock(&adev->vm_manager.pasid_lock);
+		xa_unlock(&adev->vm_manager.vms);
 		return false;
 	}
 	/* No locking required with single writer and single reader */
@@ -291,11 +291,11 @@ static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev,
 	if (!r) {
 		/* FIFO is full. Ignore it until there is space */
 		amdgpu_vm_clear_fault(vm->fault_hash, key);
-		spin_unlock(&adev->vm_manager.pasid_lock);
+		xa_unlock(&adev->vm_manager.vms);
 		return false;
 	}
 
-	spin_unlock(&adev->vm_manager.pasid_lock);
+	xa_unlock(&adev->vm_manager.vms);
 	/* It's the first fault for this address, process it normally */
 	return true;
 }
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 15/34] drm/amdkfd: Convert event_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (13 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 14/34] drm/amdgpu: Convert pasid_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 16/34] drm/amdkfd: Convert alloc_idr " Matthew Wilcox
                   ` (19 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdkfd/kfd_events.c | 71 ++++++++++---------------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h   |  2 +-
 2 files changed, 30 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index e9f0e0a1b41c..28adfb52d7ca 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -94,7 +94,7 @@ static struct kfd_signal_page *allocate_signal_page(struct kfd_process *p)
 static int allocate_event_notification_slot(struct kfd_process *p,
 					    struct kfd_event *ev)
 {
-	int id;
+	int err;
 
 	if (!p->signal_page) {
 		p->signal_page = allocate_signal_page(p);
@@ -110,13 +110,12 @@ static int allocate_event_notification_slot(struct kfd_process *p,
 	 * KFD_SIGNAL_EVENT_LIMIT. This also allows future increase
 	 * of the event limit without breaking user mode.
 	 */
-	id = idr_alloc(&p->event_idr, ev, 0, p->signal_mapped_size / 8,
-		       GFP_KERNEL);
-	if (id < 0)
-		return id;
+	err = xa_alloc(&p->events, &ev->event_id, ev,
+			XA_LIMIT(0, p->signal_mapped_size / 8 - 1), GFP_KERNEL);
+	if (err < 0)
+		return err;
 
-	ev->event_id = id;
-	page_slots(p->signal_page)[id] = UNSIGNALED_EVENT_SLOT;
+	page_slots(p->signal_page)[ev->event_id] = UNSIGNALED_EVENT_SLOT;
 
 	return 0;
 }
@@ -127,7 +126,7 @@ static int allocate_event_notification_slot(struct kfd_process *p,
  */
 static struct kfd_event *lookup_event_by_id(struct kfd_process *p, uint32_t id)
 {
-	return idr_find(&p->event_idr, id);
+	return xa_load(&p->events, id);
 }
 
 /**
@@ -162,7 +161,7 @@ static struct kfd_event *lookup_signaled_event_by_partial_id(
 		if (page_slots(p->signal_page)[id] == UNSIGNALED_EVENT_SLOT)
 			return NULL;
 
-		return idr_find(&p->event_idr, id);
+		return xa_load(&p->events, id);
 	}
 
 	/* General case for partial IDs: Iterate over all matching IDs
@@ -172,7 +171,7 @@ static struct kfd_event *lookup_signaled_event_by_partial_id(
 		if (page_slots(p->signal_page)[id] == UNSIGNALED_EVENT_SLOT)
 			continue;
 
-		ev = idr_find(&p->event_idr, id);
+		ev = xa_load(&p->events, id);
 	}
 
 	return ev;
@@ -211,26 +210,15 @@ static int create_signal_event(struct file *devkfd,
 
 static int create_other_event(struct kfd_process *p, struct kfd_event *ev)
 {
-	/* Cast KFD_LAST_NONSIGNAL_EVENT to uint32_t. This allows an
-	 * intentional integer overflow to -1 without a compiler
-	 * warning. idr_alloc treats a negative value as "maximum
-	 * signed integer".
-	 */
-	int id = idr_alloc(&p->event_idr, ev, KFD_FIRST_NONSIGNAL_EVENT_ID,
-			   (uint32_t)KFD_LAST_NONSIGNAL_EVENT_ID + 1,
-			   GFP_KERNEL);
-
-	if (id < 0)
-		return id;
-	ev->event_id = id;
-
-	return 0;
+	return xa_alloc(&p->events, &ev->event_id, ev,
+			XA_LIMIT(KFD_FIRST_NONSIGNAL_EVENT_ID,
+				KFD_LAST_NONSIGNAL_EVENT_ID), GFP_KERNEL);
 }
 
 void kfd_event_init_process(struct kfd_process *p)
 {
 	mutex_init(&p->event_mutex);
-	idr_init(&p->event_idr);
+	xa_init_flags(&p->events, XA_FLAGS_ALLOC);
 	p->signal_page = NULL;
 	p->signal_event_count = 0;
 }
@@ -248,18 +236,18 @@ static void destroy_event(struct kfd_process *p, struct kfd_event *ev)
 	    ev->type == KFD_EVENT_TYPE_DEBUG)
 		p->signal_event_count--;
 
-	idr_remove(&p->event_idr, ev->event_id);
+	xa_erase(&p->events, ev->event_id);
 	kfree(ev);
 }
 
 static void destroy_events(struct kfd_process *p)
 {
 	struct kfd_event *ev;
-	uint32_t id;
+	unsigned long id;
 
-	idr_for_each_entry(&p->event_idr, ev, id)
+	xa_for_each(&p->events, id, ev)
 		destroy_event(p, ev);
-	idr_destroy(&p->event_idr);
+	xa_destroy(&p->events);
 }
 
 /*
@@ -490,7 +478,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
 		 * exhaustive search of signaled events.
 		 */
 		uint64_t *slots = page_slots(p->signal_page);
-		uint32_t id;
+		unsigned long id;
 
 		if (valid_id_bits)
 			pr_debug_ratelimited("Partial ID invalid: %u (%u valid bits)\n",
@@ -498,9 +486,9 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
 
 		if (p->signal_event_count < KFD_SIGNAL_EVENT_LIMIT / 64) {
 			/* With relatively few events, it's faster to
-			 * iterate over the event IDR
+			 * iterate over the event array
 			 */
-			idr_for_each_entry(&p->event_idr, ev, id) {
+			xa_for_each(&p->events, id, ev) {
 				if (id >= KFD_SIGNAL_EVENT_LIMIT)
 					break;
 
@@ -510,7 +498,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
 		} else {
 			/* With relatively many events, it's faster to
 			 * iterate over the signal slots and lookup
-			 * only signaled events from the IDR.
+			 * only signaled events from the array.
 			 */
 			for (id = 0; id < KFD_SIGNAL_EVENT_LIMIT; id++)
 				if (slots[id] != UNSIGNALED_EVENT_SLOT) {
@@ -833,13 +821,12 @@ static void lookup_events_by_type_and_signal(struct kfd_process *p,
 {
 	struct kfd_hsa_memory_exception_data *ev_data;
 	struct kfd_event *ev;
-	uint32_t id;
+	unsigned long id;
 	bool send_signal = true;
 
 	ev_data = (struct kfd_hsa_memory_exception_data *) event_data;
 
-	id = KFD_FIRST_NONSIGNAL_EVENT_ID;
-	idr_for_each_entry_continue(&p->event_idr, ev, id)
+	xa_for_each_start(&p->events, id, ev, KFD_FIRST_NONSIGNAL_EVENT_ID)
 		if (ev->type == type) {
 			send_signal = false;
 			dev_dbg(kfd_device,
@@ -975,7 +962,7 @@ void kfd_signal_vm_fault_event(struct kfd_dev *dev, unsigned int pasid,
 				struct kfd_vm_fault_info *info)
 {
 	struct kfd_event *ev;
-	uint32_t id;
+	unsigned long id;
 	struct kfd_process *p = kfd_lookup_process_by_pasid(pasid);
 	struct kfd_hsa_memory_exception_data memory_exception_data;
 
@@ -997,8 +984,7 @@ void kfd_signal_vm_fault_event(struct kfd_dev *dev, unsigned int pasid,
 	}
 	mutex_lock(&p->event_mutex);
 
-	id = KFD_FIRST_NONSIGNAL_EVENT_ID;
-	idr_for_each_entry_continue(&p->event_idr, ev, id)
+	xa_for_each_start(&p->events, id, ev, KFD_FIRST_NONSIGNAL_EVENT_ID)
 		if (ev->type == KFD_EVENT_TYPE_MEMORY) {
 			ev->memory_exception_data = memory_exception_data;
 			set_event(ev);
@@ -1014,7 +1000,8 @@ void kfd_signal_reset_event(struct kfd_dev *dev)
 	struct kfd_process *p;
 	struct kfd_event *ev;
 	unsigned int temp;
-	uint32_t id, idx;
+	unsigned long id;
+	int idx;
 
 	/* Whole gpu reset caused by GPU hang and memory is lost */
 	memset(&hw_exception_data, 0, sizeof(hw_exception_data));
@@ -1024,8 +1011,8 @@ void kfd_signal_reset_event(struct kfd_dev *dev)
 	idx = srcu_read_lock(&kfd_processes_srcu);
 	hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
 		mutex_lock(&p->event_mutex);
-		id = KFD_FIRST_NONSIGNAL_EVENT_ID;
-		idr_for_each_entry_continue(&p->event_idr, ev, id)
+		xa_for_each_start(&p->events, id, ev,
+				KFD_FIRST_NONSIGNAL_EVENT_ID)
 			if (ev->type == KFD_EVENT_TYPE_HW_EXCEPTION) {
 				ev->hw_exception_data = hw_exception_data;
 				set_event(ev);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 0689d4ccbbc0..9878abc6d847 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -657,7 +657,7 @@ struct kfd_process {
 	/* Event-related data */
 	struct mutex event_mutex;
 	/* Event ID allocator and lookup */
-	struct idr event_idr;
+	struct xarray events;
 	/* Event page */
 	struct kfd_signal_page *signal_page;
 	size_t signal_mapped_size;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 16/34] drm/amdkfd: Convert alloc_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (14 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 15/34] drm/amdkfd: Convert event_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 17/34] drm/etnaviv: Convert fence_idr " Matthew Wilcox
                   ` (18 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h    |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_process.c | 32 +++++++++++-------------
 2 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 9878abc6d847..4f67cb707b7b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -590,7 +590,7 @@ struct kfd_process_device {
 	void *vm;
 
 	/* GPUVM allocations storage */
-	struct idr alloc_idr;
+	struct xarray allocations;
 
 	/* Flag used to tell the pdd has dequeued from the dqm.
 	 * This is used to prevent dev->dqm->ops.process_termination() from
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 80b36e860a0a..1ed34d0e9561 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -284,13 +284,13 @@ static void kfd_process_device_free_bos(struct kfd_process_device *pdd)
 {
 	struct kfd_process *p = pdd->process;
 	void *mem;
-	int id;
+	unsigned long id;
 
 	/*
-	 * Remove all handles from idr and release appropriate
+	 * Remove all handles and release appropriate
 	 * local memory object
 	 */
-	idr_for_each_entry(&pdd->alloc_idr, mem, id) {
+	xa_for_each(&pdd->allocations, id, mem) {
 		struct kfd_process_device *peer_pdd;
 
 		list_for_each_entry(peer_pdd, &p->per_device_data,
@@ -339,8 +339,6 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
 				get_order(KFD_CWSR_TBA_TMA_SIZE));
 
 		kfree(pdd->qpd.doorbell_bitmap);
-		idr_destroy(&pdd->alloc_idr);
-
 		kfree(pdd);
 	}
 }
@@ -656,8 +654,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 	pdd->already_dequeued = false;
 	list_add(&pdd->per_device_list, &p->per_device_data);
 
-	/* Init idr used for memory handle translation */
-	idr_init(&pdd->alloc_idr);
+	xa_init_flags(&pdd->allocations, XA_FLAGS_ALLOC);
 
 	return pdd;
 }
@@ -774,35 +771,36 @@ bool kfd_has_process_device_data(struct kfd_process *p)
 	return !(list_empty(&p->per_device_data));
 }
 
-/* Create specific handle mapped to mem from process local memory idr
+/* Create specific handle mapped to mem from process local memory
  * Assumes that the process lock is held.
  */
 int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd,
 					void *mem)
 {
-	return idr_alloc(&pdd->alloc_idr, mem, 0, 0, GFP_KERNEL);
+	int id, ret;
+
+	ret = xa_alloc(&pdd->allocations, &id, mem, xa_limit_31b, GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	return id;
 }
 
-/* Translate specific handle from process local memory idr
+/* Translate specific handle from process local memory
  * Assumes that the process lock is held.
  */
 void *kfd_process_device_translate_handle(struct kfd_process_device *pdd,
 					int handle)
 {
-	if (handle < 0)
-		return NULL;
-
-	return idr_find(&pdd->alloc_idr, handle);
+	return xa_load(&pdd->allocations, handle);
 }
 
-/* Remove specific handle from process local memory idr
+/* Remove specific handle from process local memory
  * Assumes that the process lock is held.
  */
 void kfd_process_device_remove_obj_handle(struct kfd_process_device *pdd,
 					int handle)
 {
-	if (handle >= 0)
-		idr_remove(&pdd->alloc_idr, handle);
+	xa_erase(&pdd->allocations, handle);
 }
 
 /* This increments the process->ref counter. */
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 17/34] drm/etnaviv: Convert fence_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (15 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 16/34] drm/amdkfd: Convert alloc_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 18/34] drm/i915: Convert handles_vma " Matthew Wilcox
                   ` (17 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 4 +---
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c        | 5 ++---
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h        | 3 ++-
 drivers/gpu/drm/etnaviv/etnaviv_sched.c      | 8 ++++----
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 98f803510e0a..f950542290ca 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -388,9 +388,7 @@ static void submit_cleanup(struct kref *kref)
 		dma_fence_put(submit->in_fence);
 	if (submit->out_fence) {
 		/* first remove from IDR, so fence can not be found anymore */
-		mutex_lock(&submit->gpu->fence_lock);
-		idr_remove(&submit->gpu->fence_idr, submit->out_fence_id);
-		mutex_unlock(&submit->gpu->fence_lock);
+		xa_erase(&submit->gpu->fences, submit->out_fence_id);
 		dma_fence_put(submit->out_fence);
 	}
 	kfree(submit->pmrs);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 6904535475de..b1d407308680 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1147,7 +1147,7 @@ int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
 	 * pretends we didn't find a fence in that case.
 	 */
 	rcu_read_lock();
-	fence = idr_find(&gpu->fence_idr, id);
+	fence = xa_load(&gpu->fences, id);
 	if (fence)
 		fence = dma_fence_get_rcu(fence);
 	rcu_read_unlock();
@@ -1630,7 +1630,7 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
 
 	gpu->drm = drm;
 	gpu->fence_context = dma_fence_context_alloc(1);
-	idr_init(&gpu->fence_idr);
+	xa_init_flags(&gpu->fences, XA_FLAGS_ALLOC);
 	spin_lock_init(&gpu->fence_spinlock);
 
 	INIT_WORK(&gpu->sync_point_work, sync_point_worker);
@@ -1689,7 +1689,6 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
 	}
 
 	gpu->drm = NULL;
-	idr_destroy(&gpu->fence_idr);
 
 	if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL))
 		thermal_cooling_device_unregister(gpu->cooling);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 9bcf151f706b..d87406ffecb5 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -117,7 +117,8 @@ struct etnaviv_gpu {
 
 	/* Fencing support */
 	struct mutex fence_lock;
-	struct idr fence_idr;
+	struct xarray fences;
+	u32 fences_next;	/* For the XArray allocation */
 	u32 next_fence;
 	u32 completed_fence;
 	wait_queue_head_t fence_event;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 49a6763693f1..f515e671ff07 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -155,10 +155,10 @@ int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
 		goto out_unlock;
 
 	submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
-	submit->out_fence_id = idr_alloc_cyclic(&submit->gpu->fence_idr,
-						submit->out_fence, 0,
-						INT_MAX, GFP_KERNEL);
-	if (submit->out_fence_id < 0) {
+	ret = xa_alloc_cyclic(&submit->gpu->fences, &submit->out_fence_id,
+				submit->out_fence, xa_limit_31b,
+				&submit->gpu->fences_next, GFP_KERNEL);
+	if (ret < 0) {
 		drm_sched_job_cleanup(&submit->sched_job);
 		ret = -ENOMEM;
 		goto out_unlock;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 18/34] drm/i915: Convert handles_vma to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (16 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 17/34] drm/etnaviv: Convert fence_idr " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 19/34] drm/i915: Convert spt_tree " Matthew Wilcox
                   ` (16 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Straightforward conversion.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/i915_gem.c               |  2 +-
 drivers/gpu/drm/i915/i915_gem_context.c       | 12 +++++-------
 drivers/gpu/drm/i915/i915_gem_context.h       |  4 ++--
 drivers/gpu/drm/i915/i915_gem_execbuffer.c    |  6 +++---
 drivers/gpu/drm/i915/selftests/mock_context.c |  2 +-
 5 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 216f52b744a6..0cdccc886587 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3663,7 +3663,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 		if (ctx->file_priv != fpriv)
 			continue;
 
-		vma = radix_tree_delete(&ctx->handles_vma, lut->handle);
+		vma = xa_erase(&ctx->handles_vma, lut->handle);
 		GEM_BUG_ON(vma->obj != obj);
 
 		/* We allow the process to have multiple handles to the same
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 371c07087095..9db04b2e65cf 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -96,9 +96,9 @@
 
 static void lut_close(struct i915_gem_context *ctx)
 {
+	XA_STATE(xas, &ctx->handles_vma, 0);
 	struct i915_lut_handle *lut, *ln;
-	struct radix_tree_iter iter;
-	void __rcu **slot;
+	struct i915_vma *vma;
 
 	list_for_each_entry_safe(lut, ln, &ctx->handles_list, ctx_link) {
 		list_del(&lut->obj_link);
@@ -106,10 +106,8 @@ static void lut_close(struct i915_gem_context *ctx)
 	}
 
 	rcu_read_lock();
-	radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) {
-		struct i915_vma *vma = rcu_dereference_raw(*slot);
-
-		radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
+	xas_for_each(&xas, vma, ULONG_MAX) {
+		xas_store(&xas, NULL);
 		__i915_gem_object_release_unless_active(vma->obj);
 	}
 	rcu_read_unlock();
@@ -345,7 +343,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
 		ce->gem_context = ctx;
 	}
 
-	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+	xa_init(&ctx->handles_vma);
 	INIT_LIST_HEAD(&ctx->handles_list);
 	INIT_LIST_HEAD(&ctx->hw_id_link);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index f6d870b1f73e..ec22de370a22 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -194,11 +194,11 @@ struct i915_gem_context {
 	/** remap_slice: Bitmask of cache lines that need remapping */
 	u8 remap_slice;
 
-	/** handles_vma: rbtree to look up our context specific obj/vma for
+	/** handles_vma: lookup our context specific obj/vma for
 	 * the user handle. (user handles are per fd, but the binding is
 	 * per vm, which may be one per context or shared with the global GTT)
 	 */
-	struct radix_tree_root handles_vma;
+	struct xarray handles_vma;
 
 	/** handles_list: reverse list of all the rbtree entries in use for
 	 * this context, which allows us to free all the allocations on
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 485b259127c3..8f136da3f73a 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -756,7 +756,7 @@ static int eb_select_context(struct i915_execbuffer *eb)
 
 static int eb_lookup_vmas(struct i915_execbuffer *eb)
 {
-	struct radix_tree_root *handles_vma = &eb->ctx->handles_vma;
+	struct xarray *handles_vma = &eb->ctx->handles_vma;
 	struct drm_i915_gem_object *obj;
 	unsigned int i, batch;
 	int err;
@@ -777,7 +777,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 		struct i915_lut_handle *lut;
 		struct i915_vma *vma;
 
-		vma = radix_tree_lookup(handles_vma, handle);
+		vma = xa_load(handles_vma, handle);
 		if (likely(vma))
 			goto add_vma;
 
@@ -799,7 +799,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 			goto err_obj;
 		}
 
-		err = radix_tree_insert(handles_vma, handle, vma);
+		err = xa_err(xa_store(handles_vma, handle, vma, GFP_KERNEL));
 		if (unlikely(err)) {
 			kmem_cache_free(eb->i915->luts, lut);
 			goto err_obj;
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c
index d937bdff26f9..ab42ab625f25 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.c
+++ b/drivers/gpu/drm/i915/selftests/mock_context.c
@@ -41,7 +41,7 @@ mock_context(struct drm_i915_private *i915,
 	INIT_LIST_HEAD(&ctx->link);
 	ctx->i915 = i915;
 
-	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+	xa_init(&ctx->handles_vma);
 	INIT_LIST_HEAD(&ctx->handles_list);
 	INIT_LIST_HEAD(&ctx->hw_id_link);
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 19/34] drm/i915: Convert spt_tree to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (17 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 18/34] drm/i915: Convert handles_vma " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:41 ` [PATCH 20/34] drm/i915: Convert page_track_tree " Matthew Wilcox
                   ` (15 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

A straightforward conversion.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/gvt/gtt.c  | 18 ++++++++----------
 drivers/gpu/drm/i915/gvt/gtt.h  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h |  1 +
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index c7103dd2d8d5..4b8468839312 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -735,7 +735,7 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)
 	dma_unmap_page(kdev, spt->shadow_page.mfn << I915_GTT_PAGE_SHIFT, 4096,
 		       PCI_DMA_BIDIRECTIONAL);
 
-	radix_tree_delete(&spt->vgpu->gtt.spt_tree, spt->shadow_page.mfn);
+	xa_erase(&spt->vgpu->gtt.spts, spt->shadow_page.mfn);
 
 	if (spt->guest_page.gfn) {
 		if (spt->guest_page.oos_page)
@@ -751,11 +751,9 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)
 static void ppgtt_free_all_spt(struct intel_vgpu *vgpu)
 {
 	struct intel_vgpu_ppgtt_spt *spt;
-	struct radix_tree_iter iter;
-	void **slot;
+	unsigned long index;
 
-	radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) {
-		spt = radix_tree_deref_slot(slot);
+	xa_for_each(&vgpu->gtt.spts, index, spt) {
 		ppgtt_free_spt(spt);
 	}
 }
@@ -798,7 +796,7 @@ static struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_gfn(
 static inline struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn(
 		struct intel_vgpu *vgpu, unsigned long mfn)
 {
-	return radix_tree_lookup(&vgpu->gtt.spt_tree, mfn);
+	return xa_load(&vgpu->gtt.spts, mfn);
 }
 
 static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt);
@@ -840,13 +838,13 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
 	spt->shadow_page.vaddr = page_address(spt->shadow_page.page);
 	spt->shadow_page.mfn = daddr >> I915_GTT_PAGE_SHIFT;
 
-	ret = radix_tree_insert(&vgpu->gtt.spt_tree, spt->shadow_page.mfn, spt);
-	if (ret)
+	if (xa_store(&vgpu->gtt.spts, spt->shadow_page.mfn, spt, GFP_KERNEL))
 		goto err_unmap_dma;
 
 	return spt;
 
 err_unmap_dma:
+	ret = -ENOMEM;
 	dma_unmap_page(kdev, daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 err_free_spt:
 	free_spt(spt);
@@ -2407,7 +2405,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
 {
 	struct intel_vgpu_gtt *gtt = &vgpu->gtt;
 
-	INIT_RADIX_TREE(&gtt->spt_tree, GFP_KERNEL);
+	xa_init(&gtt->spts);
 
 	INIT_LIST_HEAD(&gtt->ppgtt_mm_list_head);
 	INIT_LIST_HEAD(&gtt->oos_page_list_head);
@@ -2439,7 +2437,7 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
 	if (GEM_WARN_ON(!list_empty(&vgpu->gtt.ppgtt_mm_list_head)))
 		gvt_err("vgpu ppgtt mm is not fully destroyed\n");
 
-	if (GEM_WARN_ON(!radix_tree_empty(&vgpu->gtt.spt_tree))) {
+	if (GEM_WARN_ON(!xa_empty(&vgpu->gtt.spts))) {
 		gvt_err("Why we still has spt not freed?\n");
 		ppgtt_free_all_spt(vgpu);
 	}
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index d8cb04cc946d..b7a858aab356 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -198,7 +198,7 @@ struct intel_vgpu_gtt {
 	struct intel_vgpu_mm *ggtt_mm;
 	unsigned long active_ppgtt_mm_bitmap;
 	struct list_head ppgtt_mm_list_head;
-	struct radix_tree_root spt_tree;
+	struct xarray spts;
 	struct list_head oos_page_list_head;
 	struct list_head post_shadow_list_head;
 	struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX];
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b1c31967194b..4b5ce517cbcf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -45,6 +45,7 @@
 #include <linux/pm_qos.h>
 #include <linux/reservation.h>
 #include <linux/shmem_fs.h>
+#include <linux/xarray.h>
 
 #include <drm/drmP.h>
 #include <drm/intel-gtt.h>
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 20/34] drm/i915: Convert page_track_tree to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (18 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 19/34] drm/i915: Convert spt_tree " Matthew Wilcox
@ 2019-02-21 18:41 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 21/34] drm/i915: Convert get_page " Matthew Wilcox
                   ` (14 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:41 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

No locking changes.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/gvt/gvt.h        | 2 +-
 drivers/gpu/drm/i915/gvt/page_track.c | 6 +++---
 drivers/gpu/drm/i915/gvt/vgpu.c       | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index b4ab1dad0143..e5bf20dcdd7d 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -198,7 +198,7 @@ struct intel_vgpu {
 	struct intel_vgpu_opregion opregion;
 	struct intel_vgpu_display display;
 	struct intel_vgpu_submission submission;
-	struct radix_tree_root page_track_tree;
+	struct xarray page_track;
 	u32 hws_pga[I915_NUM_ENGINES];
 
 	struct dentry *debugfs;
diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c
index 84856022528e..8e8b5935f344 100644
--- a/drivers/gpu/drm/i915/gvt/page_track.c
+++ b/drivers/gpu/drm/i915/gvt/page_track.c
@@ -34,7 +34,7 @@
 struct intel_vgpu_page_track *intel_vgpu_find_page_track(
 		struct intel_vgpu *vgpu, unsigned long gfn)
 {
-	return radix_tree_lookup(&vgpu->page_track_tree, gfn);
+	return xa_load(&vgpu->page_track, gfn);
 }
 
 /**
@@ -64,7 +64,7 @@ int intel_vgpu_register_page_track(struct intel_vgpu *vgpu, unsigned long gfn,
 	track->handler = handler;
 	track->priv_data = priv;
 
-	ret = radix_tree_insert(&vgpu->page_track_tree, gfn, track);
+	ret = xa_err(xa_store(&vgpu->page_track, gfn, track, GFP_KERNEL));
 	if (ret) {
 		kfree(track);
 		return ret;
@@ -84,7 +84,7 @@ void intel_vgpu_unregister_page_track(struct intel_vgpu *vgpu,
 {
 	struct intel_vgpu_page_track *track;
 
-	track = radix_tree_delete(&vgpu->page_track_tree, gfn);
+	track = xa_erase(&vgpu->page_track, gfn);
 	if (track) {
 		if (track->tracked)
 			intel_gvt_hypervisor_disable_page_track(vgpu, gfn);
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index c628be05fbfe..6ec5d16f4e06 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -382,7 +382,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
 	mutex_init(&vgpu->vgpu_lock);
 	mutex_init(&vgpu->dmabuf_lock);
 	INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
-	INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
+	xa_init(&vgpu->page_track);
 	idr_init(&vgpu->object_idr);
 	intel_vgpu_init_cfg_space(vgpu, param->primary);
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 21/34] drm/i915: Convert get_page to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (19 preceding siblings ...)
  2019-02-21 18:41 ` [PATCH 20/34] drm/i915: Convert page_track_tree " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 22/34] drm/i915: Convert object_idr to IDA Matthew Wilcox
                   ` (13 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

This initially seemed like an ideal use-case for the store_range
functionality, but there's no easy way to determine where we were
relative to the base of the entry.  So this is a straightforward
conversion which doesn't even touch the locking.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/i915_gem.c         | 38 ++++++++++---------------
 drivers/gpu/drm/i915/i915_gem_context.h |  2 +-
 drivers/gpu/drm/i915/i915_gem_object.h  |  4 +--
 3 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0cdccc886587..f8c36c2d32c2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2428,13 +2428,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj,
 
 static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
 {
-	struct radix_tree_iter iter;
-	void __rcu **slot;
-
-	rcu_read_lock();
-	radix_tree_for_each_slot(slot, &obj->mm.get_page.radix, &iter, 0)
-		radix_tree_delete(&obj->mm.get_page.radix, iter.index);
-	rcu_read_unlock();
+	xa_destroy(&obj->mm.get_page.xa);
 }
 
 static struct sg_table *
@@ -4716,7 +4710,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
 
 	obj->mm.madv = I915_MADV_WILLNEED;
-	INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
+	xa_init(&obj->mm.get_page.xa);
 	mutex_init(&obj->mm.get_page.lock);
 
 	i915_gem_info_add_obj(to_i915(obj->base.dev), obj->base.size);
@@ -6073,8 +6067,8 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 	GEM_BUG_ON(n >= obj->base.size >> PAGE_SHIFT);
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
-	/* As we iterate forward through the sg, we record each entry in a
-	 * radixtree for quick repeated (backwards) lookups. If we have seen
+	/* As we iterate forward through the sg, we record each entry in an
+	 * xarray for quick repeated (backwards) lookups. If we have seen
 	 * this index previously, we will have an entry for it.
 	 *
 	 * Initial lookup is O(N), but this is amortized to O(1) for
@@ -6089,7 +6083,7 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 
 	/* We prefer to reuse the last sg so that repeated lookup of this
 	 * (or the subsequent) sg are fast - comparing against the last
-	 * sg is faster than going through the radixtree.
+	 * sg is faster than going through the xarray.
 	 */
 
 	sg = iter->sg_pos;
@@ -6099,24 +6093,22 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 	while (idx + count <= n) {
 		void *entry;
 		unsigned long i;
-		int ret;
 
 		/* If we cannot allocate and insert this entry, or the
 		 * individual pages from this range, cancel updating the
 		 * sg_idx so that on this lookup we are forced to linearly
 		 * scan onwards, but on future lookups we will try the
-		 * insertion again (in which case we need to be careful of
-		 * the error return reporting that we have already inserted
-		 * this index).
+		 * insertion again.
 		 */
-		ret = radix_tree_insert(&iter->radix, idx, sg);
-		if (ret && ret != -EEXIST)
+		if (xa_store(&iter->xa, idx, sg, GFP_KERNEL | __GFP_NOWARN)
+				== XA_ERROR(-ENOMEM))
 			goto scan;
 
 		entry = xa_mk_value(idx);
 		for (i = 1; i < count; i++) {
-			ret = radix_tree_insert(&iter->radix, idx + i, entry);
-			if (ret && ret != -EEXIST)
+			if (xa_store(&iter->xa, idx + i, entry,
+					GFP_KERNEL | __GFP_NOWARN)
+						== XA_ERROR(-ENOMEM))
 				goto scan;
 		}
 
@@ -6134,7 +6126,7 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 	if (unlikely(n < idx)) /* insertion completed by another thread */
 		goto lookup;
 
-	/* In case we failed to insert the entry into the radixtree, we need
+	/* In case we failed to insert the entry into the xarray, we need
 	 * to look beyond the current sg.
 	 */
 	while (idx + count <= n) {
@@ -6149,11 +6141,11 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 lookup:
 	rcu_read_lock();
 
-	sg = radix_tree_lookup(&iter->radix, n);
+	sg = xa_load(&iter->xa, n);
 	GEM_BUG_ON(!sg);
 
 	/* If this index is in the middle of multi-page sg entry,
-	 * the radix tree will contain a value entry that points
+	 * the xarray will contain a value entry that points
 	 * to the start of that range. We will return the pointer to
 	 * the base page and the offset of this page within the
 	 * sg entry's range.
@@ -6162,7 +6154,7 @@ i915_gem_object_get_sg(struct drm_i915_gem_object *obj,
 	if (unlikely(xa_is_value(sg))) {
 		unsigned long base = xa_to_value(sg);
 
-		sg = radix_tree_lookup(&iter->radix, base);
+		sg = xa_load(&iter->xa, base);
 		GEM_BUG_ON(!sg);
 
 		*offset = n - base;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index ec22de370a22..052ad66a5bae 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -27,7 +27,7 @@
 
 #include <linux/bitops.h>
 #include <linux/list.h>
-#include <linux/radix-tree.h>
+#include <linux/xarray.h>
 
 #include "i915_gem.h"
 #include "i915_scheduler.h"
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 7f6493229f50..9febe70b4da9 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -40,7 +40,7 @@ struct drm_i915_gem_object;
 
 /*
  * struct i915_lut_handle tracks the fast lookups from handle to vma used
- * for execbuf. Although we use a radixtree for that mapping, in order to
+ * for execbuf. Although we use an xarray for that mapping, in order to
  * remove them as the object or context is closed, we need a secondary list
  * and a translation entry (i915_lut_handle).
  */
@@ -218,7 +218,7 @@ struct drm_i915_gem_object {
 			struct scatterlist *sg_pos;
 			unsigned int sg_idx; /* in pages, but 32bit eek! */
 
-			struct radix_tree_root radix;
+			struct xarray xa;
 			struct mutex lock; /* protects this cache */
 		} get_page;
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 22/34] drm/i915: Convert object_idr to IDA
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (20 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 21/34] drm/i915: Convert get_page " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 23/34] drm/i915: Convert context_idr to XArray Matthew Wilcox
                   ` (12 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

I suspect dmabuf_obj_list_head and object_ids should be combined into
a single xarray, but that's a job for later.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 7 +++----
 drivers/gpu/drm/i915/gvt/gvt.h    | 2 +-
 drivers/gpu/drm/i915/gvt/vgpu.c   | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 51ed99a37803..9fb60461affc 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -96,8 +96,7 @@ static void dmabuf_gem_object_free(struct kref *kref)
 					struct intel_vgpu_dmabuf_obj, list);
 			if (dmabuf_obj == obj) {
 				intel_gvt_hypervisor_put_vfio_device(vgpu);
-				idr_remove(&vgpu->object_idr,
-					   dmabuf_obj->dmabuf_id);
+				ida_free(&vgpu->object_ids, dmabuf_obj->dmabuf_id);
 				kfree(dmabuf_obj->info);
 				kfree(dmabuf_obj);
 				list_del(pos);
@@ -431,7 +430,7 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
 
 	dmabuf_obj->vgpu = vgpu;
 
-	ret = idr_alloc(&vgpu->object_idr, dmabuf_obj, 1, 0, GFP_NOWAIT);
+	ret = ida_alloc_min(&vgpu->object_ids, 1, GFP_NOWAIT);
 	if (ret < 0)
 		goto out_free_info;
 	gfx_plane_info->dmabuf_id = ret;
@@ -553,7 +552,7 @@ void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
 						list);
 		dmabuf_obj->vgpu = NULL;
 
-		idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
+		ida_free(&vgpu->object_ids, dmabuf_obj->dmabuf_id);
 		intel_gvt_hypervisor_put_vfio_device(vgpu);
 		list_del(pos);
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index e5bf20dcdd7d..ffb181a086be 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -231,7 +231,7 @@ struct intel_vgpu {
 
 	struct list_head dmabuf_obj_list_head;
 	struct mutex dmabuf_lock;
-	struct idr object_idr;
+	struct ida object_ids;
 
 	struct completion vblank_done;
 
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 6ec5d16f4e06..c1db9a6a1281 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -383,7 +383,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
 	mutex_init(&vgpu->dmabuf_lock);
 	INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
 	xa_init(&vgpu->page_track);
-	idr_init(&vgpu->object_idr);
+	ida_init(&vgpu->object_ids);
 	intel_vgpu_init_cfg_space(vgpu, param->primary);
 
 	ret = intel_vgpu_init_mmio(vgpu);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 23/34] drm/i915: Convert context_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (21 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 22/34] drm/i915: Convert object_idr to IDA Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 24/34] drm/i915: Convert metrics_idr " Matthew Wilcox
                   ` (11 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/i915_debugfs.c     | 32 ++++++++++++-------------
 drivers/gpu/drm/i915/i915_drv.h         |  4 ++--
 drivers/gpu/drm/i915/i915_gem_context.c | 31 ++++++++++--------------
 3 files changed, 30 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 030263870ba6..4981d1f6e7a5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -376,9 +376,9 @@ static void print_batch_pool_stats(struct seq_file *m,
 	print_file_stats(m, "[k]batch pool", stats);
 }
 
-static int per_file_ctx_stats(int idx, void *ptr, void *data)
+static void per_file_ctx_stats(struct i915_gem_context *ctx,
+		struct file_stats *stats)
 {
-	struct i915_gem_context *ctx = ptr;
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
@@ -386,12 +386,10 @@ static int per_file_ctx_stats(int idx, void *ptr, void *data)
 		struct intel_context *ce = to_intel_context(ctx, engine);
 
 		if (ce->state)
-			per_file_stats(ce->state->obj, data);
+			per_file_stats(ce->state->obj, stats);
 		if (ce->ring)
-			per_file_stats(ce->ring->vma->obj, data);
+			per_file_stats(ce->ring->vma->obj, stats);
 	}
-
-	return 0;
 }
 
 static void print_context_stats(struct seq_file *m,
@@ -405,11 +403,15 @@ static void print_context_stats(struct seq_file *m,
 
 	mutex_lock(&dev->struct_mutex);
 	if (dev_priv->kernel_context)
-		per_file_ctx_stats(0, dev_priv->kernel_context, &stats);
+		per_file_ctx_stats(dev_priv->kernel_context, &stats);
 
 	list_for_each_entry(file, &dev->filelist, lhead) {
 		struct drm_i915_file_private *fpriv = file->driver_priv;
-		idr_for_each(&fpriv->context_idr, per_file_ctx_stats, &stats);
+		struct i915_gem_context *ctx;
+		unsigned long index;
+
+		xa_for_each(&fpriv->contexts, index, ctx)
+			per_file_ctx_stats(ctx, &stats);
 	}
 	mutex_unlock(&dev->struct_mutex);
 
@@ -2078,16 +2080,14 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
 	return 0;
 }
 
-static int per_file_ctx(int id, void *ptr, void *data)
+static void per_file_ctx(struct i915_gem_context *ctx, struct seq_file *m)
 {
-	struct i915_gem_context *ctx = ptr;
-	struct seq_file *m = data;
 	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
 
 	if (!ppgtt) {
 		seq_printf(m, "  no ppgtt for context %d\n",
 			   ctx->user_handle);
-		return 0;
+		return;
 	}
 
 	if (i915_gem_context_is_default(ctx))
@@ -2095,8 +2095,6 @@ static int per_file_ctx(int id, void *ptr, void *data)
 	else
 		seq_printf(m, "  context %d:\n", ctx->user_handle);
 	ppgtt->debug_dump(ppgtt, m);
-
-	return 0;
 }
 
 static void gen8_ppgtt_info(struct seq_file *m,
@@ -2176,6 +2174,8 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
 	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
 		struct drm_i915_file_private *file_priv = file->driver_priv;
 		struct task_struct *task;
+		struct i915_gem_context *ctx;
+		unsigned long index;
 
 		task = get_pid_task(file->pid, PIDTYPE_PID);
 		if (!task) {
@@ -2184,8 +2184,8 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
 		}
 		seq_printf(m, "\nproc: %s\n", task->comm);
 		put_task_struct(task);
-		idr_for_each(&file_priv->context_idr, per_file_ctx,
-			     (void *)(unsigned long)m);
+		xa_for_each(&file_priv->contexts, index, ctx)
+			per_file_ctx(ctx, m);
 	}
 
 out_rpm:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4b5ce517cbcf..1b7663258f42 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -213,7 +213,7 @@ struct drm_i915_file_private {
  */
 #define DRM_I915_THROTTLE_JIFFIES msecs_to_jiffies(20)
 	} mm;
-	struct idr context_idr;
+	struct xarray contexts;
 
 	struct intel_rps_client {
 		atomic_t boosts;
@@ -3118,7 +3118,7 @@ void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
 static inline struct i915_gem_context *
 __i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
 {
-	return idr_find(&file_priv->context_idr, id);
+	return xa_load(&file_priv->contexts, id);
 }
 
 static inline struct i915_gem_context *
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 9db04b2e65cf..033a6fd72e40 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -350,12 +350,12 @@ __create_hw_context(struct drm_i915_private *dev_priv,
 	/* Default context will never have a file_priv */
 	ret = DEFAULT_CONTEXT_HANDLE;
 	if (file_priv) {
-		ret = idr_alloc(&file_priv->context_idr, ctx,
-				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
+		ret = xa_alloc(&file_priv->contexts, &ctx->user_handle, ctx,
+				XA_LIMIT(DEFAULT_CONTEXT_HANDLE, UINT_MAX),
+				GFP_KERNEL);
 		if (ret < 0)
 			goto err_lut;
 	}
-	ctx->user_handle = ret;
 
 	ctx->file_priv = file_priv;
 	if (file_priv) {
@@ -384,7 +384,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
 
 err_pid:
 	put_pid(ctx->pid);
-	idr_remove(&file_priv->context_idr, ctx->user_handle);
+	xa_erase(&file_priv->contexts, ctx->user_handle);
 err_lut:
 	context_close(ctx);
 	return ERR_PTR(ret);
@@ -393,7 +393,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
 static void __destroy_hw_context(struct i915_gem_context *ctx,
 				 struct drm_i915_file_private *file_priv)
 {
-	idr_remove(&file_priv->context_idr, ctx->user_handle);
+	xa_erase(&file_priv->contexts, ctx->user_handle);
 	context_close(ctx);
 }
 
@@ -597,29 +597,19 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
 	ida_destroy(&i915->contexts.hw_ida);
 }
 
-static int context_idr_cleanup(int id, void *p, void *data)
-{
-	struct i915_gem_context *ctx = p;
-
-	context_close(ctx);
-	return 0;
-}
-
 int i915_gem_context_open(struct drm_i915_private *i915,
 			  struct drm_file *file)
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
 	struct i915_gem_context *ctx;
 
-	idr_init(&file_priv->context_idr);
+	xa_init_flags(&file_priv->contexts, XA_FLAGS_ALLOC);
 
 	mutex_lock(&i915->drm.struct_mutex);
 	ctx = i915_gem_create_context(i915, file_priv);
 	mutex_unlock(&i915->drm.struct_mutex);
-	if (IS_ERR(ctx)) {
-		idr_destroy(&file_priv->context_idr);
+	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
-	}
 
 	GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
 
@@ -629,11 +619,14 @@ int i915_gem_context_open(struct drm_i915_private *i915,
 void i915_gem_context_close(struct drm_file *file)
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct i915_gem_context *ctx;
+	unsigned long index;
 
 	lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
 
-	idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
-	idr_destroy(&file_priv->context_idr);
+	xa_for_each(&file_priv->contexts, index, ctx)
+		context_close(ctx);
+	xa_destroy(&file_priv->contexts);
 }
 
 static struct i915_request *
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 24/34] drm/i915: Convert metrics_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (22 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 23/34] drm/i915: Convert context_idr to XArray Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 25/34] drm/i915: Convert vgpus_idr " Matthew Wilcox
                   ` (10 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/i915_drv.h  |  4 ++--
 drivers/gpu/drm/i915/i915_perf.c | 39 ++++++++++++--------------------
 2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1b7663258f42..5dd79453c525 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1805,7 +1805,7 @@ struct drm_i915_private {
 
 		/*
 		 * Lock associated with adding/modifying/removing OA configs
-		 * in dev_priv->perf.metrics_idr.
+		 * in dev_priv->perf.configs.
 		 */
 		struct mutex metrics_lock;
 
@@ -1813,7 +1813,7 @@ struct drm_i915_private {
 		 * List of dynamic configurations, you need to hold
 		 * dev_priv->perf.metrics_lock to access it.
 		 */
-		struct idr metrics_idr;
+		struct xarray configs;
 
 		/*
 		 * Lock associated with anything below within this structure
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 2b2eb57ca71f..8a053772a11e 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -400,7 +400,7 @@ static int get_oa_config(struct drm_i915_private *dev_priv,
 	if (ret)
 		return ret;
 
-	*out_config = idr_find(&dev_priv->perf.metrics_idr, metrics_set);
+	*out_config = xa_load(&dev_priv->perf.configs, metrics_set);
 	if (!*out_config)
 		ret = -EINVAL;
 	else
@@ -3142,7 +3142,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_perf_oa_config *args = data;
 	struct i915_oa_config *oa_config, *tmp;
-	int err, id;
+	unsigned long id;
+	int err;
 
 	if (!dev_priv->perf.initialized) {
 		DRM_DEBUG("i915 perf interface not available for this system\n");
@@ -3238,7 +3239,7 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 	/* We shouldn't have too many configs, so this iteration shouldn't be
 	 * too costly.
 	 */
-	idr_for_each_entry(&dev_priv->perf.metrics_idr, tmp, id) {
+	xa_for_each(&dev_priv->perf.configs, id, tmp) {
 		if (!strcmp(tmp->uuid, oa_config->uuid)) {
 			DRM_DEBUG("OA config already exists with this uuid\n");
 			err = -EADDRINUSE;
@@ -3253,12 +3254,10 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
 	}
 
 	/* Config id 0 is invalid, id 1 for kernel stored test config. */
-	oa_config->id = idr_alloc(&dev_priv->perf.metrics_idr,
-				  oa_config, 2,
-				  0, GFP_KERNEL);
-	if (oa_config->id < 0) {
+	err = xa_alloc(&dev_priv->perf.configs, &oa_config->id, oa_config,
+			XA_LIMIT(2, UINT_MAX), GFP_KERNEL);
+	if (err < 0) {
 		DRM_DEBUG("Failed to create sysfs entry for OA config\n");
-		err = oa_config->id;
 		goto sysfs_err;
 	}
 
@@ -3309,7 +3308,7 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
 	if (ret)
 		goto lock_err;
 
-	oa_config = idr_find(&dev_priv->perf.metrics_idr, *arg);
+	oa_config = xa_erase(&dev_priv->perf.configs, *arg);
 	if (!oa_config) {
 		DRM_DEBUG("Failed to remove unknown OA config\n");
 		ret = -ENOENT;
@@ -3321,8 +3320,6 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
 	sysfs_remove_group(dev_priv->perf.metrics_kobj,
 			   &oa_config->sysfs_metric);
 
-	idr_remove(&dev_priv->perf.metrics_idr, *arg);
-
 	DRM_DEBUG("Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
 
 	put_oa_config(dev_priv, oa_config);
@@ -3475,33 +3472,27 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
 		dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
 
 		mutex_init(&dev_priv->perf.metrics_lock);
-		idr_init(&dev_priv->perf.metrics_idr);
+		xa_init_flags(&dev_priv->perf.configs, XA_FLAGS_ALLOC);
 
 		dev_priv->perf.initialized = true;
 	}
 }
 
-static int destroy_config(int id, void *p, void *data)
-{
-	struct drm_i915_private *dev_priv = data;
-	struct i915_oa_config *oa_config = p;
-
-	put_oa_config(dev_priv, oa_config);
-
-	return 0;
-}
-
 /**
  * i915_perf_fini - Counter part to i915_perf_init()
  * @dev_priv: i915 device instance
  */
 void i915_perf_fini(struct drm_i915_private *dev_priv)
 {
+	struct i915_oa_config *oa_config;
+	unsigned long index;
+
 	if (!dev_priv->perf.initialized)
 		return;
 
-	idr_for_each(&dev_priv->perf.metrics_idr, destroy_config, dev_priv);
-	idr_destroy(&dev_priv->perf.metrics_idr);
+	xa_for_each(&dev_priv->perf.configs, index, oa_config)
+		put_oa_config(dev_priv, oa_config);
+	xa_destroy(&dev_priv->perf.configs);
 
 	unregister_sysctl_table(dev_priv->perf.sysctl_header);
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 25/34] drm/i915: Convert vgpus_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (23 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 24/34] drm/i915: Convert metrics_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 26/34] drm/qxl: Convert release_idr " Matthew Wilcox
                   ` (9 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/i915/gvt/display.c      |  5 +++--
 drivers/gpu/drm/i915/gvt/gvt.c          |  4 +---
 drivers/gpu/drm/i915/gvt/gvt.h          |  5 +++--
 drivers/gpu/drm/i915/gvt/kvmgt.c        |  2 +-
 drivers/gpu/drm/i915/gvt/sched_policy.c |  2 +-
 drivers/gpu/drm/i915/gvt/vgpu.c         | 20 ++++++++++----------
 6 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index df1e14145747..e0b25efd9fee 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -359,7 +359,8 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt)
 {
 	struct intel_gvt_irq *irq = &gvt->irq;
 	struct intel_vgpu *vgpu;
-	int pipe, id;
+	unsigned long id;
+	int pipe;
 	int found = false;
 
 	mutex_lock(&gvt->lock);
@@ -434,7 +435,7 @@ static void emulate_vblank(struct intel_vgpu *vgpu)
 void intel_gvt_emulate_vblank(struct intel_gvt *gvt)
 {
 	struct intel_vgpu *vgpu;
-	int id;
+	unsigned long id;
 
 	mutex_lock(&gvt->lock);
 	for_each_active_vgpu(gvt, vgpu, id)
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 733a2a0d0c30..ef6c62ebc2be 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -329,7 +329,6 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
 	intel_gvt_clean_irq(gvt);
 	intel_gvt_free_firmware(gvt);
 	intel_gvt_clean_mmio_info(gvt);
-	idr_destroy(&gvt->vgpu_idr);
 
 	kfree(dev_priv->gvt);
 	dev_priv->gvt = NULL;
@@ -368,7 +367,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 
 	gvt_dbg_core("init gvt device\n");
 
-	idr_init(&gvt->vgpu_idr);
+	xa_init_flags(&gvt->vgpus, XA_FLAGS_ALLOC1);
 	spin_lock_init(&gvt->scheduler.mmio_context_lock);
 	mutex_init(&gvt->lock);
 	mutex_init(&gvt->sched_lock);
@@ -462,7 +461,6 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
 out_clean_mmio_info:
 	intel_gvt_clean_mmio_info(gvt);
 out_clean_idr:
-	idr_destroy(&gvt->vgpu_idr);
 	kfree(gvt);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index ffb181a086be..843d199dc82a 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -314,7 +314,7 @@ struct intel_gvt {
 	struct mutex sched_lock;
 
 	struct drm_i915_private *dev_priv;
-	struct idr vgpu_idr;	/* vGPU IDR pool */
+	struct xarray vgpus;	/* vGPU IDR pool */
 
 	struct intel_gvt_device_info device_info;
 	struct intel_gvt_gm gm;
@@ -458,8 +458,9 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu,
 #define vgpu_sreg(vgpu, offset) \
 	(*(u32 *)(vgpu->mmio.sreg + (offset)))
 
+/* Can this use an XArray mark instead? */
 #define for_each_active_vgpu(gvt, vgpu, id) \
-	idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) \
+	xa_for_each((&(gvt)->vgpus), (id), (vgpu)) \
 		for_each_if(vgpu->active)
 
 static inline void intel_vgpu_write_pci_bar(struct intel_vgpu *vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index dd3dfd00f4e6..7f761879c14a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1587,7 +1587,7 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm)
 {
 	struct intel_vgpu *itr;
 	struct kvmgt_guest_info *info;
-	int id;
+	unsigned long id;
 	bool ret = false;
 
 	mutex_lock(&vgpu->gvt->lock);
diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c
index c32e7d5e8629..f0223e0a1a23 100644
--- a/drivers/gpu/drm/i915/gvt/sched_policy.c
+++ b/drivers/gpu/drm/i915/gvt/sched_policy.c
@@ -334,7 +334,7 @@ static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
 	vgpu->sched_data = NULL;
 
 	/* this vgpu id has been removed */
-	if (idr_is_empty(&gvt->vgpu_idr))
+	if (xa_empty(&gvt->vgpus))
 		hrtimer_cancel(&sched_data->timer);
 }
 
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index c1db9a6a1281..5dfdfa20331f 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -290,8 +290,8 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
 	mutex_unlock(&vgpu->vgpu_lock);
 
 	mutex_lock(&gvt->lock);
-	idr_remove(&gvt->vgpu_idr, vgpu->id);
-	if (idr_is_empty(&gvt->vgpu_idr))
+	xa_erase(&gvt->vgpus, vgpu->id);
+	if (xa_empty(&gvt->vgpus))
 		intel_gvt_clean_irq(gvt);
 	intel_gvt_update_vgpu_types(gvt);
 	mutex_unlock(&gvt->lock);
@@ -299,7 +299,8 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
 	vfree(vgpu);
 }
 
-#define IDLE_VGPU_IDR 0
+/* Don't change this without changing the XA_FLAGS_ALLOC1 initialisation */
+#define IDLE_VGPU_ID 0
 
 /**
  * intel_gvt_create_idle_vgpu - create an idle virtual GPU
@@ -320,7 +321,7 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt)
 	if (!vgpu)
 		return ERR_PTR(-ENOMEM);
 
-	vgpu->id = IDLE_VGPU_IDR;
+	vgpu->id = IDLE_VGPU_ID;
 	vgpu->gvt = gvt;
 	mutex_init(&vgpu->vgpu_lock);
 
@@ -370,12 +371,11 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
 	if (!vgpu)
 		return ERR_PTR(-ENOMEM);
 
-	ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU,
-		GFP_KERNEL);
+	ret = xa_alloc(&gvt->vgpus, &vgpu->id, vgpu,
+			XA_LIMIT(0, GVT_MAX_VGPU), GFP_KERNEL);
 	if (ret < 0)
 		goto out_free_vgpu;
 
-	vgpu->id = ret;
 	vgpu->handle = param->handle;
 	vgpu->gvt = gvt;
 	vgpu->sched_ctl.weight = param->weight;
@@ -388,7 +388,7 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
 
 	ret = intel_vgpu_init_mmio(vgpu);
 	if (ret)
-		goto out_clean_idr;
+		goto out_erase;
 
 	ret = intel_vgpu_alloc_resource(vgpu, param);
 	if (ret)
@@ -446,8 +446,8 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
 	intel_vgpu_free_resource(vgpu);
 out_clean_vgpu_mmio:
 	intel_vgpu_clean_mmio(vgpu);
-out_clean_idr:
-	idr_remove(&gvt->vgpu_idr, vgpu->id);
+out_erase:
+	xa_erase(&gvt->vgpus, vgpu->id);
 out_free_vgpu:
 	vfree(vgpu);
 	return ERR_PTR(ret);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 26/34] drm/qxl: Convert release_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (24 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 25/34] drm/i915: Convert vgpus_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 27/34] drm/qxl: Convert surf_id_idr " Matthew Wilcox
                   ` (8 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/qxl/qxl_drv.h     |  3 +-
 drivers/gpu/drm/qxl/qxl_kms.c     |  3 +-
 drivers/gpu/drm/qxl/qxl_release.c | 54 +++++++++++++------------------
 3 files changed, 25 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 13a0254b59a1..3abd432a4b85 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -238,9 +238,8 @@ struct qxl_device {
 	uint64_t	va_slot_mask;
 
 	spinlock_t	release_lock;
-	struct idr	release_idr;
+	struct xarray	releases;
 	uint32_t	release_seqno;
-	spinlock_t release_idr_lock;
 	struct mutex	async_io_mutex;
 	unsigned int last_sent_io_cmd;
 
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 15238a413f9d..b2cc71c95142 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -247,8 +247,7 @@ int qxl_device_init(struct qxl_device *qdev,
 		goto release_ring_free;
 	}
 
-	idr_init(&qdev->release_idr);
-	spin_lock_init(&qdev->release_idr_lock);
+	xa_init_flags(&qdev->releases, XA_FLAGS_ALLOC1);
 	spin_lock_init(&qdev->release_lock);
 
 	idr_init(&qdev->surf_id_idr);
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c
index 30f85f0130cb..a1a42662ebf4 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -121,7 +121,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
 		  struct qxl_release **ret)
 {
 	struct qxl_release *release;
-	int handle;
+	int err;
 	size_t size = sizeof(*release);
 
 	release = kmalloc(size, GFP_KERNEL);
@@ -135,21 +135,19 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
 	release->surface_release_id = 0;
 	INIT_LIST_HEAD(&release->bos);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&qdev->release_idr_lock);
-	handle = idr_alloc(&qdev->release_idr, release, 1, 0, GFP_NOWAIT);
+	xa_lock(&qdev->releases);
+	err = __xa_alloc(&qdev->releases, &release->id, release, xa_limit_31b,
+			GFP_KERNEL);
 	release->base.seqno = ++qdev->release_seqno;
-	spin_unlock(&qdev->release_idr_lock);
-	idr_preload_end();
-	if (handle < 0) {
+	xa_unlock(&qdev->releases);
+	if (err < 0) {
 		kfree(release);
 		*ret = NULL;
-		return handle;
+		return err;
 	}
 	*ret = release;
-	DRM_DEBUG_DRIVER("allocated release %d\n", handle);
-	release->id = handle;
-	return handle;
+	DRM_DEBUG_DRIVER("allocated release %d\n", release->id);
+	return release->id;
 }
 
 static void
@@ -178,9 +176,7 @@ qxl_release_free(struct qxl_device *qdev,
 	if (release->surface_release_id)
 		qxl_surface_id_dealloc(qdev, release->surface_release_id);
 
-	spin_lock(&qdev->release_idr_lock);
-	idr_remove(&qdev->release_idr, release->id);
-	spin_unlock(&qdev->release_idr_lock);
+	xa_erase(&qdev->releases, release->id);
 
 	if (release->base.ops) {
 		WARN_ON(list_empty(&release->bos));
@@ -288,14 +284,14 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 				       struct qxl_release **release)
 {
 	if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
-		int idr_ret;
+		int id;
 		struct qxl_bo *bo;
 		union qxl_release_info *info;
 
 		/* stash the release after the create command */
-		idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
-		if (idr_ret < 0)
-			return idr_ret;
+		id = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
+		if (id < 0)
+			return id;
 		bo = create_rel->release_bo;
 
 		(*release)->release_bo = bo;
@@ -304,7 +300,7 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 		qxl_release_list_add(*release, bo);
 
 		info = qxl_release_map(qdev, *release);
-		info->id = idr_ret;
+		info->id = id;
 		qxl_release_unmap(qdev, *release, info);
 		return 0;
 	}
@@ -318,7 +314,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 				       struct qxl_bo **rbo)
 {
 	struct qxl_bo *bo;
-	int idr_ret;
+	int id;
 	int ret = 0;
 	union qxl_release_info *info;
 	int cur_idx;
@@ -334,11 +330,11 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 		return -EINVAL;
 	}
 
-	idr_ret = qxl_release_alloc(qdev, type, release);
-	if (idr_ret < 0) {
+	id = qxl_release_alloc(qdev, type, release);
+	if (id < 0) {
 		if (rbo)
 			*rbo = NULL;
-		return idr_ret;
+		return id;
 	}
 
 	mutex_lock(&qdev->release_mutex);
@@ -375,7 +371,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 	}
 
 	info = qxl_release_map(qdev, *release);
-	info->id = idr_ret;
+	info->id = id;
 	qxl_release_unmap(qdev, *release, info);
 
 	return ret;
@@ -386,13 +382,9 @@ struct qxl_release *qxl_release_from_id_locked(struct qxl_device *qdev,
 {
 	struct qxl_release *release;
 
-	spin_lock(&qdev->release_idr_lock);
-	release = idr_find(&qdev->release_idr, id);
-	spin_unlock(&qdev->release_idr_lock);
-	if (!release) {
-		DRM_ERROR("failed to find id in release_idr\n");
-		return NULL;
-	}
+	release = xa_load(&qdev->releases, id);
+	if (!release)
+		DRM_ERROR("failed to find id in releases\n");
 
 	return release;
 }
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 27/34] drm/qxl: Convert surf_id_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (25 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 26/34] drm/qxl: Convert release_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 28/34] drm/tegra: Convert contexts IDR " Matthew Wilcox
                   ` (7 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/qxl/qxl_cmd.c | 60 ++++++++++++-----------------------
 drivers/gpu/drm/qxl/qxl_drv.h |  3 +-
 drivers/gpu/drm/qxl/qxl_kms.c |  5 +--
 3 files changed, 23 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index dffc5093ff16..afe8079453af 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -420,41 +420,27 @@ void qxl_io_monitors_config(struct qxl_device *qdev)
 int qxl_surface_id_alloc(struct qxl_device *qdev,
 		      struct qxl_bo *surf)
 {
-	uint32_t handle;
-	int idr_ret;
-	int count = 0;
+	int ret;
 again:
-	idr_preload(GFP_ATOMIC);
-	spin_lock(&qdev->surf_id_idr_lock);
-	idr_ret = idr_alloc(&qdev->surf_id_idr, NULL, 1, 0, GFP_NOWAIT);
-	spin_unlock(&qdev->surf_id_idr_lock);
-	idr_preload_end();
-	if (idr_ret < 0)
-		return idr_ret;
-	handle = idr_ret;
-
-	if (handle >= qdev->rom->n_surfaces) {
-		count++;
-		spin_lock(&qdev->surf_id_idr_lock);
-		idr_remove(&qdev->surf_id_idr, handle);
-		spin_unlock(&qdev->surf_id_idr_lock);
+	ret = xa_alloc(&qdev->surfaces, &surf->surface_id, NULL,
+			XA_LIMIT(0, qdev->rom->n_surfaces - 1), GFP_ATOMIC);
+	if (ret == -EBUSY) {
 		qxl_reap_surface_id(qdev, 2);
 		goto again;
 	}
-	surf->surface_id = handle;
+	if (ret < 0)
+		return ret;
 
-	spin_lock(&qdev->surf_id_idr_lock);
-	qdev->last_alloced_surf_id = handle;
-	spin_unlock(&qdev->surf_id_idr_lock);
+	xa_lock(&qdev->surfaces);
+	qdev->last_alloced_surf_id = surf->surface_id;
+	xa_unlock(&qdev->surfaces);
 	return 0;
 }
 
 void qxl_surface_id_dealloc(struct qxl_device *qdev,
 			    uint32_t surface_id)
 {
-	spin_lock(&qdev->surf_id_idr_lock);
-	idr_remove(&qdev->surf_id_idr, surface_id);
-	spin_unlock(&qdev->surf_id_idr_lock);
+	xa_erase(&qdev->surfaces, surface_id);
 }
 
 int qxl_hw_surface_alloc(struct qxl_device *qdev,
@@ -507,9 +493,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
 	qxl_release_fence_buffer_objects(release);
 
 	surf->hw_surf_alloc = true;
-	spin_lock(&qdev->surf_id_idr_lock);
-	idr_replace(&qdev->surf_id_idr, surf, surf->surface_id);
-	spin_unlock(&qdev->surf_id_idr_lock);
+	xa_store(&qdev->surfaces, surf->surface_id, surf, GFP_KERNEL);
 	return 0;
 }
 
@@ -531,10 +515,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev,
 		return ret;
 
 	surf->surf_create = NULL;
-	/* remove the surface from the idr, but not the surface id yet */
-	spin_lock(&qdev->surf_id_idr_lock);
-	idr_replace(&qdev->surf_id_idr, NULL, surf->surface_id);
-	spin_unlock(&qdev->surf_id_idr_lock);
+	/* remove the surface from the array, but don't free the surface id */
+	xa_store(&qdev->surfaces, surf->surface_id, NULL, 0);
 	surf->hw_surf_alloc = false;
 
 	id = surf->surface_id;
@@ -623,20 +605,20 @@ static int qxl_reap_surface_id(struct qxl_device *qdev, int max_to_reap)
 	mutex_lock(&qdev->surf_evict_mutex);
 again:
 
-	spin_lock(&qdev->surf_id_idr_lock);
+	xa_lock(&qdev->surfaces);
 	start = qdev->last_alloced_surf_id + 1;
-	spin_unlock(&qdev->surf_id_idr_lock);
+	xa_unlock(&qdev->surfaces);
 
 	for (i = start; i < start + qdev->rom->n_surfaces; i++) {
 		void *objptr;
 		int surfid = i % qdev->rom->n_surfaces;
 
-		/* this avoids the case where the objects is in the
-		   idr but has been evicted half way - its makes
-		   the idr lookup atomic with the eviction */
-		spin_lock(&qdev->surf_id_idr_lock);
-		objptr = idr_find(&qdev->surf_id_idr, surfid);
-		spin_unlock(&qdev->surf_id_idr_lock);
+		/* this avoids the case where the object is in the
+		   array but has been evicted half way - it makes
+		   the array lookup atomic with the eviction */
+		xa_lock(&qdev->surfaces);
+		objptr = xa_load(&qdev->surfaces, surfid);
+		xa_unlock(&qdev->surfaces);
 
 		if (!objptr)
 			continue;
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 3abd432a4b85..8d0254a133dc 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -260,8 +260,7 @@ struct qxl_device {
 
 	struct mutex		update_area_mutex;
 
-	struct idr	surf_id_idr;
-	spinlock_t surf_id_idr_lock;
+	struct xarray	surfaces;
 	int last_alloced_surf_id;
 
 	struct mutex surf_evict_mutex;
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index b2cc71c95142..dafdb61f7a32 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -249,10 +249,7 @@ int qxl_device_init(struct qxl_device *qdev,
 
 	xa_init_flags(&qdev->releases, XA_FLAGS_ALLOC1);
 	spin_lock_init(&qdev->release_lock);
-
-	idr_init(&qdev->surf_id_idr);
-	spin_lock_init(&qdev->surf_id_idr_lock);
-
+	xa_init_flags(&qdev->surfaces, XA_FLAGS_ALLOC1);
 	mutex_init(&qdev->async_io_mutex);
 
 	/* reset the device into a known state - no memslots, no primary
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 28/34] drm/tegra: Convert contexts IDR to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (26 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 27/34] drm/qxl: Convert surf_id_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 29/34] drm/vc4: Convert perfmon " Matthew Wilcox
                   ` (6 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/tegra/drm.c | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 4b70ce664c41..5daa414cc2cf 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -9,7 +9,7 @@
 
 #include <linux/bitops.h>
 #include <linux/host1x.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/iommu.h>
 
 #include <drm/drm_atomic.h>
@@ -33,7 +33,7 @@
 #define CDMA_GATHER_FETCHES_MAX_NB 16383
 
 struct tegra_drm_file {
-	struct idr contexts;
+	struct xarray contexts;
 	struct mutex lock;
 };
 
@@ -246,7 +246,7 @@ static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 	if (!fpriv)
 		return -ENOMEM;
 
-	idr_init(&fpriv->contexts);
+	xa_init_flags(&fpriv->contexts, XA_FLAGS_ALLOC1);
 	mutex_init(&fpriv->lock);
 	filp->driver_priv = fpriv;
 
@@ -582,14 +582,14 @@ static int tegra_client_open(struct tegra_drm_file *fpriv,
 	if (err < 0)
 		return err;
 
-	err = idr_alloc(&fpriv->contexts, context, 1, 0, GFP_KERNEL);
+	err = xa_alloc(&fpriv->contexts, &context->id, context, xa_limit_31b,
+			GFP_KERNEL);
 	if (err < 0) {
 		client->ops->close_channel(context);
 		return err;
 	}
 
 	context->client = client;
-	context->id = err;
 
 	return 0;
 }
@@ -637,13 +637,12 @@ static int tegra_close_channel(struct drm_device *drm, void *data,
 
 	mutex_lock(&fpriv->lock);
 
-	context = idr_find(&fpriv->contexts, args->context);
+	context = xa_erase(&fpriv->contexts, args->context);
 	if (!context) {
 		err = -EINVAL;
 		goto unlock;
 	}
 
-	idr_remove(&fpriv->contexts, context->id);
 	tegra_drm_context_free(context);
 
 unlock:
@@ -662,7 +661,7 @@ static int tegra_get_syncpt(struct drm_device *drm, void *data,
 
 	mutex_lock(&fpriv->lock);
 
-	context = idr_find(&fpriv->contexts, args->context);
+	context = xa_load(&fpriv->contexts, args->context);
 	if (!context) {
 		err = -ENODEV;
 		goto unlock;
@@ -691,7 +690,7 @@ static int tegra_submit(struct drm_device *drm, void *data,
 
 	mutex_lock(&fpriv->lock);
 
-	context = idr_find(&fpriv->contexts, args->context);
+	context = xa_load(&fpriv->contexts, args->context);
 	if (!context) {
 		err = -ENODEV;
 		goto unlock;
@@ -716,7 +715,7 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data,
 
 	mutex_lock(&fpriv->lock);
 
-	context = idr_find(&fpriv->contexts, args->context);
+	context = xa_load(&fpriv->contexts, args->context);
 	if (!context) {
 		err = -ENODEV;
 		goto unlock;
@@ -928,24 +927,18 @@ static const struct file_operations tegra_drm_fops = {
 	.llseek = noop_llseek,
 };
 
-static int tegra_drm_context_cleanup(int id, void *p, void *data)
-{
-	struct tegra_drm_context *context = p;
-
-	tegra_drm_context_free(context);
-
-	return 0;
-}
-
 static void tegra_drm_postclose(struct drm_device *drm, struct drm_file *file)
 {
 	struct tegra_drm_file *fpriv = file->driver_priv;
+	struct tegra_drm_context *context;
+	unsigned long index;
 
 	mutex_lock(&fpriv->lock);
-	idr_for_each(&fpriv->contexts, tegra_drm_context_cleanup, NULL);
+	xa_for_each(&fpriv->contexts, index, context)
+		tegra_drm_context_free(context);
 	mutex_unlock(&fpriv->lock);
 
-	idr_destroy(&fpriv->contexts);
+	xa_destroy(&fpriv->contexts);
 	mutex_destroy(&fpriv->lock);
 	kfree(fpriv);
 }
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 29/34] drm/vc4: Convert perfmon IDR to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (27 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 28/34] drm/tegra: Convert contexts IDR " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 30/34] drm/sis: Convert object_idr " Matthew Wilcox
                   ` (5 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/vc4/vc4_drv.h     |  2 +-
 drivers/gpu/drm/vc4/vc4_perfmon.c | 33 +++++++++++--------------------
 2 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 4f87b03f837d..845b84d27f82 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -561,7 +561,7 @@ struct vc4_exec_info {
  */
 struct vc4_file {
 	struct {
-		struct idr idr;
+		struct xarray array;
 		struct mutex lock;
 	} perfmon;
 };
diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c
index 437e7a27f21d..d5485821f996 100644
--- a/drivers/gpu/drm/vc4/vc4_perfmon.c
+++ b/drivers/gpu/drm/vc4/vc4_perfmon.c
@@ -12,9 +12,6 @@
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
-#define VC4_PERFMONID_MIN	1
-#define VC4_PERFMONID_MAX	U32_MAX
-
 void vc4_perfmon_get(struct vc4_perfmon *perfmon)
 {
 	if (perfmon)
@@ -67,7 +64,7 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id)
 	struct vc4_perfmon *perfmon;
 
 	mutex_lock(&vc4file->perfmon.lock);
-	perfmon = idr_find(&vc4file->perfmon.idr, id);
+	perfmon = xa_load(&vc4file->perfmon.array, id);
 	vc4_perfmon_get(perfmon);
 	mutex_unlock(&vc4file->perfmon.lock);
 
@@ -77,23 +74,18 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id)
 void vc4_perfmon_open_file(struct vc4_file *vc4file)
 {
 	mutex_init(&vc4file->perfmon.lock);
-	idr_init(&vc4file->perfmon.idr);
-}
-
-static int vc4_perfmon_idr_del(int id, void *elem, void *data)
-{
-	struct vc4_perfmon *perfmon = elem;
-
-	vc4_perfmon_put(perfmon);
-
-	return 0;
+	xa_init_flags(&vc4file->perfmon.array, XA_FLAGS_ALLOC1);
 }
 
 void vc4_perfmon_close_file(struct vc4_file *vc4file)
 {
+	struct vc4_perfmon *perfmon;
+	unsigned long index;
+
 	mutex_lock(&vc4file->perfmon.lock);
-	idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL);
-	idr_destroy(&vc4file->perfmon.idr);
+	xa_for_each(&vc4file->perfmon.array, index, perfmon)
+		vc4_perfmon_put(perfmon);
+	xa_destroy(&vc4file->perfmon.array);
 	mutex_unlock(&vc4file->perfmon.lock);
 }
 
@@ -130,8 +122,8 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data,
 	refcount_set(&perfmon->refcnt, 1);
 
 	mutex_lock(&vc4file->perfmon.lock);
-	ret = idr_alloc(&vc4file->perfmon.idr, perfmon, VC4_PERFMONID_MIN,
-			VC4_PERFMONID_MAX, GFP_KERNEL);
+	ret = xa_alloc(&vc4file->perfmon.array, &req->id, perfmon,
+			xa_limit_32b, GFP_KERNEL);
 	mutex_unlock(&vc4file->perfmon.lock);
 
 	if (ret < 0) {
@@ -139,7 +131,6 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data,
 		return ret;
 	}
 
-	req->id = ret;
 	return 0;
 }
 
@@ -151,7 +142,7 @@ int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data,
 	struct vc4_perfmon *perfmon;
 
 	mutex_lock(&vc4file->perfmon.lock);
-	perfmon = idr_remove(&vc4file->perfmon.idr, req->id);
+	perfmon = xa_erase(&vc4file->perfmon.array, req->id);
 	mutex_unlock(&vc4file->perfmon.lock);
 
 	if (!perfmon)
@@ -170,7 +161,7 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
 	int ret;
 
 	mutex_lock(&vc4file->perfmon.lock);
-	perfmon = idr_find(&vc4file->perfmon.idr, req->id);
+	perfmon = xa_load(&vc4file->perfmon.array, req->id);
 	vc4_perfmon_get(perfmon);
 	mutex_unlock(&vc4file->perfmon.lock);
 
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 30/34] drm/sis: Convert object_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (28 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 29/34] drm/vc4: Convert perfmon " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 31/34] drm/vgem: Convert fence_idr " Matthew Wilcox
                   ` (4 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/sis/sis_drv.c |  4 +---
 drivers/gpu/drm/sis/sis_drv.h |  2 +-
 drivers/gpu/drm/sis/sis_mm.c  | 17 ++++++++---------
 3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index e04a92658cd7..bb5caad5d365 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -47,7 +47,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
 	if (dev_priv == NULL)
 		return -ENOMEM;
 
-	idr_init(&dev_priv->object_idr);
+	xa_init_flags(&dev_priv->objects, XA_FLAGS_ALLOC1);
 	dev->dev_private = (void *)dev_priv;
 	dev_priv->chipset = chipset;
 
@@ -58,8 +58,6 @@ static void sis_driver_unload(struct drm_device *dev)
 {
 	drm_sis_private_t *dev_priv = dev->dev_private;
 
-	idr_destroy(&dev_priv->object_idr);
-
 	kfree(dev_priv);
 }
 
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h
index 328f8a750976..18277fee8550 100644
--- a/drivers/gpu/drm/sis/sis_drv.h
+++ b/drivers/gpu/drm/sis/sis_drv.h
@@ -64,7 +64,7 @@ typedef struct drm_sis_private {
 	struct drm_mm vram_mm;
 	struct drm_mm agp_mm;
 	/** Mapping of userspace keys to mm objects */
-	struct idr object_idr;
+	struct xarray objects;
 } drm_sis_private_t;
 
 struct sis_file_private {
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 1622db24cd39..2fbc31697563 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -84,9 +84,10 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
 {
 	drm_sis_private_t *dev_priv = dev->dev_private;
 	drm_sis_mem_t *mem = data;
-	int retval = 0, user_key;
+	int retval = 0;
 	struct sis_memblock *item;
 	struct sis_file_private *file_priv = file->driver_priv;
+	unsigned int id;
 	unsigned long offset;
 
 	mutex_lock(&dev->struct_mutex);
@@ -128,23 +129,22 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
 	if (retval)
 		goto fail_alloc;
 
-	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
+	retval = xa_alloc(&dev_priv->objects, &id, item, xa_limit_31b,
+			GFP_KERNEL);
 	if (retval < 0)
-		goto fail_idr;
-	user_key = retval;
-
+		goto fail_xa;
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
 
+	mem->free = id;
 	mem->offset = ((pool == 0) ?
 		      dev_priv->vram_offset : dev_priv->agp_offset) +
 	    (offset << SIS_MM_ALIGN_SHIFT);
-	mem->free = user_key;
 	mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
 
 	return 0;
 
-fail_idr:
+fail_xa:
 	drm_mm_remove_node(&item->mm_node);
 fail_alloc:
 	kfree(item);
@@ -167,13 +167,12 @@ static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *fil
 	struct sis_memblock *obj;
 
 	mutex_lock(&dev->struct_mutex);
-	obj = idr_find(&dev_priv->object_idr, mem->free);
+	obj = xa_erase(&dev_priv->objects, mem->free);
 	if (obj == NULL) {
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
 
-	idr_remove(&dev_priv->object_idr, mem->free);
 	list_del(&obj->owner_list);
 	if (drm_mm_node_allocated(&obj->mm_node))
 		drm_mm_remove_node(&obj->mm_node);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 31/34] drm/vgem: Convert fence_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (29 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 30/34] drm/sis: Convert object_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 32/34] drm/via: Convert object_idr " Matthew Wilcox
                   ` (3 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/vgem/vgem_drv.h   |  3 +--
 drivers/gpu/drm/vgem/vgem_fence.c | 43 +++++++++++++------------------
 2 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h
index 5c8f6d619ff3..56c8872b0967 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.h
+++ b/drivers/gpu/drm/vgem/vgem_drv.h
@@ -36,8 +36,7 @@
 #include <uapi/drm/vgem_drm.h>
 
 struct vgem_file {
-	struct idr fence_idr;
-	struct mutex fence_mutex;
+	struct xarray fences;
 };
 
 #define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base)
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
index c1c420afe2dd..aa410ebcddf2 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -184,15 +184,10 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,
 		reservation_object_add_shared_fence(resv, fence);
 	reservation_object_unlock(resv);
 
-	/* Record the fence in our idr for later signaling */
+	/* Record the fence in our array for later signaling */
 	if (ret == 0) {
-		mutex_lock(&vfile->fence_mutex);
-		ret = idr_alloc(&vfile->fence_idr, fence, 1, 0, GFP_KERNEL);
-		mutex_unlock(&vfile->fence_mutex);
-		if (ret > 0) {
-			arg->out_fence = ret;
-			ret = 0;
-		}
+		ret = xa_alloc(&vfile->fences, &arg->out_fence, fence,
+				xa_limit_31b, GFP_KERNEL);
 	}
 err_fence:
 	if (ret) {
@@ -232,13 +227,13 @@ int vgem_fence_signal_ioctl(struct drm_device *dev,
 	if (arg->flags)
 		return -EINVAL;
 
-	mutex_lock(&vfile->fence_mutex);
-	fence = idr_replace(&vfile->fence_idr, NULL, arg->fence);
-	mutex_unlock(&vfile->fence_mutex);
-	if (!fence)
+	fence = xa_store(&vfile->fences, arg->fence, NULL, 0);
+	if (!fence) {
+		xa_erase(&vfile->fences, arg->fence);
+		return -ENOENT;
+	}
+	if (xa_is_err(fence))
 		return -ENOENT;
-	if (IS_ERR(fence))
-		return PTR_ERR(fence);
 
 	if (dma_fence_is_signaled(fence))
 		ret = -ETIMEDOUT;
@@ -250,21 +245,19 @@ int vgem_fence_signal_ioctl(struct drm_device *dev,
 
 int vgem_fence_open(struct vgem_file *vfile)
 {
-	mutex_init(&vfile->fence_mutex);
-	idr_init(&vfile->fence_idr);
+	xa_init_flags(&vfile->fences, XA_FLAGS_ALLOC1);
 
 	return 0;
 }
 
-static int __vgem_fence_idr_fini(int id, void *p, void *data)
-{
-	dma_fence_signal(p);
-	dma_fence_put(p);
-	return 0;
-}
-
 void vgem_fence_close(struct vgem_file *vfile)
 {
-	idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile);
-	idr_destroy(&vfile->fence_idr);
+	struct dma_fence *fence;
+	unsigned long index;
+
+	xa_for_each(&vfile->fences, index, fence) {
+		dma_fence_signal(fence);
+		dma_fence_put(fence);
+	}
+	xa_destroy(&vfile->fences);
 }
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 32/34] drm/via: Convert object_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (30 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 31/34] drm/vgem: Convert fence_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 33/34] drm/vmwgfx: Convert base IDR " Matthew Wilcox
                   ` (2 subsequent siblings)
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/via/via_drv.h |  2 +-
 drivers/gpu/drm/via/via_map.c |  4 +---
 drivers/gpu/drm/via/via_mm.c  | 11 +++++------
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 6d1ae834484c..df0f451908e2 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -95,7 +95,7 @@ typedef struct drm_via_private {
 	int agp_initialized;
 	struct drm_mm agp_mm;
 	/** Mapping of userspace keys to mm objects */
-	struct idr object_idr;
+	struct xarray objects;
 	unsigned long vram_offset;
 	unsigned long agp_offset;
 	drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index 2ad865870372..c47630105f5b 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -100,7 +100,7 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
 	if (dev_priv == NULL)
 		return -ENOMEM;
 
-	idr_init(&dev_priv->object_idr);
+	xa_init_flags(&dev_priv->objects, XA_FLAGS_ALLOC1);
 	dev->dev_private = (void *)dev_priv;
 
 	dev_priv->chipset = chipset;
@@ -120,7 +120,5 @@ void via_driver_unload(struct drm_device *dev)
 {
 	drm_via_private_t *dev_priv = dev->dev_private;
 
-	idr_destroy(&dev_priv->object_idr);
-
 	kfree(dev_priv);
 }
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 4217d66a5cc6..aaa90a096e52 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -148,10 +148,10 @@ int via_mem_alloc(struct drm_device *dev, void *data,
 	if (retval)
 		goto fail_alloc;
 
-	retval = idr_alloc(&dev_priv->object_idr, item, 1, 0, GFP_KERNEL);
+	retval = xa_alloc(&dev_priv->objects, &user_key, item,
+			xa_limit_31b, GFP_KERNEL);
 	if (retval < 0)
-		goto fail_idr;
-	user_key = retval;
+		goto fail_xa;
 
 	list_add(&item->owner_list, &file_priv->obj_list);
 	mutex_unlock(&dev->struct_mutex);
@@ -163,7 +163,7 @@ int via_mem_alloc(struct drm_device *dev, void *data,
 
 	return 0;
 
-fail_idr:
+fail_xa:
 	drm_mm_remove_node(&item->mm_node);
 fail_alloc:
 	kfree(item);
@@ -184,13 +184,12 @@ int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
 	struct via_memblock *obj;
 
 	mutex_lock(&dev->struct_mutex);
-	obj = idr_find(&dev_priv->object_idr, mem->index);
+	obj = xa_erase(&dev_priv->objects, mem->index);
 	if (obj == NULL) {
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
 
-	idr_remove(&dev_priv->object_idr, mem->index);
 	list_del(&obj->owner_list);
 	drm_mm_remove_node(&obj->mm_node);
 	kfree(obj);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 33/34] drm/vmwgfx: Convert base IDR to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (31 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 32/34] drm/via: Convert object_idr " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-21 18:42 ` [PATCH 34/34] drm/vmwgfx: Convert res_idr " Matthew Wilcox
  2019-02-22  9:54 ` [PATCH 00/34] Convert DRM " Daniel Vetter
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/vmwgfx/ttm_object.c | 29 ++++++++---------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c
index 36990b80e790..8f394b94060b 100644
--- a/drivers/gpu/drm/vmwgfx/ttm_object.c
+++ b/drivers/gpu/drm/vmwgfx/ttm_object.c
@@ -77,8 +77,6 @@ struct ttm_object_file {
 /**
  * struct ttm_object_device
  *
- * @object_lock: lock that protects the object_hash hash table.
- *
  * @object_hash: hash table for fast lookup of object global names.
  *
  * @object_count: Per device object count.
@@ -87,14 +85,13 @@ struct ttm_object_file {
  */
 
 struct ttm_object_device {
-	spinlock_t object_lock;
 	struct drm_open_hash object_hash;
 	atomic_t object_count;
 	struct ttm_mem_global *mem_glob;
 	struct dma_buf_ops ops;
 	void (*dmabuf_release)(struct dma_buf *dma_buf);
 	size_t dma_buf_size;
-	struct idr idr;
+	struct xarray bases;
 };
 
 /**
@@ -172,15 +169,11 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
 	base->ref_obj_release = ref_obj_release;
 	base->object_type = object_type;
 	kref_init(&base->refcount);
-	idr_preload(GFP_KERNEL);
-	spin_lock(&tdev->object_lock);
-	ret = idr_alloc(&tdev->idr, base, 0, 0, GFP_NOWAIT);
-	spin_unlock(&tdev->object_lock);
-	idr_preload_end();
+	ret = xa_alloc(&tdev->bases, &base->handle, base, xa_limit_31b,
+			GFP_KERNEL);
 	if (ret < 0)
 		return ret;
 
-	base->handle = ret;
 	ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
 	if (unlikely(ret != 0))
 		goto out_err1;
@@ -189,9 +182,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
 
 	return 0;
 out_err1:
-	spin_lock(&tdev->object_lock);
-	idr_remove(&tdev->idr, base->handle);
-	spin_unlock(&tdev->object_lock);
+	xa_erase(&tdev->bases, base->handle);
 	return ret;
 }
 
@@ -201,9 +192,7 @@ static void ttm_release_base(struct kref *kref)
 	    container_of(kref, struct ttm_base_object, refcount);
 	struct ttm_object_device *tdev = base->tfile->tdev;
 
-	spin_lock(&tdev->object_lock);
-	idr_remove(&tdev->idr, base->handle);
-	spin_unlock(&tdev->object_lock);
+	xa_erase(&tdev->bases, base->handle);
 
 	/*
 	 * Note: We don't use synchronize_rcu() here because it's far
@@ -287,7 +276,7 @@ ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key)
 	struct ttm_base_object *base;
 
 	rcu_read_lock();
-	base = idr_find(&tdev->idr, key);
+	base = xa_load(&tdev->bases, key);
 
 	if (base && !kref_get_unless_zero(&base->refcount))
 		base = NULL;
@@ -534,13 +523,12 @@ ttm_object_device_init(struct ttm_mem_global *mem_glob,
 		return NULL;
 
 	tdev->mem_glob = mem_glob;
-	spin_lock_init(&tdev->object_lock);
 	atomic_set(&tdev->object_count, 0);
 	ret = drm_ht_create(&tdev->object_hash, hash_order);
 	if (ret != 0)
 		goto out_no_object_hash;
 
-	idr_init(&tdev->idr);
+	xa_init_flags(&tdev->bases, XA_FLAGS_ALLOC);
 	tdev->ops = *ops;
 	tdev->dmabuf_release = tdev->ops.release;
 	tdev->ops.release = ttm_prime_dmabuf_release;
@@ -559,8 +547,7 @@ void ttm_object_device_release(struct ttm_object_device **p_tdev)
 
 	*p_tdev = NULL;
 
-	WARN_ON_ONCE(!idr_is_empty(&tdev->idr));
-	idr_destroy(&tdev->idr);
+	WARN_ON_ONCE(!xa_empty(&tdev->bases));
 	drm_ht_remove(&tdev->object_hash);
 
 	kfree(tdev);
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 34/34] drm/vmwgfx: Convert res_idr to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (32 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 33/34] drm/vmwgfx: Convert base IDR " Matthew Wilcox
@ 2019-02-21 18:42 ` Matthew Wilcox
  2019-02-22  9:54 ` [PATCH 00/34] Convert DRM " Daniel Vetter
  34 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-21 18:42 UTC (permalink / raw)
  To: dri-devel; +Cc: Matthew Wilcox

Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c      |  9 +------
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h      |  3 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 31 ++++++------------------
 3 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 25afb1d594e3..2d121fbe5c93 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -677,7 +677,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 	spin_lock_init(&dev_priv->cursor_lock);
 
 	for (i = vmw_res_context; i < vmw_res_max; ++i) {
-		idr_init(&dev_priv->res_idr[i]);
+		xa_init_flags(&dev_priv->resources[i], XA_FLAGS_ALLOC1);
 		INIT_LIST_HEAD(&dev_priv->res_lru[i]);
 	}
 
@@ -988,9 +988,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 out_err4:
 	memunmap(dev_priv->mmio_virt);
 out_err0:
-	for (i = vmw_res_context; i < vmw_res_max; ++i)
-		idr_destroy(&dev_priv->res_idr[i]);
-
 	if (dev_priv->ctx.staged_bindings)
 		vmw_binding_state_free(dev_priv->ctx.staged_bindings);
 	kfree(dev_priv);
@@ -1000,7 +997,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 static void vmw_driver_unload(struct drm_device *dev)
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
-	enum vmw_res_type i;
 
 	unregister_pm_notifier(&dev_priv->pm_nb);
 
@@ -1039,9 +1035,6 @@ static void vmw_driver_unload(struct drm_device *dev)
 	if (dev_priv->ctx.staged_bindings)
 		vmw_binding_state_free(dev_priv->ctx.staged_bindings);
 
-	for (i = vmw_res_context; i < vmw_res_max; ++i)
-		idr_destroy(&dev_priv->res_idr[i]);
-
 	kfree(dev_priv);
 }
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index cd607ba9c2fe..e7613a33a773 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -484,7 +484,8 @@ struct vmw_private {
 	 */
 
 	spinlock_t resource_lock;
-	struct idr res_idr[vmw_res_max];
+	struct xarray resources[vmw_res_max];
+
 	/*
 	 * Block lastclose from racing with firstopen.
 	 */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 3025bfc001a1..d8cc329a9c0e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -56,13 +56,11 @@ vmw_resource_reference_unless_doomed(struct vmw_resource *res)
 void vmw_resource_release_id(struct vmw_resource *res)
 {
 	struct vmw_private *dev_priv = res->dev_priv;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
-	spin_lock(&dev_priv->resource_lock);
 	if (res->id != -1)
-		idr_remove(idr, res->id);
+		xa_erase(xa, res->id);
 	res->id = -1;
-	spin_unlock(&dev_priv->resource_lock);
 }
 
 static void vmw_resource_release(struct kref *kref)
@@ -70,8 +68,7 @@ static void vmw_resource_release(struct kref *kref)
 	struct vmw_resource *res =
 	    container_of(kref, struct vmw_resource, kref);
 	struct vmw_private *dev_priv = res->dev_priv;
-	int id;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
 	spin_lock(&dev_priv->resource_lock);
 	list_del_init(&res->lru_head);
@@ -101,16 +98,12 @@ static void vmw_resource_release(struct kref *kref)
 		res->hw_destroy(res);
 	}
 
-	id = res->id;
+	if (res->id != -1)
+		xa_erase(xa, res->id);
 	if (res->res_free != NULL)
 		res->res_free(res);
 	else
 		kfree(res);
-
-	spin_lock(&dev_priv->resource_lock);
-	if (id != -1)
-		idr_remove(idr, id);
-	spin_unlock(&dev_priv->resource_lock);
 }
 
 void vmw_resource_unreference(struct vmw_resource **p_res)
@@ -133,21 +126,11 @@ void vmw_resource_unreference(struct vmw_resource **p_res)
 int vmw_resource_alloc_id(struct vmw_resource *res)
 {
 	struct vmw_private *dev_priv = res->dev_priv;
-	int ret;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
 	BUG_ON(res->id != -1);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&dev_priv->resource_lock);
-
-	ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		res->id = ret;
-
-	spin_unlock(&dev_priv->resource_lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+	return xa_alloc(xa, &res->id, res, xa_limit_31b, GFP_NOWAIT);
 }
 
 /**
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 01/34] drm: Convert drm_minors_idr to XArray
  2019-02-21 18:41 ` [PATCH 01/34] drm: Convert drm_minors_idr " Matthew Wilcox
@ 2019-02-22  9:11   ` Daniel Vetter
  2019-02-22  9:55     ` Daniel Vetter
  2019-02-22 15:13     ` Matthew Wilcox
  0 siblings, 2 replies; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22  9:11 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Thu, Feb 21, 2019 at 10:41:21AM -0800, Matthew Wilcox wrote:
> Divide all the indices by 64 to save memory.
> 
> Signed-off-by: Matthew Wilcox <willy@infradead.org>

Pretty sure this goes boom. Our char device minor allocation scheme is

device 0: card0=0, renderD0=64
device 1: card1=1, renderD1=65
...

I think your scheme aliases all devices with the first one.

And yes the minor(cardX) + 64 == minor(renderDX) is uapi :-)

If you want to save space we'd need to move the minor allocation from
drm_minor to drm_device (with a very strange allocation scheme of blocks
of 64 entries, every 128 entries). That would also solve the issue with
the current scheme potentially racing if you load multiple drivers at the
same time (except for drm_global_mutex, but that's more an accident than
intention). Not sure if worth the bother.

Or maybe coffee hasn't kicked in yet over here and I'm missing something?
-Daniel

> ---
>  drivers/gpu/drm/drm_drv.c | 49 ++++++++++++++-------------------------
>  1 file changed, 17 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 12e5e2be7890..17ed29f49060 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -64,8 +64,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
>  "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
>  module_param_named(debug, drm_debug, int, 0600);
>  
> -static DEFINE_SPINLOCK(drm_minor_lock);
> -static struct idr drm_minors_idr;
> +static DEFINE_XARRAY_FLAGS(drm_minors, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
>  
>  /*
>   * If the drm core fails to init for whatever reason,
> @@ -109,7 +108,6 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
>  static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>  {
>  	struct drm_minor *minor;
> -	unsigned long flags;
>  	int r;
>  
>  	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
> @@ -118,22 +116,12 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>  
>  	minor->type = type;
>  	minor->dev = dev;
> +	minor->index = 64 * type;
>  
> -	idr_preload(GFP_KERNEL);
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	r = idr_alloc(&drm_minors_idr,
> -		      NULL,
> -		      64 * type,
> -		      64 * (type + 1),
> -		      GFP_NOWAIT);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> -	idr_preload_end();
> -
> +	r = xa_insert_irq(&drm_minors, minor->index / 64, NULL, GFP_KERNEL);
>  	if (r < 0)
>  		goto err_free;
>  
> -	minor->index = r;
> -
>  	minor->kdev = drm_sysfs_minor_alloc(minor);
>  	if (IS_ERR(minor->kdev)) {
>  		r = PTR_ERR(minor->kdev);
> @@ -144,9 +132,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>  	return 0;
>  
>  err_index:
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_remove(&drm_minors_idr, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +	xa_erase_irq(&drm_minors, minor->index / 64);
>  err_free:
>  	kfree(minor);
>  	return r;
> @@ -164,9 +150,9 @@ static void drm_minor_free(struct drm_device *dev, unsigned int type)
>  
>  	put_device(minor->kdev);
>  
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_remove(&drm_minors_idr, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +	xa_lock_irqsave(&drm_minors, flags);
> +	__xa_erase(&drm_minors, minor->index / 64);
> +	xa_unlock_irqrestore(&drm_minors, flags);
>  
>  	kfree(minor);
>  	*slot = NULL;
> @@ -195,9 +181,9 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type)
>  		goto err_debugfs;
>  
>  	/* replace NULL with @minor so lookups will succeed from now on */
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_replace(&drm_minors_idr, minor, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +	xa_lock_irqsave(&drm_minors, flags);
> +	__xa_store(&drm_minors, minor->index / 64, minor, 0);
> +	xa_unlock_irqrestore(&drm_minors, flags);
>  
>  	DRM_DEBUG("new minor registered %d\n", minor->index);
>  	return 0;
> @@ -217,9 +203,9 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
>  		return;
>  
>  	/* replace @minor with NULL so lookups will fail from now on */
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_replace(&drm_minors_idr, NULL, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +	xa_lock_irqsave(&drm_minors, flags);
> +	__xa_store(&drm_minors, minor->index / 64, NULL, 0);
> +	xa_unlock_irqrestore(&drm_minors, flags);
>  
>  	device_del(minor->kdev);
>  	dev_set_drvdata(minor->kdev, NULL); /* safety belt */
> @@ -240,11 +226,11 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id)
>  	struct drm_minor *minor;
>  	unsigned long flags;
>  
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	minor = idr_find(&drm_minors_idr, minor_id);
> +	xa_lock_irqsave(&drm_minors, flags);
> +	minor = xa_load(&drm_minors, minor_id / 64);
>  	if (minor)
>  		drm_dev_get(minor->dev);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +	xa_unlock_irqrestore(&drm_minors, flags);
>  
>  	if (!minor) {
>  		return ERR_PTR(-ENODEV);
> @@ -958,7 +944,7 @@ static void drm_core_exit(void)
>  	unregister_chrdev(DRM_MAJOR, "drm");
>  	debugfs_remove(drm_debugfs_root);
>  	drm_sysfs_destroy();
> -	idr_destroy(&drm_minors_idr);
> +	WARN_ON(!xa_empty(&drm_minors));
>  	drm_connector_ida_destroy();
>  }
>  
> @@ -967,7 +953,6 @@ static int __init drm_core_init(void)
>  	int ret;
>  
>  	drm_connector_ida_init();
> -	idr_init(&drm_minors_idr);
>  
>  	ret = drm_sysfs_init();
>  	if (ret < 0) {
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 03/34] drm: Convert object_name_idr to XArray
  2019-02-21 18:41 ` [PATCH 03/34] drm: Convert object_name_idr " Matthew Wilcox
@ 2019-02-22  9:17   ` Daniel Vetter
  0 siblings, 0 replies; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22  9:17 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Thu, Feb 21, 2019 at 10:41:25AM -0800, Matthew Wilcox wrote:
> Leave the object_name_lock in place for now as I'm not certain it can be
> removed safely.

It protects all object names, not just the gem flink one, also dma-buf
exports. See struct drm_gem_object.dma_buf kerneldoc. We could completely
replace object_name_lock with xa_lock, but that feels a bit silly (or
would at least need some drm_gem_object_name_lock/unlock helpers to give
it some meaning). But spin_lock is probably not the right one, we run
quite some code under object_name_lock.

Maybe add that to the commit message for the next round and leave as-is.
-Daniel

> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>  drivers/gpu/drm/drm_debugfs.c | 19 ++++++-------------
>  drivers/gpu/drm/drm_gem.c     | 11 +++++------
>  include/drm/drm_device.h      |  2 +-
>  3 files changed, 12 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index f8468eae0503..2bf08f293331 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -106,27 +106,20 @@ static int drm_clients_info(struct seq_file *m, void *data)
>  	return 0;
>  }
>  
> -static int drm_gem_one_name_info(int id, void *ptr, void *data)
> -{
> -	struct drm_gem_object *obj = ptr;
> -	struct seq_file *m = data;
> -
> -	seq_printf(m, "%6d %8zd %7d %8d\n",
> -		   obj->name, obj->size,
> -		   obj->handle_count,
> -		   kref_read(&obj->refcount));
> -	return 0;
> -}
> -
>  static int drm_gem_name_info(struct seq_file *m, void *data)
>  {
>  	struct drm_info_node *node = (struct drm_info_node *) m->private;
>  	struct drm_device *dev = node->minor->dev;
> +	struct drm_gem_object *obj;
> +	unsigned long index;
>  
>  	seq_printf(m, "  name     size handles refcount\n");
>  
>  	mutex_lock(&dev->object_name_lock);
> -	idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m);
> +	xa_for_each(&dev->object_names, index, obj) {
> +		seq_printf(m, "%6d %8zd %7d %8d\n", obj->name, obj->size,
> +				obj->handle_count, kref_read(&obj->refcount));
> +	}
>  	mutex_unlock(&dev->object_name_lock);
>  
>  	return 0;
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 8b55ece97967..0a52a958cffe 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -98,7 +98,7 @@ drm_gem_init(struct drm_device *dev)
>  	struct drm_vma_offset_manager *vma_offset_manager;
>  
>  	mutex_init(&dev->object_name_lock);
> -	idr_init_base(&dev->object_name_idr, 1);
> +	xa_init_flags(&dev->object_names, XA_FLAGS_ALLOC1);
>  
>  	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);
>  	if (!vma_offset_manager) {
> @@ -205,7 +205,7 @@ static void drm_gem_object_handle_free(struct drm_gem_object *obj)
>  
>  	/* Remove any name for this object */
>  	if (obj->name) {
> -		idr_remove(&dev->object_name_idr, obj->name);
> +		xa_erase(&dev->object_names, obj->name);
>  		obj->name = 0;
>  	}
>  }
> @@ -714,11 +714,10 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
>  	}
>  
>  	if (!obj->name) {
> -		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_KERNEL);
> +		ret = xa_alloc(&dev->object_names, &obj->name, obj,
> +				xa_limit_32b, GFP_KERNEL);
>  		if (ret < 0)
>  			goto err;
> -
> -		obj->name = ret;
>  	}
>  
>  	args->name = (uint64_t) obj->name;
> @@ -754,7 +753,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
>  		return -EOPNOTSUPP;
>  
>  	mutex_lock(&dev->object_name_lock);
> -	obj = idr_find(&dev->object_name_idr, (int) args->name);
> +	obj = xa_load(&dev->object_names, (int) args->name);
>  	if (obj) {
>  		drm_gem_object_get(obj);
>  	} else {
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index 42411b3ea0c8..52e271b97de8 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -219,7 +219,7 @@ struct drm_device {
>  	/** \name GEM information */
>  	/*@{ */
>  	struct mutex object_name_lock;
> -	struct idr object_name_idr;
> +	struct xarray object_names;
>  	struct drm_vma_offset_manager *vma_offset_manager;
>  	/*@} */
>  	int switch_power_state;
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 11/34] drm: Convert crtc_idr to XArray
  2019-02-21 18:41 ` [PATCH 11/34] drm: Convert crtc_idr " Matthew Wilcox
@ 2019-02-22  9:40   ` Daniel Vetter
  2019-02-22 15:32     ` Matthew Wilcox
  0 siblings, 1 reply; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22  9:40 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Thu, Feb 21, 2019 at 10:41:41AM -0800, Matthew Wilcox wrote:
>  - Rename it to 'objects', as requested in todo.rst

Yay, thanks!

>  - Also convert leases IDR to XArray as the two are occasionally used by
>    the same code (see drm_mode_get_lease_ioctl())
>  - Refactor drm_mode_create_lease_ioctl() to create the new drm_master
>    early to avoid creating an XArray on the stack and reparenting it
>    afterwards.

All lgtm, also the idr_replace replacement.

One thing I wonder: For the lesse object xa, we really only store 0/1 in
there, and I don't think that'll change. There was once the idea that we'd
look up objects for a lease directly, bypassing the main object idr. But
that doesn't work due to unregister/hotunplug rules, or at least it would
be pain not worth having. Might be worth it to a lookup structure
optimized for that. Or does XA already autocompress that for us? The
object id are likely fairly compressed, good chance all the ones you need
for a lease will fit into the first 64 id.

> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>  Documentation/gpu/todo.rst        |   3 -
>  drivers/gpu/drm/drm_auth.c        |   4 +-
>  drivers/gpu/drm/drm_lease.c       | 136 ++++++++++++++----------------
>  drivers/gpu/drm/drm_mode_config.c |   3 +-
>  drivers/gpu/drm/drm_mode_object.c |  47 +++++------
>  include/drm/drm_auth.h            |   2 +-
>  include/drm/drm_mode_config.h     |   6 +-
>  7 files changed, 90 insertions(+), 111 deletions(-)
> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index 14191b64446d..41da7b06195c 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -354,9 +354,6 @@ KMS cleanups
>  
>  Some of these date from the very introduction of KMS in 2008 ...
>  
> -- drm_mode_config.crtc_idr is misnamed, since it contains all KMS object. Should
> -  be renamed to drm_mode_config.object_idr.
> -
>  - drm_display_mode doesn't need to be derived from drm_mode_object. That's
>    leftovers from older (never merged into upstream) KMS designs where modes
>    where set using their ID, including support to add/remove modes.
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index 1813507f9b9c..c6967f0b095d 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -110,7 +110,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
>  	/* initialize the tree of output resource lessees */
>  	master->lessor = NULL;
>  	master->lessee_id = 0;
> -	idr_init(&master->leases);
> +	xa_init(&master->leases);

XA_FALGS_ALLOC1, for safety to make sure we never store 0 (considered
invalid id throughout at least modern drm)?
-Daniel

>  	xa_init_flags(&master->lessees, XA_FLAGS_ALLOC1);
>  
>  	return master;
> @@ -345,7 +345,7 @@ static void drm_master_destroy(struct kref *kref)
>  
>  	drm_legacy_master_rmmaps(dev, master);
>  
> -	idr_destroy(&master->leases);
> +	xa_destroy(&master->leases);
>  
>  	kfree(master->unique);
>  	kfree(master);
> diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
> index 47830f9ec616..1e88f406c738 100644
> --- a/drivers/gpu/drm/drm_lease.c
> +++ b/drivers/gpu/drm/drm_lease.c
> @@ -20,8 +20,6 @@
>  #include <drm/drm_auth.h>
>  #include <drm/drm_crtc_helper.h>
>  
> -static uint64_t drm_lease_idr_object;
> -
>  /**
>   * drm_lease_owner - return ancestor owner drm_master
>   * @master: drm_master somewhere within tree of lessees and lessors
> @@ -69,7 +67,7 @@ static int _drm_lease_held_master(struct drm_master *master, int id)
>  {
>  	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
>  	if (master->lessor)
> -		return idr_find(&master->leases, id) != NULL;
> +		return xa_load(&master->leases, id) != NULL;
>  	return true;
>  }
>  
> @@ -183,7 +181,7 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
>  /*
>   * drm_lease_create - create a new drm_master with leased objects (idr_mutex not held)
>   * @lessor: lease holder (or owner) of objects
> - * @leases: objects to lease to the new drm_master
> + * @lessee: leaser of objects
>   *
>   * Uses drm_master_create to allocate a new drm_master, then checks to
>   * make sure all of the desired objects can be leased, atomically
> @@ -195,35 +193,30 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
>   *	ERR_PTR(-EEXIST)	same object specified more than once in the provided list
>   *	ERR_PTR(-ENOMEM)	allocation failed
>   */
> -static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
> +static struct drm_master *drm_lease_create(struct drm_master *lessor,
> +		struct drm_master *lessee)
>  {
>  	struct drm_device *dev = lessor->dev;
>  	int error;
> -	struct drm_master *lessee;
> -	int object;
>  	void *entry;
> +	unsigned long index;
>  
>  	DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
>  
> -	lessee = drm_master_create(lessor->dev);
> -	if (!lessee) {
> -		DRM_DEBUG_LEASE("drm_master_create failed\n");
> -		return ERR_PTR(-ENOMEM);
> -	}
> -
>  	mutex_lock(&dev->mode_config.idr_mutex);
>  
> -	idr_for_each_entry(leases, entry, object) {
> +	xa_for_each(&lessee->leases, index, entry) {
>  		error = 0;
> -		if (!idr_find(&dev->mode_config.crtc_idr, object))
> +		if (!xa_load(&dev->mode_config.objects, index))
>  			error = -ENOENT;
> -		else if (!_drm_lease_held_master(lessor, object))
> +		else if (!_drm_lease_held_master(lessor, index))
>  			error = -EACCES;
> -		else if (_drm_has_leased(lessor, object))
> +		else if (_drm_has_leased(lessor, index))
>  			error = -EBUSY;
>  
>  		if (error != 0) {
> -			DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
> +			DRM_DEBUG_LEASE("object %d failed %d\n", (u32)index,
> +					error);
>  			goto out_lessee;
>  		}
>  	}
> @@ -236,8 +229,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
>  
>  	lessee->lessor = drm_master_get(lessor);
>  
> -	/* Move the leases over */
> -	lessee->leases = *leases;
>  	DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
>  
>  	mutex_unlock(&dev->mode_config.idr_mutex);
> @@ -246,8 +237,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
>  out_lessee:
>  	mutex_unlock(&dev->mode_config.idr_mutex);
>  
> -	drm_master_put(&lessee);
> -
>  	return ERR_PTR(error);
>  }
>  
> @@ -292,8 +281,6 @@ void drm_lease_destroy(struct drm_master *master)
>   */
>  static void _drm_lease_revoke(struct drm_master *top)
>  {
> -	int object;
> -	void *entry;
>  	struct drm_master *master = top;
>  
>  	lockdep_assert_held(&top->dev->mode_config.idr_mutex);
> @@ -309,8 +296,7 @@ static void _drm_lease_revoke(struct drm_master *top)
>  		DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
>  
>  		/* Evacuate the lease */
> -		idr_for_each_entry(&master->leases, entry, object)
> -			idr_remove(&master->leases, object);
> +		xa_destroy(&master->leases);
>  
>  		/* Depth-first tree walk */
>  		tmp = xa_find(&master->lessees, &index, ULONG_MAX, XA_PRESENT);
> @@ -378,11 +364,9 @@ static int validate_lease(struct drm_device *dev,
>  	return 0;
>  }
>  
> -static int fill_object_idr(struct drm_device *dev,
> -			   struct drm_file *lessor_priv,
> -			   struct idr *leases,
> -			   int object_count,
> -			   u32 *object_ids)
> +static int fill_object_array(struct drm_device *dev,
> +		struct drm_file *lessor_priv, struct xarray *leases,
> +		int object_count, u32 *object_ids)
>  {
>  	struct drm_mode_object **objects;
>  	u32 o;
> @@ -431,14 +415,14 @@ static int fill_object_idr(struct drm_device *dev,
>  		DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
>  
>  		/*
> -		 * We're using an IDR to hold the set of leased
> +		 * We're using an array to hold the set of leased
>  		 * objects, but we don't need to point at the object's
> -		 * data structure from the lease as the main crtc_idr
> +		 * data structure from the lease as the main object array
>  		 * will be used to actually find that. Instead, all we
>  		 * really want is a 'leased/not-leased' result, for
>  		 * which any non-NULL pointer will work fine.
>  		 */
> -		ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
> +		ret = xa_insert(leases, object_id, xa_mk_value(0), GFP_KERNEL);
>  		if (ret < 0) {
>  			DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
>  					object_id, ret);
> @@ -446,19 +430,21 @@ static int fill_object_idr(struct drm_device *dev,
>  		}
>  		if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
>  			struct drm_crtc *crtc = obj_to_crtc(obj);
> -			ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
> +			ret = xa_insert(leases, crtc->primary->base.id,
> +					xa_mk_value(0), GFP_KERNEL);
>  			if (ret < 0) {
>  				DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
>  						object_id, ret);
>  				goto out_free_objects;
>  			}
> -			if (crtc->cursor) {
> -				ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
> -				if (ret < 0) {
> -					DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
> -							object_id, ret);
> -					goto out_free_objects;
> -				}
> +			if (!crtc->cursor)
> +				continue;
> +			ret = xa_insert(leases, crtc->cursor->base.id,
> +					xa_mk_value(0), GFP_KERNEL);
> +			if (ret < 0) {
> +				DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
> +						object_id, ret);
> +				goto out_free_objects;
>  			}
>  		}
>  	}
> @@ -490,9 +476,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
>  	struct drm_mode_create_lease *cl = data;
>  	size_t object_count;
>  	int ret = 0;
> -	struct idr leases;
>  	struct drm_master *lessor = lessor_priv->master;
> -	struct drm_master *lessee = NULL;
> +	struct drm_master *lessee;
>  	struct file *lessee_file = NULL;
>  	struct file *lessor_file = lessor_priv->filp;
>  	struct drm_file *lessee_priv;
> @@ -520,37 +505,42 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
>  		return -EINVAL;
>  	}
>  
> -	object_count = cl->object_count;
> +	lessee = drm_master_create(lessor->dev);
> +	if (!lessee) {
> +		DRM_DEBUG_LEASE("drm_master_create failed\n");
> +		return -ENOMEM;
> +	}
>  
> -	object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), object_count * sizeof(__u32));
> -	if (IS_ERR(object_ids))
> -		return PTR_ERR(object_ids);
> +	object_count = cl->object_count;
>  
> -	idr_init(&leases);
> +	object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
> +			array_size(object_count, sizeof(__u32)));
> +	if (IS_ERR(object_ids)) {
> +		ret = PTR_ERR(object_ids);
> +		goto out_lessee;
> +	}
>  
> -	/* fill and validate the object idr */
> -	ret = fill_object_idr(dev, lessor_priv, &leases,
> +	/* fill and validate the object array */
> +	ret = fill_object_array(dev, lessor_priv, &lessee->leases,
>  			      object_count, object_ids);
>  	kfree(object_ids);
>  	if (ret) {
>  		DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret);
> -		idr_destroy(&leases);
> -		return ret;
> +		goto out_lessee;
>  	}
>  
>  	/* Allocate a file descriptor for the lease */
> -	fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
> -	if (fd < 0) {
> -		idr_destroy(&leases);
> -		return fd;
> -	}
> +	ret = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
> +	if (ret < 0)
> +		goto out_lessee;
> +	fd = ret;
>  
>  	DRM_DEBUG_LEASE("Creating lease\n");
> -	lessee = drm_lease_create(lessor, &leases);
> +	lessee = drm_lease_create(lessor, lessee);
>  
>  	if (IS_ERR(lessee)) {
>  		ret = PTR_ERR(lessee);
> -		goto out_leases;
> +		goto out_fd;
>  	}
>  
>  	/* Clone the lessor file to create a new file for us */
> @@ -558,7 +548,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
>  	lessee_file = file_clone_open(lessor_file);
>  	if (IS_ERR(lessee_file)) {
>  		ret = PTR_ERR(lessee_file);
> -		goto out_lessee;
> +		goto out_fd;
>  	}
>  
>  	lessee_priv = lessee_file->private_data;
> @@ -579,13 +569,11 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
>  	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
>  	return 0;
>  
> +out_fd:
> +	put_unused_fd(fd);
>  out_lessee:
>  	drm_master_put(&lessee);
>  
> -out_leases:
> -	put_unused_fd(fd);
> -	idr_destroy(&leases);
> -
>  	DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
>  	return ret;
>  }
> @@ -627,7 +615,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
>  	count = 0;
>  	xa_for_each(&lessor->lessees, index, lessee) {
>  		/* Only list un-revoked leases */
> -		if (!idr_is_empty(&lessee->leases)) {
> +		if (!xa_empty(&lessee->leases)) {
>  			if (count_lessees > count) {
>  				DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
>  				ret = put_user(lessee->lessee_id, lessee_ids + count);
> @@ -663,10 +651,10 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
>  	__u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
>  	__u32 count_objects = arg->count_objects;
>  	struct drm_master *lessee = lessee_priv->master;
> -	struct idr *object_idr;
> +	struct xarray *objects;
>  	int count;
>  	void *entry;
> -	int object;
> +	unsigned long index;
>  	int ret = 0;
>  
>  	if (arg->pad)
> @@ -682,16 +670,16 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
>  
>  	if (lessee->lessor == NULL)
>  		/* owner can use all objects */
> -		object_idr = &lessee->dev->mode_config.crtc_idr;
> +		objects = &lessee->dev->mode_config.objects;
>  	else
> -		/* lessee can only use allowed object */
> -		object_idr = &lessee->leases;
> +		/* lessee can only use allowed objects */
> +		objects = &lessee->leases;
>  
>  	count = 0;
> -	idr_for_each_entry(object_idr, entry, object) {
> +	xa_for_each(objects, index, entry) {
>  		if (count_objects > count) {
> -			DRM_DEBUG_LEASE("adding object %d\n", object);
> -			ret = put_user(object, object_ids + count);
> +			DRM_DEBUG_LEASE("adding object %d\n", (u32)index);
> +			ret = put_user((u32)index, object_ids + count);
>  			if (ret)
>  				break;
>  		}
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 609b30d7dcb1..10c616e0f591 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -393,7 +393,7 @@ void drm_mode_config_init(struct drm_device *dev)
>  	INIT_LIST_HEAD(&dev->mode_config.property_list);
>  	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
>  	INIT_LIST_HEAD(&dev->mode_config.plane_list);
> -	idr_init(&dev->mode_config.crtc_idr);
> +	xa_init_flags(&dev->mode_config.objects, XA_FLAGS_ALLOC1);
>  	xa_init_flags(&dev->mode_config.tiles, XA_FLAGS_ALLOC1);
>  	ida_init(&dev->mode_config.connector_ida);
>  	spin_lock_init(&dev->mode_config.connector_list_lock);
> @@ -495,7 +495,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>  	}
>  
>  	ida_destroy(&dev->mode_config.connector_ida);
> -	idr_destroy(&dev->mode_config.crtc_idr);
>  	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
>  }
>  EXPORT_SYMBOL(drm_mode_config_cleanup);
> diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
> index 004191d01772..686fba472abf 100644
> --- a/drivers/gpu/drm/drm_mode_object.c
> +++ b/drivers/gpu/drm/drm_mode_object.c
> @@ -37,24 +37,23 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
>  {
>  	int ret;
>  
> -	mutex_lock(&dev->mode_config.idr_mutex);
> -	ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL,
> -			1, 0, GFP_KERNEL);
> -	if (ret >= 0) {
> -		/*
> -		 * Set up the object linking under the protection of the idr
> -		 * lock so that other users can't see inconsistent state.
> -		 */
> -		obj->id = ret;
> -		obj->type = obj_type;
> -		if (obj_free_cb) {
> -			obj->free_cb = obj_free_cb;
> -			kref_init(&obj->refcount);
> -		}
> +	/*
> +	 * Initialise the object before putting the object in the array
> +	 * so that other users can't see inconsistent state.  The ID is
> +	 * initialised before the object is inserted into the array with
> +	 * a write barrier so even RCU-protected walkers can't see an
> +	 * uninitialised ID.
> +	 */
> +	obj->type = obj_type;
> +	if (obj_free_cb) {
> +		obj->free_cb = obj_free_cb;
> +		kref_init(&obj->refcount);
>  	}
> -	mutex_unlock(&dev->mode_config.idr_mutex);
>  
> -	return ret < 0 ? ret : 0;
> +	ret = xa_alloc(&dev->mode_config.objects, &obj->id,
> +			register_obj ? obj : NULL, xa_limit_31b, GFP_KERNEL);
> +
> +	return ret;
>  }
>  
>  /**
> @@ -78,9 +77,7 @@ int drm_mode_object_add(struct drm_device *dev,
>  void drm_mode_object_register(struct drm_device *dev,
>  			      struct drm_mode_object *obj)
>  {
> -	mutex_lock(&dev->mode_config.idr_mutex);
> -	idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
> -	mutex_unlock(&dev->mode_config.idr_mutex);
> +	xa_store(&dev->mode_config.objects, obj->id, obj, 0);
>  }
>  
>  /**
> @@ -97,12 +94,10 @@ void drm_mode_object_register(struct drm_device *dev,
>  void drm_mode_object_unregister(struct drm_device *dev,
>  				struct drm_mode_object *object)
>  {
> -	mutex_lock(&dev->mode_config.idr_mutex);
>  	if (object->id) {
> -		idr_remove(&dev->mode_config.crtc_idr, object->id);
> +		xa_erase(&dev->mode_config.objects, object->id);
>  		object->id = 0;
>  	}
> -	mutex_unlock(&dev->mode_config.idr_mutex);
>  }
>  
>  /**
> @@ -128,10 +123,10 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
>  					       struct drm_file *file_priv,
>  					       uint32_t id, uint32_t type)
>  {
> -	struct drm_mode_object *obj = NULL;
> +	struct drm_mode_object *obj;
>  
> -	mutex_lock(&dev->mode_config.idr_mutex);
> -	obj = idr_find(&dev->mode_config.crtc_idr, id);
> +	xa_lock(&dev->mode_config.objects);
> +	obj = xa_load(&dev->mode_config.objects, id);
>  	if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
>  		obj = NULL;
>  	if (obj && obj->id != id)
> @@ -145,7 +140,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
>  		if (!kref_get_unless_zero(&obj->refcount))
>  			obj = NULL;
>  	}
> -	mutex_unlock(&dev->mode_config.idr_mutex);
> +	xa_unlock(&dev->mode_config.objects);
>  
>  	return obj;
>  }
> diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
> index fbb58264538b..88c8bbf14916 100644
> --- a/include/drm/drm_auth.h
> +++ b/include/drm/drm_auth.h
> @@ -90,7 +90,7 @@ struct drm_master {
>  
>  	struct drm_master *lessor;
>  	int	lessee_id;
> -	struct idr leases;
> +	struct xarray leases;
>  	struct xarray lessees;
>  };
>  
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index fea334d99201..64bdf66d878c 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -397,12 +397,12 @@ struct drm_mode_config {
>  	struct mutex idr_mutex;
>  
>  	/**
> -	 * @crtc_idr:
> +	 * @objects:
>  	 *
> -	 * Main KMS ID tracking object. Use this idr for all IDs, fb, crtc,
> +	 * Main KMS ID tracking object. Use this array for all IDs, fb, crtc,
>  	 * connector, modes - just makes life easier to have only one.
>  	 */
> -	struct idr crtc_idr;
> +	struct xarray objects;
>  
>  	/**
>  	 * @tiles:
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/34] Convert DRM to XArray
  2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
                   ` (33 preceding siblings ...)
  2019-02-21 18:42 ` [PATCH 34/34] drm/vmwgfx: Convert res_idr " Matthew Wilcox
@ 2019-02-22  9:54 ` Daniel Vetter
  2019-02-24  4:21   ` Matthew Wilcox
  34 siblings, 1 reply; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22  9:54 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Thu, Feb 21, 2019 at 10:41:20AM -0800, Matthew Wilcox wrote:
> I intend to remove the IDR and the radix tree interfaces from Linux.
> Converting each user from either the IDR or radix tree interface varies
> from the trivial 1:1 replacement to a complete rewrite of the locking.
> Despite the best efforts of our automated testers (who have caught many
> of my mistakes), I cannot claim that my conversions of code are free
> from bugs.
> 
> Please check these patches over carefully and test them; there may be
> off-by-one errors, locking mistakes, or various other failures on my part.
> The patches are based on the latest XArray API which can be found here:
> http://git.infradead.org/users/willy/linux-dax.git/shortlog/refs/heads/xarray
> which I intend to submit during the upcoming merge window.

For testing please cc intel-gfx@lists.freedesktop.org on the entire
series, including dependencies, so our CI can pick it up.
> 
> Substantive interface changes
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
>  - The IDR and radix tree required callers to handle their own locking.
>    The XArray embeds a spinlock which is taken for modifications to
>    the data structure; plain lookups occur under the RCU read lock or
>    under the spinlock.
>  - You can take the spinlock yourself (xa_lock() and friends) to protect
>    related data.
>  - idr_alloc() returned -ENOSPC, radix_tree_insert() returned -EEXIST.
>    xa_insert() and xa_alloc() return -EBUSY.

I think this will upset a few of our tests. Just written some more for
drm-lease at least, and those check for the ENOSPC. Not sure yet what to
do.

>  - The search keys which the radix tree calls "tags", the XArray calls
>    "marks".
>  - There is no preloading in the XArray API.  If your locking is
>    exceptionally complicated, you may need to use xa_reserve(), but
>    there are only 6 callers of xa_reserve(), so it's quite uncommon.
>  - The radix tree provided GFP flags as part of the tree definition;
>    the XArray (like the IDR) passes GFP flags at the point of allocation.
>  - radix_tree_insert() of a NULL pointer was not well-specified.  The
>    XArray treats it as reserving the entry (it reads back as NULL but
>    a subsequent xa_insert() to that slot will fail).
>  - xa_alloc_cyclic() returns 1 if the allocation wraps, unlike
>    idr_alloc_cyclic() which provides no indication.
>  - There is no equivalent to idr_for_each(); the xa_for_each() iterator
>    is similar to idr_for_each_entry().
>  - idr_replace() has no exact equivalent.  Some users relied on its exact
>    semantics of only storing if the entry was non-NULL, but all users of
>    idr_replace() were able to use xa_store().

Yeah looked good to me.

>  - The family of radix tree gang lookup functions have been replaced with
>    xa_extract().
> 
> Matthew Wilcox (34):
>   drm: Convert drm_minors_idr to XArray
>   drm: Convert aux_idr to XArray
>   drm: Convert object_name_idr to XArray
>   drm: Convert object_idr to XArray
>   drm: Convert syncobj_idr to XArray
>   drm: Convert magic_map to XArray
>   drm: Convert lessee_idr to XArray
>   drm: Remove linked lists for lessees
>   drm: Convert ctx_idr to XArray
>   drm: Convert tile_idr to XArray
>   drm: Convert crtc_idr to XArray
>   drm/agp: Convert bo_list_handles to XArray

I did at least read the above, I'll leave all the driver patches for
others. At least for now, any leftovers can be smashed into drm-misc.

Thanks, Daniel

>   drm/amdgpu: Convert ctx_handles to XArray
>   drm/amdgpu: Convert pasid_idr to XArray
>   drm/amdkfd: Convert event_idr to XArray
>   drm/amdkfd: Convert alloc_idr to XArray
>   drm/etnaviv: Convert fence_idr to XArray
>   drm/i915: Convert handles_vma to XArray
>   drm/i915: Convert spt_tree to XArray
>   drm/i915: Convert page_track_tree to XArray
>   drm/i915: Convert get_page to XArray
>   drm/i915: Convert object_idr to IDA
>   drm/i915: Convert context_idr to XArray
>   drm/i915: Convert metrics_idr to XArray
>   drm/i915: Convert vgpus_idr to XArray
>   drm/qxl: Convert release_idr to XArray
>   drm/qxl: Convert surf_id_idr to XArray
>   drm/tegra: Convert contexts IDR to XArray
>   drm/vc4: Convert perfmon IDR to XArray
>   drm/sis: Convert object_idr to XArray
>   drm/vgem: Convert fence_idr to XArray
>   drm/via: Convert object_idr to XArray
>   drm/vmwgfx: Convert base IDR to XArray
>   drm/vmwgfx: Convert res_idr to XArray
> 
>  Documentation/gpu/todo.rst                    |   3 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   5 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c   |  22 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c       |  42 ++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h       |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c       |  23 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  10 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c     |   4 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c        |  66 ++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h        |   3 +-
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c         |  12 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_events.c       |  71 +++----
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |   4 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_process.c      |  32 ++-
>  drivers/gpu/drm/drm_auth.c                    |  27 +--
>  drivers/gpu/drm/drm_connector.c               |  27 +--
>  drivers/gpu/drm/drm_context.c                 |  42 ++--
>  drivers/gpu/drm/drm_debugfs.c                 |  19 +-
>  drivers/gpu/drm/drm_dp_aux_dev.c              |  41 ++--
>  drivers/gpu/drm/drm_drv.c                     |  49 ++---
>  drivers/gpu/drm/drm_gem.c                     |  78 +++----
>  drivers/gpu/drm/drm_lease.c                   | 201 ++++++++----------
>  drivers/gpu/drm/drm_mode_config.c             |   6 +-
>  drivers/gpu/drm/drm_mode_object.c             |  47 ++--
>  drivers/gpu/drm/drm_syncobj.c                 |  64 ++----
>  drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |  16 +-
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.c         |   5 +-
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.h         |   3 +-
>  drivers/gpu/drm/etnaviv/etnaviv_sched.c       |   8 +-
>  drivers/gpu/drm/i915/gvt/display.c            |   5 +-
>  drivers/gpu/drm/i915/gvt/dmabuf.c             |   7 +-
>  drivers/gpu/drm/i915/gvt/gtt.c                |  18 +-
>  drivers/gpu/drm/i915/gvt/gtt.h                |   2 +-
>  drivers/gpu/drm/i915/gvt/gvt.c                |   4 +-
>  drivers/gpu/drm/i915/gvt/gvt.h                |   9 +-
>  drivers/gpu/drm/i915/gvt/kvmgt.c              |   2 +-
>  drivers/gpu/drm/i915/gvt/page_track.c         |   6 +-
>  drivers/gpu/drm/i915/gvt/sched_policy.c       |   2 +-
>  drivers/gpu/drm/i915/gvt/vgpu.c               |  24 +--
>  drivers/gpu/drm/i915/i915_debugfs.c           |  48 +++--
>  drivers/gpu/drm/i915/i915_drv.h               |   9 +-
>  drivers/gpu/drm/i915/i915_gem.c               |  40 ++--
>  drivers/gpu/drm/i915/i915_gem_context.c       |  43 ++--
>  drivers/gpu/drm/i915/i915_gem_context.h       |   6 +-
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c    |   6 +-
>  drivers/gpu/drm/i915/i915_gem_object.h        |   6 +-
>  drivers/gpu/drm/i915/i915_perf.c              |  39 ++--
>  .../gpu/drm/i915/selftests/i915_gem_context.c |   7 +-
>  drivers/gpu/drm/i915/selftests/mock_context.c |   2 +-
>  drivers/gpu/drm/msm/msm_gem_submit.c          |  12 +-
>  drivers/gpu/drm/qxl/qxl_cmd.c                 |  60 ++----
>  drivers/gpu/drm/qxl/qxl_drv.h                 |   6 +-
>  drivers/gpu/drm/qxl/qxl_kms.c                 |   8 +-
>  drivers/gpu/drm/qxl/qxl_release.c             |  54 ++---
>  drivers/gpu/drm/sis/sis_drv.c                 |   4 +-
>  drivers/gpu/drm/sis/sis_drv.h                 |   2 +-
>  drivers/gpu/drm/sis/sis_mm.c                  |  17 +-
>  drivers/gpu/drm/tegra/drm.c                   |  35 ++-
>  drivers/gpu/drm/v3d/v3d_gem.c                 |  17 +-
>  drivers/gpu/drm/vc4/vc4_drv.h                 |   2 +-
>  drivers/gpu/drm/vc4/vc4_gem.c                 |   6 +-
>  drivers/gpu/drm/vc4/vc4_perfmon.c             |  33 ++-
>  drivers/gpu/drm/vgem/vgem_drv.h               |   3 +-
>  drivers/gpu/drm/vgem/vgem_fence.c             |  43 ++--
>  drivers/gpu/drm/via/via_drv.h                 |   2 +-
>  drivers/gpu/drm/via/via_map.c                 |   4 +-
>  drivers/gpu/drm/via/via_mm.c                  |  11 +-
>  drivers/gpu/drm/vmwgfx/ttm_object.c           |  29 +--
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c           |   9 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h           |   3 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_resource.c      |  31 +--
>  include/drm/drm_auth.h                        |  11 +-
>  include/drm/drm_device.h                      |   4 +-
>  include/drm/drm_file.h                        |  15 +-
>  include/drm/drm_mode_config.h                 |  18 +-
>  75 files changed, 673 insertions(+), 983 deletions(-)
> 
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 01/34] drm: Convert drm_minors_idr to XArray
  2019-02-22  9:11   ` Daniel Vetter
@ 2019-02-22  9:55     ` Daniel Vetter
  2019-02-22 15:13     ` Matthew Wilcox
  1 sibling, 0 replies; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22  9:55 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Fri, Feb 22, 2019 at 10:11:14AM +0100, Daniel Vetter wrote:
> On Thu, Feb 21, 2019 at 10:41:21AM -0800, Matthew Wilcox wrote:
> > Divide all the indices by 64 to save memory.
> > 
> > Signed-off-by: Matthew Wilcox <willy@infradead.org>
> 
> Pretty sure this goes boom. Our char device minor allocation scheme is
> 
> device 0: card0=0, renderD0=64
> device 1: card1=1, renderD1=65
> ...
> 
> I think your scheme aliases all devices with the first one.
> 
> And yes the minor(cardX) + 64 == minor(renderDX) is uapi :-)
> 
> If you want to save space we'd need to move the minor allocation from
> drm_minor to drm_device (with a very strange allocation scheme of blocks
> of 64 entries, every 128 entries). That would also solve the issue with
> the current scheme potentially racing if you load multiple drivers at the
> same time (except for drm_global_mutex, but that's more an accident than
> intention). Not sure if worth the bother.
> 
> Or maybe coffee hasn't kicked in yet over here and I'm missing something?

btw if you want to test locally, enable vkms.ko and vgem.ko and load them
both, for at least 2 drm drivers.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 01/34] drm: Convert drm_minors_idr to XArray
  2019-02-22  9:11   ` Daniel Vetter
  2019-02-22  9:55     ` Daniel Vetter
@ 2019-02-22 15:13     ` Matthew Wilcox
  1 sibling, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-22 15:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: dri-devel

On Fri, Feb 22, 2019 at 10:11:14AM +0100, Daniel Vetter wrote:
> On Thu, Feb 21, 2019 at 10:41:21AM -0800, Matthew Wilcox wrote:
> > Divide all the indices by 64 to save memory.
> > 
> > Signed-off-by: Matthew Wilcox <willy@infradead.org>
> 
> Pretty sure this goes boom. Our char device minor allocation scheme is
> 
> device 0: card0=0, renderD0=64
> device 1: card1=1, renderD1=65
> ...
> 
> I think your scheme aliases all devices with the first one.
> 
> And yes the minor(cardX) + 64 == minor(renderDX) is uapi :-)
> 
> If you want to save space we'd need to move the minor allocation from
> drm_minor to drm_device (with a very strange allocation scheme of blocks
> of 64 entries, every 128 entries). That would also solve the issue with
> the current scheme potentially racing if you load multiple drivers at the
> same time (except for drm_global_mutex, but that's more an accident than
> intention). Not sure if worth the bother.
> 
> Or maybe coffee hasn't kicked in yet over here and I'm missing something?

I'm the one who needed moar coffee.  I misread:

> > -	r = idr_alloc(&drm_minors_idr,
> > -		      NULL,
> > -		      64 * type,
> > -		      64 * (type + 1),
> > -		      GFP_NOWAIT);

As (64 * type) + 1.  So I'll redo this patch.

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 11/34] drm: Convert crtc_idr to XArray
  2019-02-22  9:40   ` Daniel Vetter
@ 2019-02-22 15:32     ` Matthew Wilcox
  2019-02-22 17:12       ` Daniel Vetter
  0 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-22 15:32 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: dri-devel

On Fri, Feb 22, 2019 at 10:40:14AM +0100, Daniel Vetter wrote:
> On Thu, Feb 21, 2019 at 10:41:41AM -0800, Matthew Wilcox wrote:
> >  - Rename it to 'objects', as requested in todo.rst
> 
> Yay, thanks!
> 
> >  - Also convert leases IDR to XArray as the two are occasionally used by
> >    the same code (see drm_mode_get_lease_ioctl())
> >  - Refactor drm_mode_create_lease_ioctl() to create the new drm_master
> >    early to avoid creating an XArray on the stack and reparenting it
> >    afterwards.
> 
> All lgtm, also the idr_replace replacement.
> 
> One thing I wonder: For the lesse object xa, we really only store 0/1 in
> there, and I don't think that'll change. There was once the idea that we'd
> look up objects for a lease directly, bypassing the main object idr. But
> that doesn't work due to unregister/hotunplug rules, or at least it would
> be pain not worth having. Might be worth it to a lookup structure
> optimized for that. Or does XA already autocompress that for us? The
> object id are likely fairly compressed, good chance all the ones you need
> for a lease will fit into the first 64 id.

The XArray doesn't compress the contents of the user pointers.  It might be
worth augmenting the IDA to have all the functionality you need (there's
no ida_test() today, for example).  I didn't want to take that on as part
of this project, and it's certainly no worse than the IDR.  But it's on
my radar along with a couple of other places in the kernel that could benefit
from the IDA if only it had a couple of extra features (eg the fd table
would like to an ida_for_each()).

It'd involve changing drm_mode_get_lease_ioctl() and maybe a couple of
other places where we use config.objects and leases interchangably, so
I wasn't entirely convinced it'd be worth it.

> > +++ b/drivers/gpu/drm/drm_auth.c
> > @@ -110,7 +110,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
> >  	/* initialize the tree of output resource lessees */
> >  	master->lessor = NULL;
> >  	master->lessee_id = 0;
> > -	idr_init(&master->leases);
> > +	xa_init(&master->leases);
> 
> XA_FALGS_ALLOC1, for safety to make sure we never store 0 (considered
> invalid id throughout at least modern drm)?

This xarray turns out not to be an allocating XArray, it's just one
we store pointers in at a predetermined ID.  Marking it as allocating
wouldn't be terribly harmful, just slightly inefficient.

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 11/34] drm: Convert crtc_idr to XArray
  2019-02-22 15:32     ` Matthew Wilcox
@ 2019-02-22 17:12       ` Daniel Vetter
  0 siblings, 0 replies; 53+ messages in thread
From: Daniel Vetter @ 2019-02-22 17:12 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Fri, Feb 22, 2019 at 4:32 PM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Fri, Feb 22, 2019 at 10:40:14AM +0100, Daniel Vetter wrote:
> > On Thu, Feb 21, 2019 at 10:41:41AM -0800, Matthew Wilcox wrote:
> > >  - Rename it to 'objects', as requested in todo.rst
> >
> > Yay, thanks!
> >
> > >  - Also convert leases IDR to XArray as the two are occasionally used by
> > >    the same code (see drm_mode_get_lease_ioctl())
> > >  - Refactor drm_mode_create_lease_ioctl() to create the new drm_master
> > >    early to avoid creating an XArray on the stack and reparenting it
> > >    afterwards.
> >
> > All lgtm, also the idr_replace replacement.
> >
> > One thing I wonder: For the lesse object xa, we really only store 0/1 in
> > there, and I don't think that'll change. There was once the idea that we'd
> > look up objects for a lease directly, bypassing the main object idr. But
> > that doesn't work due to unregister/hotunplug rules, or at least it would
> > be pain not worth having. Might be worth it to a lookup structure
> > optimized for that. Or does XA already autocompress that for us? The
> > object id are likely fairly compressed, good chance all the ones you need
> > for a lease will fit into the first 64 id.
>
> The XArray doesn't compress the contents of the user pointers.  It might be
> worth augmenting the IDA to have all the functionality you need (there's
> no ida_test() today, for example).  I didn't want to take that on as part
> of this project, and it's certainly no worse than the IDR.  But it's on
> my radar along with a couple of other places in the kernel that could benefit
> from the IDA if only it had a couple of extra features (eg the fd table
> would like to an ida_for_each()).
>
> It'd involve changing drm_mode_get_lease_ioctl() and maybe a couple of
> other places where we use config.objects and leases interchangably, so
> I wasn't entirely convinced it'd be worth it.

Makes all sense.

> > > +++ b/drivers/gpu/drm/drm_auth.c
> > > @@ -110,7 +110,7 @@ struct drm_master *drm_master_create(struct drm_device *dev)
> > >     /* initialize the tree of output resource lessees */
> > >     master->lessor = NULL;
> > >     master->lessee_id = 0;
> > > -   idr_init(&master->leases);
> > > +   xa_init(&master->leases);
> >
> > XA_FALGS_ALLOC1, for safety to make sure we never store 0 (considered
> > invalid id throughout at least modern drm)?
>
> This xarray turns out not to be an allocating XArray, it's just one
> we store pointers in at a predetermined ID.  Marking it as allocating
> wouldn't be terribly harmful, just slightly inefficient.

tbf I didn't read what exactly the flag means in detail, just wondered
whether it could help in making sure we never store something at id 0
(which would be a bug). But neither did the current code do such
checks, so fine either way.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/34] Convert DRM to XArray
  2019-02-22  9:54 ` [PATCH 00/34] Convert DRM " Daniel Vetter
@ 2019-02-24  4:21   ` Matthew Wilcox
  0 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-24  4:21 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: dri-devel

On Fri, Feb 22, 2019 at 10:54:21AM +0100, Daniel Vetter wrote:
> >  - idr_alloc() returned -ENOSPC, radix_tree_insert() returned -EEXIST.
> >    xa_insert() and xa_alloc() return -EBUSY.
> 
> I think this will upset a few of our tests. Just written some more for
> drm-lease at least, and those check for the ENOSPC. Not sure yet what to
> do.

If there's real userspace (not just a test suite) which actually relies
on the exact errno returned, we can change the places which currently
just return the errno to something like:

	if (err == -EBUSY)
		return -ENOSPC;
	return err;

There are actually a number of places in the kernel which do the opposite
translation today, presumably because having a program print out "No
space left on device" was confusing.

If it's only the test-suite which cares, presumably the test suite can
be changed to treat EBUSY and ENOSPC as being equivalent errno values
for a given test.

> I did at least read the above, I'll leave all the driver patches for
> others. At least for now, any leftovers can be smashed into drm-misc.

Thanks!  I'll resend after -rc1.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 12/34] drm/agp: Convert bo_list_handles to XArray
  2019-02-21 18:41 ` [PATCH 12/34] drm/agp: Convert bo_list_handles " Matthew Wilcox
@ 2019-02-25 16:06   ` Christian König
  2019-02-25 16:39     ` Matthew Wilcox
  0 siblings, 1 reply; 53+ messages in thread
From: Christian König @ 2019-02-25 16:06 UTC (permalink / raw)
  To: Matthew Wilcox, dri-devel

In this one there is a typo in the subject line.

Christian.

Am 21.02.19 um 19:41 schrieb Matthew Wilcox:
> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  3 +--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 22 ++++++++-------------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c     | 10 ++++------
>   3 files changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index bcef6ea4bcf9..6a704aaa7dbe 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -406,8 +406,7 @@ struct amdgpu_fpriv {
>   	struct amdgpu_vm	vm;
>   	struct amdgpu_bo_va	*prt_va;
>   	struct amdgpu_bo_va	*csa_va;
> -	struct mutex		bo_list_lock;
> -	struct idr		bo_list_handles;
> +	struct xarray		bo_list_handles;
>   	struct amdgpu_ctx_mgr	ctx_mgr;
>   };
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> index 5c79da8e1150..76439a52a6b0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> @@ -153,9 +153,7 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
>   {
>   	struct amdgpu_bo_list *list;
>   
> -	mutex_lock(&fpriv->bo_list_lock);
> -	list = idr_remove(&fpriv->bo_list_handles, id);
> -	mutex_unlock(&fpriv->bo_list_lock);
> +	list = xa_erase(&fpriv->bo_list_handles, id);
>   	if (list)
>   		kref_put(&list->refcount, amdgpu_bo_list_free);
>   }
> @@ -164,7 +162,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
>   		       struct amdgpu_bo_list **result)
>   {
>   	rcu_read_lock();
> -	*result = idr_find(&fpriv->bo_list_handles, id);
> +	*result = xa_load(&fpriv->bo_list_handles, id);
>   
>   	if (*result && kref_get_unless_zero(&(*result)->refcount)) {
>   		rcu_read_unlock();
> @@ -278,15 +276,13 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
>   		if (r)
>   			goto error_free;
>   
> -		mutex_lock(&fpriv->bo_list_lock);
> -		r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
> -		mutex_unlock(&fpriv->bo_list_lock);
> +		r = xa_alloc(&fpriv->bo_list_handles, &handle, list,
> +				xa_limit_31b, GFP_KERNEL);
>   		if (r < 0) {
>   			amdgpu_bo_list_put(list);
>   			return r;
>   		}
>   
> -		handle = r;
>   		break;
>   
>   	case AMDGPU_BO_LIST_OP_DESTROY:
> @@ -300,13 +296,11 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
>   		if (r)
>   			goto error_free;
>   
> -		mutex_lock(&fpriv->bo_list_lock);
> -		old = idr_replace(&fpriv->bo_list_handles, list, handle);
> -		mutex_unlock(&fpriv->bo_list_lock);
> -
> -		if (IS_ERR(old)) {
> +		old = xa_store(&fpriv->bo_list_handles, handle, list,
> +				GFP_KERNEL);
> +		if (xa_is_err(old)) {
>   			amdgpu_bo_list_put(list);
> -			r = PTR_ERR(old);
> +			r = xa_err(old);
>   			goto error_free;
>   		}
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index bc62bf41b7e9..1a5bf3a4f5d9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -986,8 +986,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>   			goto error_vm;
>   	}
>   
> -	mutex_init(&fpriv->bo_list_lock);
> -	idr_init(&fpriv->bo_list_handles);
> +	xa_init_flags(&fpriv->bo_list_handles, XA_FLAGS_ALLOC1);
>   
>   	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr);
>   
> @@ -1026,7 +1025,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
>   	struct amdgpu_bo_list *list;
>   	struct amdgpu_bo *pd;
>   	unsigned int pasid;
> -	int handle;
> +	unsigned long handle;
>   
>   	if (!fpriv)
>   		return;
> @@ -1058,11 +1057,10 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
>   		amdgpu_pasid_free_delayed(pd->tbo.resv, pasid);
>   	amdgpu_bo_unref(&pd);
>   
> -	idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
> +	xa_for_each(&fpriv->bo_list_handles, handle, list)
>   		amdgpu_bo_list_put(list);
>   
> -	idr_destroy(&fpriv->bo_list_handles);
> -	mutex_destroy(&fpriv->bo_list_lock);
> +	xa_destroy(&fpriv->bo_list_handles);
>   
>   	kfree(fpriv);
>   	file_priv->driver_priv = NULL;

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 13/34] drm/amdgpu: Convert ctx_handles to XArray
  2019-02-21 18:41 ` [PATCH 13/34] drm/amdgpu: Convert ctx_handles " Matthew Wilcox
@ 2019-02-25 16:07   ` Christian König
  2019-02-25 16:39     ` Matthew Wilcox
  0 siblings, 1 reply; 53+ messages in thread
From: Christian König @ 2019-02-25 16:07 UTC (permalink / raw)
  To: Matthew Wilcox, dri-devel

Am 21.02.19 um 19:41 schrieb Matthew Wilcox:
> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h       |  2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c   | 42 ++++++++---------------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h   |  2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c |  4 +--
>   4 files changed, 19 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 6a704aaa7dbe..c2650f143ba7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -164,7 +164,7 @@ extern int amdgpu_si_support;
>   extern int amdgpu_cik_support;
>   #endif
>   
> -#define AMDGPU_VM_MAX_NUM_CTX			4096
> +#define AMDGPU_VM_CTX_LIMIT			XA_LIMIT(0, 4095)

IIRC we actually use 0 as reserved context value in some places.

Christian.

>   #define AMDGPU_SG_THRESHOLD			(256*1024*1024)
>   #define AMDGPU_DEFAULT_GTT_SIZE_MB		3072ULL /* 3GB by default */
>   #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> index d85184b5b35c..bddc28b1c9ed 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> @@ -248,17 +248,17 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
>   		return -ENOMEM;
>   
>   	mutex_lock(&mgr->lock);
> -	r = idr_alloc(&mgr->ctx_handles, ctx, 1, AMDGPU_VM_MAX_NUM_CTX, GFP_KERNEL);
> +	r = xa_alloc(&mgr->ctx_handles, id, ctx, AMDGPU_VM_CTX_LIMIT,
> +			GFP_KERNEL);
>   	if (r < 0) {
>   		mutex_unlock(&mgr->lock);
>   		kfree(ctx);
>   		return r;
>   	}
>   
> -	*id = (uint32_t)r;
>   	r = amdgpu_ctx_init(adev, priority, filp, ctx);
>   	if (r) {
> -		idr_remove(&mgr->ctx_handles, *id);
> +		xa_erase(&mgr->ctx_handles, *id);
>   		*id = 0;
>   		kfree(ctx);
>   	}
> @@ -290,7 +290,7 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
>   	struct amdgpu_ctx *ctx;
>   
>   	mutex_lock(&mgr->lock);
> -	ctx = idr_remove(&mgr->ctx_handles, id);
> +	ctx = xa_erase(&mgr->ctx_handles, id);
>   	if (ctx)
>   		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
>   	mutex_unlock(&mgr->lock);
> @@ -310,7 +310,7 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
>   
>   	mgr = &fpriv->ctx_mgr;
>   	mutex_lock(&mgr->lock);
> -	ctx = idr_find(&mgr->ctx_handles, id);
> +	ctx = xa_load(&mgr->ctx_handles, id);
>   	if (!ctx) {
>   		mutex_unlock(&mgr->lock);
>   		return -EINVAL;
> @@ -345,7 +345,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
>   
>   	mgr = &fpriv->ctx_mgr;
>   	mutex_lock(&mgr->lock);
> -	ctx = idr_find(&mgr->ctx_handles, id);
> +	ctx = xa_load(&mgr->ctx_handles, id);
>   	if (!ctx) {
>   		mutex_unlock(&mgr->lock);
>   		return -EINVAL;
> @@ -419,7 +419,7 @@ struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
>   	mgr = &fpriv->ctx_mgr;
>   
>   	mutex_lock(&mgr->lock);
> -	ctx = idr_find(&mgr->ctx_handles, id);
> +	ctx = xa_load(&mgr->ctx_handles, id);
>   	if (ctx)
>   		kref_get(&ctx->refcount);
>   	mutex_unlock(&mgr->lock);
> @@ -533,22 +533,18 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
>   void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
>   {
>   	mutex_init(&mgr->lock);
> -	idr_init(&mgr->ctx_handles);
> +	xa_init_flags(&mgr->ctx_handles, XA_FLAGS_ALLOC1);
>   }
>   
>   void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
>   {
>   	unsigned num_entities = amdgput_ctx_total_num_entities();
>   	struct amdgpu_ctx *ctx;
> -	struct idr *idp;
> -	uint32_t id, i;
> +	unsigned long id, i;
>   	long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
>   
> -	idp = &mgr->ctx_handles;
> -
>   	mutex_lock(&mgr->lock);
> -	idr_for_each_entry(idp, ctx, id) {
> -
> +	xa_for_each(&mgr->ctx_handles, id, ctx) {
>   		if (!ctx->adev) {
>   			mutex_unlock(&mgr->lock);
>   			return;
> @@ -568,13 +564,9 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
>   {
>   	unsigned num_entities = amdgput_ctx_total_num_entities();
>   	struct amdgpu_ctx *ctx;
> -	struct idr *idp;
> -	uint32_t id, i;
> -
> -	idp = &mgr->ctx_handles;
> -
> -	idr_for_each_entry(idp, ctx, id) {
> +	unsigned long id, i;
>   
> +	xa_for_each(&mgr->ctx_handles, id, ctx) {
>   		if (!ctx->adev)
>   			return;
>   
> @@ -591,18 +583,14 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
>   void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
>   {
>   	struct amdgpu_ctx *ctx;
> -	struct idr *idp;
> -	uint32_t id;
> +	unsigned long id;
>   
>   	amdgpu_ctx_mgr_entity_fini(mgr);
>   
> -	idp = &mgr->ctx_handles;
> -
> -	idr_for_each_entry(idp, ctx, id) {
> +	xa_for_each(&mgr->ctx_handles, id, ctx) {
>   		if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
>   			DRM_ERROR("ctx %p is still alive\n", ctx);
>   	}
> -
> -	idr_destroy(&mgr->ctx_handles);
> +	xa_destroy(&mgr->ctx_handles);
>   	mutex_destroy(&mgr->lock);
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
> index b3b012c0a7da..011b1f15308a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
> @@ -55,7 +55,7 @@ struct amdgpu_ctx_mgr {
>   	struct amdgpu_device	*adev;
>   	struct mutex		lock;
>   	/* protected by lock */
> -	struct idr		ctx_handles;
> +	struct xarray		ctx_handles;
>   };
>   
>   extern const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM];
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
> index 1cafe8d83a4d..278b4bd98dcc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
> @@ -57,14 +57,14 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
>   	struct drm_file *file;
>   	struct amdgpu_fpriv *fpriv;
>   	struct amdgpu_ctx *ctx;
> -	uint32_t id;
> +	unsigned long id;
>   
>   	if (!filp)
>   		return -EINVAL;
>   
>   	file = filp->private_data;
>   	fpriv = file->driver_priv;
> -	idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
> +	xa_for_each(&fpriv->ctx_mgr.ctx_handles, id, ctx)
>   		amdgpu_ctx_priority_override(ctx, priority);
>   
>   	fput(filp);

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 13/34] drm/amdgpu: Convert ctx_handles to XArray
  2019-02-25 16:07   ` Christian König
@ 2019-02-25 16:39     ` Matthew Wilcox
  2019-02-25 16:59       ` Koenig, Christian
  0 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-25 16:39 UTC (permalink / raw)
  To: christian.koenig; +Cc: dri-devel

On Mon, Feb 25, 2019 at 05:07:24PM +0100, Christian König wrote:
> > -#define AMDGPU_VM_MAX_NUM_CTX			4096
> > +#define AMDGPU_VM_CTX_LIMIT			XA_LIMIT(0, 4095)
> 
> IIRC we actually use 0 as reserved context value in some places.

That's OK; the ALLOC1 prevents it from using index 0.

You can change it to be XA_LIMIT(1, 4095) if you think that'll be clearer;
it'll be slightly less efficient assembly (a 64-bit mov-immediate instead
of a 32-bit mov-immediate), but it's your driver, so it's up to you.

> > @@ -533,22 +533,18 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
> >   void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
> >   {
> >   	mutex_init(&mgr->lock);
> > -	idr_init(&mgr->ctx_handles);
> > +	xa_init_flags(&mgr->ctx_handles, XA_FLAGS_ALLOC1);
> >   }
> >   void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
> >   {

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 12/34] drm/agp: Convert bo_list_handles to XArray
  2019-02-25 16:06   ` Christian König
@ 2019-02-25 16:39     ` Matthew Wilcox
  0 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-25 16:39 UTC (permalink / raw)
  To: christian.koenig; +Cc: dri-devel

On Mon, Feb 25, 2019 at 05:06:18PM +0100, Christian König wrote:
> In this one there is a typo in the subject line.

Thanks, I'll fix it.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 13/34] drm/amdgpu: Convert ctx_handles to XArray
  2019-02-25 16:39     ` Matthew Wilcox
@ 2019-02-25 16:59       ` Koenig, Christian
  2019-02-25 18:47         ` Matthew Wilcox
  0 siblings, 1 reply; 53+ messages in thread
From: Koenig, Christian @ 2019-02-25 16:59 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

Am 25.02.19 um 17:39 schrieb Matthew Wilcox:
> On Mon, Feb 25, 2019 at 05:07:24PM +0100, Christian König wrote:
>>> -#define AMDGPU_VM_MAX_NUM_CTX			4096
>>> +#define AMDGPU_VM_CTX_LIMIT			XA_LIMIT(0, 4095)
>> IIRC we actually use 0 as reserved context value in some places.
> That's OK; the ALLOC1 prevents it from using index 0.
>
> You can change it to be XA_LIMIT(1, 4095) if you think that'll be clearer;
> it'll be slightly less efficient assembly (a 64-bit mov-immediate instead
> of a 32-bit mov-immediate), but it's your driver, so it's up to you.

A code comment should do as well.

But thinking more about it please DON'T actually change the 
AMDGPU_VM_MAX_NUM_CTX define.

That one needs to be used to calculate the reserved GPU space to map the 
context save area, and I really don't want to deal with a XA_LIMIT in 
that calculation :)

I'm really wondering why that doesn't go up in a boom during compilation....

Christian.

>
>>> @@ -533,22 +533,18 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
>>>    void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
>>>    {
>>>    	mutex_init(&mgr->lock);
>>> -	idr_init(&mgr->ctx_handles);
>>> +	xa_init_flags(&mgr->ctx_handles, XA_FLAGS_ALLOC1);
>>>    }
>>>    void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
>>>    {

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 02/34] drm: Convert aux_idr to XArray
  2019-02-21 18:41 ` [PATCH 02/34] drm: Convert aux_idr " Matthew Wilcox
@ 2019-02-25 17:57   ` Ville Syrjälä
  2019-02-25 18:42     ` Matthew Wilcox
  0 siblings, 1 reply; 53+ messages in thread
From: Ville Syrjälä @ 2019-02-25 17:57 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Thu, Feb 21, 2019 at 10:41:23AM -0800, Matthew Wilcox wrote:
> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>  drivers/gpu/drm/drm_dp_aux_dev.c | 41 +++++++++++++-------------------
>  1 file changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c b/drivers/gpu/drm/drm_dp_aux_dev.c
> index 0e4f25d63fd2..393a32976900 100644
> --- a/drivers/gpu/drm/drm_dp_aux_dev.c
> +++ b/drivers/gpu/drm/drm_dp_aux_dev.c
> @@ -49,8 +49,7 @@ struct drm_dp_aux_dev {
>  
>  #define DRM_AUX_MINORS	256
>  #define AUX_MAX_OFFSET	(1 << 20)
> -static DEFINE_IDR(aux_idr);
> -static DEFINE_MUTEX(aux_idr_mutex);
> +static DEFINE_XARRAY_ALLOC(aux_xa);
>  static struct class *drm_dp_aux_dev_class;
>  static int drm_dev_major = -1;
>  
> @@ -58,19 +57,21 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
>  {
>  	struct drm_dp_aux_dev *aux_dev = NULL;
>  
> -	mutex_lock(&aux_idr_mutex);
> -	aux_dev = idr_find(&aux_idr, index);
> +	xa_lock(&aux_xa);
> +	aux_dev = xa_load(&aux_xa, index);
>  	if (!kref_get_unless_zero(&aux_dev->refcount))
>  		aux_dev = NULL;
> -	mutex_unlock(&aux_idr_mutex);
> +	xa_unlock(&aux_xa);
>  
>  	return aux_dev;
>  }
>  
>  static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
>  {
> +	static u32 next;

Is there a particular reason for that being static?

> +
>  	struct drm_dp_aux_dev *aux_dev;
> -	int index;
> +	int err;
>  
>  	aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
>  	if (!aux_dev)
> @@ -79,15 +80,12 @@ static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
>  	atomic_set(&aux_dev->usecount, 1);
>  	kref_init(&aux_dev->refcount);
>  
> -	mutex_lock(&aux_idr_mutex);
> -	index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
> -				 GFP_KERNEL);
> -	mutex_unlock(&aux_idr_mutex);
> -	if (index < 0) {
> +	err = xa_alloc_cyclic(&aux_xa, &aux_dev->index, aux_dev,
> +			XA_LIMIT(0, DRM_AUX_MINORS), &next, GFP_KERNEL);
> +	if (err < 0) {
>  		kfree(aux_dev);
> -		return ERR_PTR(index);
> +		return ERR_PTR(err);
>  	}
> -	aux_dev->index = index;
>  
>  	return aux_dev;
>  }
> @@ -246,22 +244,19 @@ static const struct file_operations auxdev_fops = {
>  
>  static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
>  {
> -	struct drm_dp_aux_dev *iter, *aux_dev = NULL;
> -	int id;
> +	struct drm_dp_aux_dev *aux_dev;
> +	unsigned long id;
>  
>  	/* don't increase kref count here because this function should only be
>  	 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
>  	 * least one reference - the one that drm_dp_aux_register_devnode
>  	 * created
>  	 */
> -	mutex_lock(&aux_idr_mutex);
> -	idr_for_each_entry(&aux_idr, iter, id) {
> -		if (iter->aux == aux) {
> -			aux_dev = iter;
> +	xa_for_each(&aux_xa, id, aux_dev) {
> +		if (aux_dev->aux == aux)
>  			break;
> -		}
>  	}
> -	mutex_unlock(&aux_idr_mutex);
> +
>  	return aux_dev;
>  }
>  
> @@ -274,9 +269,7 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
>  	if (!aux_dev) /* attach must have failed */
>  		return;
>  
> -	mutex_lock(&aux_idr_mutex);
> -	idr_remove(&aux_idr, aux_dev->index);
> -	mutex_unlock(&aux_idr_mutex);
> +	xa_erase(&aux_xa, aux_dev->index);
>  
>  	atomic_dec(&aux_dev->usecount);
>  	wait_var_event(&aux_dev->usecount, !atomic_read(&aux_dev->usecount));
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 02/34] drm: Convert aux_idr to XArray
  2019-02-25 17:57   ` Ville Syrjälä
@ 2019-02-25 18:42     ` Matthew Wilcox
  2019-02-25 18:50       ` Ville Syrjälä
  0 siblings, 1 reply; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-25 18:42 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: dri-devel

On Mon, Feb 25, 2019 at 07:57:33PM +0200, Ville Syrjälä wrote:
> On Thu, Feb 21, 2019 at 10:41:23AM -0800, Matthew Wilcox wrote:
> > @@ -49,8 +49,7 @@ struct drm_dp_aux_dev {
> >  
> >  #define DRM_AUX_MINORS	256
> >  #define AUX_MAX_OFFSET	(1 << 20)
> > -static DEFINE_IDR(aux_idr);
> > -static DEFINE_MUTEX(aux_idr_mutex);
> > +static DEFINE_XARRAY_ALLOC(aux_xa);
> >  static struct class *drm_dp_aux_dev_class;
> >  static int drm_dev_major = -1;
[...]
> >  static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
> >  {
> > +	static u32 next;
> 
> Is there a particular reason for that being static?

It needs to maintain its value between function calls so that we know
where to start allocating from the next time we call xa_alloc_cyclic().
It can either live here with a short name, or we could put it at file
scope with a descriptive name (probably aux_xa_next).  It's up to you
which you think is better; it's your driver.

The IDR embedded the 'next' value in the struct idr, but that was
overhead paid by all users of the IDR rather than the very few that
called idr_alloc_cyclic().

> > +	err = xa_alloc_cyclic(&aux_xa, &aux_dev->index, aux_dev,
> > +			XA_LIMIT(0, DRM_AUX_MINORS), &next, GFP_KERNEL);
> > +	if (err < 0) {
> >  		kfree(aux_dev);

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 13/34] drm/amdgpu: Convert ctx_handles to XArray
  2019-02-25 16:59       ` Koenig, Christian
@ 2019-02-25 18:47         ` Matthew Wilcox
  0 siblings, 0 replies; 53+ messages in thread
From: Matthew Wilcox @ 2019-02-25 18:47 UTC (permalink / raw)
  To: Koenig, Christian; +Cc: dri-devel

On Mon, Feb 25, 2019 at 04:59:55PM +0000, Koenig, Christian wrote:
> Am 25.02.19 um 17:39 schrieb Matthew Wilcox:
> > On Mon, Feb 25, 2019 at 05:07:24PM +0100, Christian König wrote:
> >>> -#define AMDGPU_VM_MAX_NUM_CTX			4096
> >>> +#define AMDGPU_VM_CTX_LIMIT			XA_LIMIT(0, 4095)
> >> IIRC we actually use 0 as reserved context value in some places.
> > That's OK; the ALLOC1 prevents it from using index 0.
> >
> > You can change it to be XA_LIMIT(1, 4095) if you think that'll be clearer;
> > it'll be slightly less efficient assembly (a 64-bit mov-immediate instead
> > of a 32-bit mov-immediate), but it's your driver, so it's up to you.
> 
> A code comment should do as well.
> 
> But thinking more about it please DON'T actually change the 
> AMDGPU_VM_MAX_NUM_CTX define.
> 
> That one needs to be used to calculate the reserved GPU space to map the 
> context save area, and I really don't want to deal with a XA_LIMIT in 
> that calculation :)
> 
> I'm really wondering why that doesn't go up in a boom during compilation....

Maybe that code isn't merged in Linus' tree yet?  I was basing this on
5.0-rc5 and there's no mention of AMDGPU_VM_MAX_NUM_CTX outside these
usages.  If I'd seen another usage, I wouldn't've changed it.

The rebasing I'm going to have to do on -rc1 is going to be epically
challenging.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 02/34] drm: Convert aux_idr to XArray
  2019-02-25 18:42     ` Matthew Wilcox
@ 2019-02-25 18:50       ` Ville Syrjälä
  0 siblings, 0 replies; 53+ messages in thread
From: Ville Syrjälä @ 2019-02-25 18:50 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: dri-devel

On Mon, Feb 25, 2019 at 10:42:46AM -0800, Matthew Wilcox wrote:
> On Mon, Feb 25, 2019 at 07:57:33PM +0200, Ville Syrjälä wrote:
> > On Thu, Feb 21, 2019 at 10:41:23AM -0800, Matthew Wilcox wrote:
> > > @@ -49,8 +49,7 @@ struct drm_dp_aux_dev {
> > >  
> > >  #define DRM_AUX_MINORS	256
> > >  #define AUX_MAX_OFFSET	(1 << 20)
> > > -static DEFINE_IDR(aux_idr);
> > > -static DEFINE_MUTEX(aux_idr_mutex);
> > > +static DEFINE_XARRAY_ALLOC(aux_xa);
> > >  static struct class *drm_dp_aux_dev_class;
> > >  static int drm_dev_major = -1;
> [...]
> > >  static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
> > >  {
> > > +	static u32 next;
> > 
> > Is there a particular reason for that being static?
> 
> It needs to maintain its value between function calls so that we know
> where to start allocating from the next time we call xa_alloc_cyclic().
> It can either live here with a short name, or we could put it at file
> scope with a descriptive name (probably aux_xa_next).  It's up to you
> which you think is better; it's your driver.

File scope would seem a bit more clear to me. I'm slightly worried
someone might do some cleanup here and drop the static without
thinking. Alterntively a short comment would probably suffice.

> 
> The IDR embedded the 'next' value in the struct idr, but that was
> overhead paid by all users of the IDR rather than the very few that
> called idr_alloc_cyclic().
> 
> > > +	err = xa_alloc_cyclic(&aux_xa, &aux_dev->index, aux_dev,
> > > +			XA_LIMIT(0, DRM_AUX_MINORS), &next, GFP_KERNEL);
> > > +	if (err < 0) {
> > >  		kfree(aux_dev);

-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2019-02-25 18:50 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-21 18:41 [PATCH 00/34] Convert DRM to XArray Matthew Wilcox
2019-02-21 18:41 ` [PATCH 01/34] drm: Convert drm_minors_idr " Matthew Wilcox
2019-02-22  9:11   ` Daniel Vetter
2019-02-22  9:55     ` Daniel Vetter
2019-02-22 15:13     ` Matthew Wilcox
2019-02-21 18:41 ` [PATCH 02/34] drm: Convert aux_idr " Matthew Wilcox
2019-02-25 17:57   ` Ville Syrjälä
2019-02-25 18:42     ` Matthew Wilcox
2019-02-25 18:50       ` Ville Syrjälä
2019-02-21 18:41 ` [PATCH 03/34] drm: Convert object_name_idr " Matthew Wilcox
2019-02-22  9:17   ` Daniel Vetter
2019-02-21 18:41 ` [PATCH 04/34] drm: Convert object_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 05/34] drm: Convert syncobj_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 06/34] drm: Convert magic_map " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 07/34] drm: Convert lessee_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 08/34] drm: Remove linked lists for lessees Matthew Wilcox
2019-02-21 18:41 ` [PATCH 09/34] drm: Convert ctx_idr to XArray Matthew Wilcox
2019-02-21 18:41 ` [PATCH 10/34] drm: Convert tile_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 11/34] drm: Convert crtc_idr " Matthew Wilcox
2019-02-22  9:40   ` Daniel Vetter
2019-02-22 15:32     ` Matthew Wilcox
2019-02-22 17:12       ` Daniel Vetter
2019-02-21 18:41 ` [PATCH 12/34] drm/agp: Convert bo_list_handles " Matthew Wilcox
2019-02-25 16:06   ` Christian König
2019-02-25 16:39     ` Matthew Wilcox
2019-02-21 18:41 ` [PATCH 13/34] drm/amdgpu: Convert ctx_handles " Matthew Wilcox
2019-02-25 16:07   ` Christian König
2019-02-25 16:39     ` Matthew Wilcox
2019-02-25 16:59       ` Koenig, Christian
2019-02-25 18:47         ` Matthew Wilcox
2019-02-21 18:41 ` [PATCH 14/34] drm/amdgpu: Convert pasid_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 15/34] drm/amdkfd: Convert event_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 16/34] drm/amdkfd: Convert alloc_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 17/34] drm/etnaviv: Convert fence_idr " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 18/34] drm/i915: Convert handles_vma " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 19/34] drm/i915: Convert spt_tree " Matthew Wilcox
2019-02-21 18:41 ` [PATCH 20/34] drm/i915: Convert page_track_tree " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 21/34] drm/i915: Convert get_page " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 22/34] drm/i915: Convert object_idr to IDA Matthew Wilcox
2019-02-21 18:42 ` [PATCH 23/34] drm/i915: Convert context_idr to XArray Matthew Wilcox
2019-02-21 18:42 ` [PATCH 24/34] drm/i915: Convert metrics_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 25/34] drm/i915: Convert vgpus_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 26/34] drm/qxl: Convert release_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 27/34] drm/qxl: Convert surf_id_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 28/34] drm/tegra: Convert contexts IDR " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 29/34] drm/vc4: Convert perfmon " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 30/34] drm/sis: Convert object_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 31/34] drm/vgem: Convert fence_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 32/34] drm/via: Convert object_idr " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 33/34] drm/vmwgfx: Convert base IDR " Matthew Wilcox
2019-02-21 18:42 ` [PATCH 34/34] drm/vmwgfx: Convert res_idr " Matthew Wilcox
2019-02-22  9:54 ` [PATCH 00/34] Convert DRM " Daniel Vetter
2019-02-24  4:21   ` Matthew Wilcox

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.