From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v3] drm/i915: Only report a wakeup if the waiter was truly asleep
Date: Fri, 7 Apr 2017 09:23:26 +0100 [thread overview]
Message-ID: <cb78cd6f-ba59-e0f3-a874-37b1f03a1416@linux.intel.com> (raw)
In-Reply-To: <33500aec-54a4-e1da-0a7c-0bc027c92267@linux.intel.com>
On 06/04/2017 18:40, Tvrtko Ursulin wrote:
> On 06/04/2017 10:30, Chris Wilson wrote:
>> If we attempt to wake up a waiter, who is currently checking the seqno
>> it will be in the TASK_INTERRUPTIBLE state and ttwu will report success.
>> However, it is actually awake and functioning -- so delay reporting the
>> actual wake up until it sleeps.
>>
>> v2: Defend against !CONFIG_SMP
>> v3: Don't filter out calls to wake_up_process
>>
>> References: https://bugs.freedesktop.org/show_bug.cgi?id=100007
>> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_breadcrumbs.c | 18 ++++++++++++++++--
>> drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++++
>> 2 files changed, 20 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c
>> b/drivers/gpu/drm/i915/intel_breadcrumbs.c
>> index 9ccbf26124c6..808d3a3cda0a 100644
>> --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
>> +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
>> @@ -27,6 +27,12 @@
>>
>> #include "i915_drv.h"
>>
>> +#ifdef CONFIG_SMP
>> +#define task_asleep(tsk) (!(tsk)->on_cpu)
>> +#else
>> +#define task_asleep(tsk) ((tsk) != current)
>> +#endif
>
> It really bothers to fish into this low level info which probably isn't
> intended to be used from the outside.
>
>> +
>> static unsigned int __intel_breadcrumbs_wakeup(struct
>> intel_breadcrumbs *b)
>> {
>> struct intel_wait *wait;
>> @@ -37,8 +43,16 @@ static unsigned int
>> __intel_breadcrumbs_wakeup(struct intel_breadcrumbs *b)
>> wait = b->irq_wait;
>> if (wait) {
>> result = ENGINE_WAKEUP_WAITER;
>> - if (wake_up_process(wait->tsk))
>> +
>> + /* Be careful not to report a successful wakeup if the waiter
>> + * is currently processing the seqno, where it will have
>> + * already called set_task_state(TASK_INTERRUPTIBLE).
>> + */
>> + if (task_asleep(wait->tsk))
>> result |= ENGINE_WAKEUP_ASLEEP;
>
> And this still has the problem of not being atomic between reporting the
> two flags. So the reported status can be false which also bothers me.
>
> I will need to take some more time thinking about this.
Warning, the idea below is potentially unrefined! :)
How about a scheme where on wake_up we would atomic_inc our own wakeup
counter, and then the signaller keeps atomic_dec_and_test one item at a
time until it has consumed all the wakeups? The code in
intel_breadcrumbs_hangcheck only declares a missed breadcrumb if the
wakeup counter is one, meaning this was the first wakeup?
Regards,
Tvrtko
>> +
>> + if (wake_up_process(wait->tsk))
>> + result |= ENGINE_WAKEUP_SUCCESS;
>> }
>>
>> return result;
>> @@ -98,7 +112,7 @@ static void intel_breadcrumbs_hangcheck(unsigned
>> long data)
>> * but we still have a waiter. Assuming all batches complete within
>> * DRM_I915_HANGCHECK_JIFFIES [1.5s]!
>> */
>> - if (intel_engine_wakeup(engine) & ENGINE_WAKEUP_ASLEEP) {
>> + if (intel_engine_wakeup(engine) == ENGINE_WAKEUP) {
>> missed_breadcrumb(engine);
>> mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1);
>> } else {
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h
>> b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> index cbe61d3f31da..974a5928bec9 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> @@ -663,6 +663,10 @@ static inline bool intel_engine_has_waiter(const
>> struct intel_engine_cs *engine)
>> unsigned int intel_engine_wakeup(struct intel_engine_cs *engine);
>> #define ENGINE_WAKEUP_WAITER BIT(0)
>> #define ENGINE_WAKEUP_ASLEEP BIT(1)
>> +#define ENGINE_WAKEUP_SUCCESS BIT(2)
>> +#define ENGINE_WAKEUP (ENGINE_WAKEUP_WAITER | \
>> + ENGINE_WAKEUP_ASLEEP | \
>> + ENGINE_WAKEUP_SUCCESS)
>>
>> void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine);
>> void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine);
>>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2017-04-07 8:23 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-06 9:30 [PATCH v3] drm/i915: Only report a wakeup if the waiter was truly asleep Chris Wilson
2017-04-06 9:52 ` ✓ Fi.CI.BAT: success for drm/i915: Only report a wakeup if the waiter was truly asleep (rev3) Patchwork
2017-04-06 17:40 ` [PATCH v3] drm/i915: Only report a wakeup if the waiter was truly asleep Tvrtko Ursulin
2017-04-07 8:23 ` Tvrtko Ursulin [this message]
2017-04-07 9:05 ` Chris Wilson
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=cb78cd6f-ba59-e0f3-a874-37b1f03a1416@linux.intel.com \
--to=tvrtko.ursulin@linux.intel.com \
--cc=chris@chris-wilson.co.uk \
--cc=intel-gfx@lists.freedesktop.org \
/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