From: John Harrison <John.C.Harrison@Intel.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: Intel-GFX@Lists.FreeDesktop.Org
Subject: Re: [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility
Date: Wed, 26 Nov 2014 12:23:43 +0000 [thread overview]
Message-ID: <5475C64F.7090401@Intel.com> (raw)
In-Reply-To: <20141126091915.GF32117@phenom.ffwll.local>
On 26/11/2014 09:19, Daniel Vetter wrote:
> On Mon, Nov 24, 2014 at 06:49:33PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The next patches in the series convert some display related seqno usage to
>> request structure usage. However, the request dereference introduced must be
>> done from interrupt context. As the dereference potentially involves freeing the
>> request structure and thus calling lots of non-interrupt friendly code, this
>> poses a problem.
>>
>> The solution is to add an IRQ friendly version of the dereference function. All
>> this does is to add the request structure to a 'delayed free' list and return.
>> The retire code, which is run periodically, then processes this list and does
>> the actual dereferencing of the request structures.
>>
>> v2: Added a count to allow for multiple IRQ dereferences of the same request at
>> a time.
>>
>> For: VIZ-4377
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_drv.h | 7 +++++++
>> drivers/gpu/drm/i915/i915_gem.c | 33 +++++++++++++++++++++++++++++++
>> drivers/gpu/drm/i915/intel_lrc.c | 2 ++
>> drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++
>> drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++
>> 5 files changed, 46 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 149532e6..e9b01e1 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2025,6 +2025,10 @@ struct drm_i915_gem_request {
>> struct drm_i915_file_private *file_priv;
>> /** file_priv list entry for this request */
>> struct list_head client_list;
>> +
>> + /** deferred free list for dereferencing from IRQ context */
>> + struct list_head delay_free_list;
>> + uint32_t delay_free_count;
>> };
>>
>> void i915_gem_request_free(struct kref *req_ref);
>> @@ -2050,9 +2054,12 @@ i915_gem_request_reference(struct drm_i915_gem_request *req)
>> static inline void
>> i915_gem_request_unreference(struct drm_i915_gem_request *req)
>> {
>> + WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
>> kref_put(&req->ref, i915_gem_request_free);
>> }
>>
>> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req);
>> +
>> static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
>> struct drm_i915_gem_request *src)
>> {
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index 8e2c530..b62b9d9 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2732,6 +2732,19 @@ void i915_gem_reset(struct drm_device *dev)
>> i915_gem_restore_fences(dev);
>> }
>>
>> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
>> +{
>> + struct intel_engine_cs *ring = req->ring;
>> + unsigned long flags;
>> +
>> + /* Need to add the req to a deferred dereference list to be processed
>> + * outside of interrupt time */
>> + spin_lock_irqsave(&ring->reqlist_lock, flags);
>> + if (req->delay_free_count++ == 0)
>> + list_add_tail(&req->delay_free_list, &ring->delayed_free_list);
>> + spin_unlock_irqrestore(&ring->reqlist_lock, flags);
>> +}
>> +
>> /**
>> * This function clears the request list as sequence numbers are passed.
>> */
>> @@ -2806,6 +2819,25 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>> ring->trace_irq_seqno = 0;
>> }
>>
>> + while (!list_empty(&ring->delayed_free_list)) {
> This needs locking. It might work as-is but it's definitely too tricky to
> be worth it.
> -Daniel
The manipulation of the list is locked, only this test is unlocked. Do
you really need to lock when testing for empty? Nothing can be removing
items from the list although something could be asynchronously adding
them. If the 'head->next == head' test goes wrong because head or next
is being written to, it can't deference a dodgy pointer. It can only
return an incorrect 'empty' in which case the clean up is delayed until
later. An incorrect 'not-empty' is not possible.
>> + struct drm_i915_gem_request *request;
>> + unsigned long flags;
>> + uint32_t count;
>> +
>> + request = list_first_entry(&ring->delayed_free_list,
>> + struct drm_i915_gem_request,
>> + delay_free_list);
>> +
>> + spin_lock_irqsave(&request->ring->reqlist_lock, flags);
>> + list_del(&request->delay_free_list);
>> + count = request->delay_free_count;
>> + request->delay_free_count = 0;
>> + spin_unlock_irqrestore(&request->ring->reqlist_lock, flags);
>> +
>> + while (count-- > 0)
>> + i915_gem_request_unreference(request);
>> + }
>> +
>> WARN_ON(i915_verify_lists(ring->dev));
>> }
>>
>> @@ -5007,6 +5039,7 @@ init_ring_lists(struct intel_engine_cs *ring)
>> {
>> INIT_LIST_HEAD(&ring->active_list);
>> INIT_LIST_HEAD(&ring->request_list);
>> + INIT_LIST_HEAD(&ring->delayed_free_list);
>> }
>>
>> void i915_init_vm(struct drm_i915_private *dev_priv,
>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
>> index 6177179..09f4588 100644
>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>> @@ -1381,7 +1381,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
>> ring->dev = dev;
>> INIT_LIST_HEAD(&ring->active_list);
>> INIT_LIST_HEAD(&ring->request_list);
>> + spin_lock_init(&ring->reqlist_lock);
>> init_waitqueue_head(&ring->irq_queue);
>> + INIT_LIST_HEAD(&ring->delayed_free_list);
>>
>> INIT_LIST_HEAD(&ring->execlist_queue);
>> INIT_LIST_HEAD(&ring->execlist_retired_req_list);
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> index b9d0d29..e3082af 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> @@ -1807,6 +1807,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
>> ring->dev = dev;
>> INIT_LIST_HEAD(&ring->active_list);
>> INIT_LIST_HEAD(&ring->request_list);
>> + spin_lock_init(&ring->reqlist_lock);
>> + INIT_LIST_HEAD(&ring->delayed_free_list);
>> INIT_LIST_HEAD(&ring->execlist_queue);
>> ringbuf->size = 32 * PAGE_SIZE;
>> ringbuf->ring = ring;
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> index 2a84bd9..cd1a9f9 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> @@ -263,6 +263,8 @@ struct intel_engine_cs {
>> * outstanding.
>> */
>> struct list_head request_list;
>> + spinlock_t reqlist_lock;
>> + struct list_head delayed_free_list;
>>
>> /**
>> * Do we have some not yet emitted requests outstanding?
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2014-11-26 12:23 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 02/28] drm/i915: Add reference count to request structure John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 03/28] drm/i915: Add helper functions to aid seqno -> request transition John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 04/28] drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 05/28] drm/i915: Convert i915_gem_ring_throttle to use requests John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits John.C.Harrison
2014-11-26 12:27 ` John Harrison
2014-11-26 13:14 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 07/28] drm/i915: Remove 'outstanding_lazy_seqno' John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 08/28] drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 09/28] drm/i915: Convert 'last_flip_req' to be a request not a seqno John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 10/28] drm/i915: Convert i915_wait_seqno to i915_wait_request John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility John.C.Harrison
2014-11-26 9:19 ` Daniel Vetter
2014-11-26 12:23 ` John Harrison [this message]
2014-11-26 12:35 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request John.C.Harrison
2014-11-26 9:23 ` Daniel Vetter
2014-11-26 12:12 ` John Harrison
2014-11-26 12:49 ` Daniel Vetter
2014-11-26 15:21 ` John Harrison
2014-11-26 18:22 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 13/28] drm/i915: Convert __wait_seqno() to __wait_request() John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 14/28] drm/i915: Remove obsolete seqno parameter from 'i915_add_request' John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request' John.C.Harrison
2014-11-26 13:07 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 16/28] drm/i915: Convert trace functions from seqno to request John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos John.C.Harrison
2014-11-26 13:24 ` Daniel Vetter
2014-11-26 14:12 ` John Harrison
2014-11-26 14:31 ` Chris Wilson
2014-11-26 14:42 ` Daniel Vetter
2014-11-26 14:58 ` John Harrison
2014-11-26 18:23 ` Daniel Vetter
2014-11-26 18:25 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 18/28] drm/i915: Convert 'ring_idle()' to use requests not seqnos John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 19/28] drm/i915: Connect requests to rings at creation not submission John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed' John.C.Harrison
2014-11-26 13:42 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring' John.C.Harrison
2014-11-26 13:43 ` Daniel Vetter
2014-11-28 17:49 ` John Harrison
2014-11-28 18:06 ` Daniel Vetter
2014-12-01 12:44 ` John Harrison
2014-12-01 16:44 ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 22/28] drm/i915: Cache request completion status John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 23/28] drm/i915: Zero fill the request structure John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 24/28] drm/i915: Spinlock protection for request list John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 25/28] drm/i915: Interrupt driven request completion John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 26/28] drm/i915: Remove obsolete parameter to i915_gem_request_completed() John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 27/28] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 28/28] drm/i915: Additional request structure tracing John.C.Harrison
2014-11-25 11:59 ` [PATCH v3 00/28] Replace seqno values with request structures Daniel, Thomas
2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
2014-12-05 13:49 ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
2014-12-05 20:37 ` Daniel Vetter
2014-12-05 13:49 ` [PATCH v4 2/4] drm/i915: Zero fill the request structure John.C.Harrison
2014-12-05 13:49 ` [PATCH v4 3/4] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
2014-12-05 13:49 ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
2014-12-05 19:01 ` shuang.he
2014-12-05 20:48 ` Daniel Vetter
2014-12-05 20:50 ` Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5475C64F.7090401@Intel.com \
--to=john.c.harrison@intel.com \
--cc=Intel-GFX@Lists.FreeDesktop.Org \
--cc=daniel@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox