Skip to content

Commit

Permalink
drm/i915: Drop spinlocks around adding to the client request list
Browse files Browse the repository at this point in the history
Adding to the tail of the client request list as the only other user is
in the throttle ioctl that iterates forwards over the list. It only
needs protection against deletion of a request as it reads it, it simply
won't see a new request added to the end of the list, or it would be too
early and rejected. We can further reduce the number of spinlocks
required when throttling by removing stale requests from the client_list
as we throttle.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170302122525.19675-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Mar 2, 2017
1 parent 5be6e33 commit c8659ef
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 44 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
mutex_lock(&dev->struct_mutex);
request = list_first_entry_or_null(&file_priv->mm.request_list,
struct drm_i915_gem_request,
client_list);
client_link);
rcu_read_lock();
task = pid_task(request && request->ctx->pid ?
request->ctx->pid : file->pid,
Expand Down
14 changes: 6 additions & 8 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3666,16 +3666,14 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
return -EIO;

spin_lock(&file_priv->mm.lock);
list_for_each_entry(request, &file_priv->mm.request_list, client_list) {
list_for_each_entry(request, &file_priv->mm.request_list, client_link) {
if (time_after_eq(request->emitted_jiffies, recent_enough))
break;

/*
* Note that the request might not have been submitted yet.
* In which case emitted_jiffies will be zero.
*/
if (!request->emitted_jiffies)
continue;
if (target) {
list_del(&target->client_link);
target->file_priv = NULL;
}

target = request;
}
Expand Down Expand Up @@ -4734,7 +4732,7 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
* file_priv.
*/
spin_lock(&file_priv->mm.lock);
list_for_each_entry(request, &file_priv->mm.request_list, client_list)
list_for_each_entry(request, &file_priv->mm.request_list, client_link)
request->file_priv = NULL;
spin_unlock(&file_priv->mm.lock);

Expand Down
14 changes: 10 additions & 4 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,14 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
return vma;
}

static void
add_to_client(struct drm_i915_gem_request *req,
struct drm_file *file)
{
req->file_priv = file->driver_priv;
list_add_tail(&req->client_link, &req->file_priv->mm.request_list);
}

static int
execbuf_submit(struct i915_execbuffer_params *params,
struct drm_i915_gem_execbuffer2 *args,
Expand Down Expand Up @@ -1772,10 +1780,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
*/
params->request->batch = params->batch;

ret = i915_gem_request_add_to_client(params->request, file);
if (ret)
goto err_request;

/*
* Save assorted stuff away to pass through to *_submission().
* NB: This data should be 'persistent' and not local as it will
Expand All @@ -1793,6 +1797,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
ret = execbuf_submit(params, args, &eb->vmas);
err_request:
__i915_add_request(params->request, ret == 0);
add_to_client(params->request, file);

if (out_fence) {
if (ret == 0) {
fd_install(out_fence_fd, out_fence->file);
Expand Down
34 changes: 6 additions & 28 deletions drivers/gpu/drm/i915/i915_gem_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,42 +82,20 @@ const struct dma_fence_ops i915_fence_ops = {
.release = i915_fence_release,
};

int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
struct drm_file *file)
{
struct drm_i915_private *dev_private;
struct drm_i915_file_private *file_priv;

WARN_ON(!req || !file || req->file_priv);

if (!req || !file)
return -EINVAL;

if (req->file_priv)
return -EINVAL;

dev_private = req->i915;
file_priv = file->driver_priv;

spin_lock(&file_priv->mm.lock);
req->file_priv = file_priv;
list_add_tail(&req->client_list, &file_priv->mm.request_list);
spin_unlock(&file_priv->mm.lock);

return 0;
}

static inline void
i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
{
struct drm_i915_file_private *file_priv = request->file_priv;
struct drm_i915_file_private *file_priv;

file_priv = request->file_priv;
if (!file_priv)
return;

spin_lock(&file_priv->mm.lock);
list_del(&request->client_list);
request->file_priv = NULL;
if (request->file_priv) {
list_del(&request->client_link);
request->file_priv = NULL;
}
spin_unlock(&file_priv->mm.lock);
}

Expand Down
4 changes: 1 addition & 3 deletions drivers/gpu/drm/i915/i915_gem_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ struct drm_i915_gem_request {

struct drm_i915_file_private *file_priv;
/** file_priv list entry for this request */
struct list_head client_list;
struct list_head client_link;
};

extern const struct dma_fence_ops i915_fence_ops;
Expand All @@ -193,8 +193,6 @@ static inline bool dma_fence_is_i915(const struct dma_fence *fence)
struct drm_i915_gem_request * __must_check
i915_gem_request_alloc(struct intel_engine_cs *engine,
struct i915_gem_context *ctx);
int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
struct drm_file *file);
void i915_gem_request_retire_upto(struct drm_i915_gem_request *req);

static inline struct drm_i915_gem_request *
Expand Down

0 comments on commit c8659ef

Please sign in to comment.