From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> We soon want to start answering questions like how much GPU time is the context belonging to a client which exited still using. To enable this we start tracking all context belonging to a client on a separate list, plus we make contexts take a reference on their clients file_priv. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 21 ++++++++++++++++++- .../gpu/drm/i915/gem/i915_gem_context_types.h | 6 ++++++ drivers/gpu/drm/i915/i915_drm_client.c | 3 +++ drivers/gpu/drm/i915/i915_drm_client.h | 5 +++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index ba3c29a01535..ba8ccc754f20 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -301,8 +301,18 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx) static void i915_gem_context_free(struct i915_gem_context *ctx) { + struct i915_drm_client *client = ctx->client; + GEM_BUG_ON(!i915_gem_context_is_closed(ctx)); + if (client) { + spin_lock(&client->ctx_lock); + list_del_rcu(&ctx->client_link); + spin_unlock(&client->ctx_lock); + + i915_drm_client_put(client); + } + spin_lock(&ctx->i915->gem.contexts.lock); list_del(&ctx->link); spin_unlock(&ctx->i915->gem.contexts.lock); @@ -772,6 +782,7 @@ static int gem_context_register(struct i915_gem_context *ctx, struct drm_i915_file_private *fpriv, u32 *id) { + struct i915_drm_client *client; struct i915_address_space *vm; int ret; @@ -789,9 +800,17 @@ static int gem_context_register(struct i915_gem_context *ctx, /* And finally expose ourselves to userspace via the idr */ ret = xa_alloc(&fpriv->context_xa, id, ctx, xa_limit_32b, GFP_KERNEL); - if (ret) + if (ret) { put_pid(fetch_and_zero(&ctx->pid)); + goto out; + } + ctx->client = client = i915_drm_client_get(fpriv->client); + spin_lock(&client->ctx_lock); + list_add_tail_rcu(&ctx->client_link, &client->ctx_list); + spin_unlock(&client->ctx_lock); + +out: return ret; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h index 017ca803ab47..879824159646 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h @@ -104,6 +104,12 @@ struct i915_gem_context { struct list_head link; struct llist_node free_link; + /** client: struct i915_drm_client */ + struct i915_drm_client *client; + + /** link: &fpriv.context_list */ + struct list_head client_link; + /** * @ref: reference count * diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c index 666ec67c77e9..195777b95891 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.c +++ b/drivers/gpu/drm/i915/i915_drm_client.c @@ -111,6 +111,9 @@ i915_drm_client_add(struct i915_drm_clients *clients, struct task_struct *task) return ERR_PTR(-ENOMEM); kref_init(&client->kref); + spin_lock_init(&client->ctx_lock); + INIT_LIST_HEAD(&client->ctx_list); + client->clients = clients; ret = xa_alloc_cyclic(&clients->xarray, &client->id, client, diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h index 2c692345bc4e..16d8db075a7d 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.h +++ b/drivers/gpu/drm/i915/i915_drm_client.h @@ -10,9 +10,11 @@ #include <linux/device.h> #include <linux/kobject.h> #include <linux/kref.h> +#include <linux/list.h> #include <linux/pid.h> #include <linux/rcupdate.h> #include <linux/sched.h> +#include <linux/spinlock.h> #include <linux/xarray.h> struct i915_drm_clients { @@ -30,6 +32,9 @@ struct i915_drm_client { char *name; bool closed; + spinlock_t ctx_lock; + struct list_head ctx_list; + struct i915_drm_clients *clients; struct kobject *root; -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx