Commit c100777c authored by Tvrtko Ursulin's avatar Tvrtko Ursulin Committed by Chris Wilson

drm/i915: Switch context id allocation directly to xarray

IDR internally uses xarray so we can use it directly which simplifies our
code by removing the need to do external locking.
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20191224095920.2386297-1-chris@chris-wilson.co.uk
parent 30084b14
...@@ -760,12 +760,6 @@ void i915_gem_driver_release__contexts(struct drm_i915_private *i915) ...@@ -760,12 +760,6 @@ void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
flush_work(&i915->gem.contexts.free_work); flush_work(&i915->gem.contexts.free_work);
} }
static int context_idr_cleanup(int id, void *p, void *data)
{
context_close(p);
return 0;
}
static int vm_idr_cleanup(int id, void *p, void *data) static int vm_idr_cleanup(int id, void *p, void *data)
{ {
i915_vm_put(p); i915_vm_put(p);
...@@ -773,7 +767,8 @@ static int vm_idr_cleanup(int id, void *p, void *data) ...@@ -773,7 +767,8 @@ static int vm_idr_cleanup(int id, void *p, void *data)
} }
static int gem_context_register(struct i915_gem_context *ctx, static int gem_context_register(struct i915_gem_context *ctx,
struct drm_i915_file_private *fpriv) struct drm_i915_file_private *fpriv,
u32 *id)
{ {
struct i915_address_space *vm; struct i915_address_space *vm;
int ret; int ret;
...@@ -791,14 +786,10 @@ static int gem_context_register(struct i915_gem_context *ctx, ...@@ -791,14 +786,10 @@ static int gem_context_register(struct i915_gem_context *ctx,
current->comm, pid_nr(ctx->pid)); current->comm, pid_nr(ctx->pid));
/* And finally expose ourselves to userspace via the idr */ /* And finally expose ourselves to userspace via the idr */
mutex_lock(&fpriv->context_idr_lock); ret = xa_alloc(&fpriv->context_xa, id, ctx, xa_limit_32b, GFP_KERNEL);
ret = idr_alloc(&fpriv->context_idr, ctx, 0, 0, GFP_KERNEL); if (ret)
mutex_unlock(&fpriv->context_idr_lock); put_pid(fetch_and_zero(&ctx->pid));
if (ret >= 0)
goto out;
put_pid(fetch_and_zero(&ctx->pid));
out:
return ret; return ret;
} }
...@@ -808,11 +799,11 @@ int i915_gem_context_open(struct drm_i915_private *i915, ...@@ -808,11 +799,11 @@ int i915_gem_context_open(struct drm_i915_private *i915,
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
int err; int err;
u32 id;
mutex_init(&file_priv->context_idr_lock); xa_init_flags(&file_priv->context_xa, XA_FLAGS_ALLOC);
mutex_init(&file_priv->vm_idr_lock);
idr_init(&file_priv->context_idr); mutex_init(&file_priv->vm_idr_lock);
idr_init_base(&file_priv->vm_idr, 1); idr_init_base(&file_priv->vm_idr, 1);
ctx = i915_gem_create_context(i915, 0); ctx = i915_gem_create_context(i915, 0);
...@@ -821,21 +812,19 @@ int i915_gem_context_open(struct drm_i915_private *i915, ...@@ -821,21 +812,19 @@ int i915_gem_context_open(struct drm_i915_private *i915,
goto err; goto err;
} }
err = gem_context_register(ctx, file_priv); err = gem_context_register(ctx, file_priv, &id);
if (err < 0) if (err < 0)
goto err_ctx; goto err_ctx;
GEM_BUG_ON(err > 0); GEM_BUG_ON(id);
return 0; return 0;
err_ctx: err_ctx:
context_close(ctx); context_close(ctx);
err: err:
idr_destroy(&file_priv->vm_idr); idr_destroy(&file_priv->vm_idr);
idr_destroy(&file_priv->context_idr); xa_destroy(&file_priv->context_xa);
mutex_destroy(&file_priv->vm_idr_lock); mutex_destroy(&file_priv->vm_idr_lock);
mutex_destroy(&file_priv->context_idr_lock);
return err; return err;
} }
...@@ -843,10 +832,12 @@ void i915_gem_context_close(struct drm_file *file) ...@@ -843,10 +832,12 @@ void i915_gem_context_close(struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
struct drm_i915_private *i915 = file_priv->dev_priv; struct drm_i915_private *i915 = file_priv->dev_priv;
struct i915_gem_context *ctx;
unsigned long idx;
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); xa_for_each(&file_priv->context_xa, idx, ctx)
idr_destroy(&file_priv->context_idr); context_close(ctx);
mutex_destroy(&file_priv->context_idr_lock); xa_destroy(&file_priv->context_xa);
idr_for_each(&file_priv->vm_idr, vm_idr_cleanup, NULL); idr_for_each(&file_priv->vm_idr, vm_idr_cleanup, NULL);
idr_destroy(&file_priv->vm_idr); idr_destroy(&file_priv->vm_idr);
...@@ -2187,6 +2178,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, ...@@ -2187,6 +2178,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_context_create_ext *args = data; struct drm_i915_gem_context_create_ext *args = data;
struct create_ext ext_data; struct create_ext ext_data;
int ret; int ret;
u32 id;
if (!DRIVER_CAPS(i915)->has_logical_contexts) if (!DRIVER_CAPS(i915)->has_logical_contexts)
return -ENODEV; return -ENODEV;
...@@ -2218,11 +2210,11 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, ...@@ -2218,11 +2210,11 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
goto err_ctx; goto err_ctx;
} }
ret = gem_context_register(ext_data.ctx, ext_data.fpriv); ret = gem_context_register(ext_data.ctx, ext_data.fpriv, &id);
if (ret < 0) if (ret < 0)
goto err_ctx; goto err_ctx;
args->ctx_id = ret; args->ctx_id = id;
DRM_DEBUG("HW context %d created\n", args->ctx_id); DRM_DEBUG("HW context %d created\n", args->ctx_id);
return 0; return 0;
...@@ -2245,11 +2237,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, ...@@ -2245,11 +2237,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
if (!args->ctx_id) if (!args->ctx_id)
return -ENOENT; return -ENOENT;
if (mutex_lock_interruptible(&file_priv->context_idr_lock)) ctx = xa_erase(&file_priv->context_xa, args->ctx_id);
return -EINTR;
ctx = idr_remove(&file_priv->context_idr, args->ctx_id);
mutex_unlock(&file_priv->context_idr_lock);
if (!ctx) if (!ctx)
return -ENOENT; return -ENOENT;
......
...@@ -77,12 +77,13 @@ live_context(struct drm_i915_private *i915, struct file *file) ...@@ -77,12 +77,13 @@ live_context(struct drm_i915_private *i915, struct file *file)
{ {
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
int err; int err;
u32 id;
ctx = i915_gem_create_context(i915, 0); ctx = i915_gem_create_context(i915, 0);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return ctx; return ctx;
err = gem_context_register(ctx, to_drm_file(file)->driver_priv); err = gem_context_register(ctx, to_drm_file(file)->driver_priv, &id);
if (err < 0) if (err < 0)
goto err_ctx; goto err_ctx;
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/dma-resv.h> #include <linux/dma-resv.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/stackdepot.h> #include <linux/stackdepot.h>
#include <linux/xarray.h>
#include <drm/intel-gtt.h> #include <drm/intel-gtt.h>
#include <drm/drm_legacy.h> /* for struct drm_dma_handle */ #include <drm/drm_legacy.h> /* for struct drm_dma_handle */
...@@ -201,8 +202,7 @@ struct drm_i915_file_private { ...@@ -201,8 +202,7 @@ struct drm_i915_file_private {
struct list_head request_list; struct list_head request_list;
} mm; } mm;
struct idr context_idr; struct xarray context_xa;
struct mutex context_idr_lock; /* guards context_idr */
struct idr vm_idr; struct idr vm_idr;
struct mutex vm_idr_lock; /* guards vm_idr */ struct mutex vm_idr_lock; /* guards vm_idr */
...@@ -1889,7 +1889,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags) ...@@ -1889,7 +1889,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags)
static inline struct i915_gem_context * static inline struct i915_gem_context *
__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id) __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->context_xa, id);
} }
static inline struct i915_gem_context * static inline struct i915_gem_context *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment