From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 05/16] drm/i915: Add unit tests for the breadcrumb rbtree, wakeups
Date: Thu, 8 Dec 2016 17:38:34 +0000 [thread overview]
Message-ID: <9f55b4fa-e6a5-857e-9728-37f1a718a1e6@linux.intel.com> (raw)
In-Reply-To: <20161207135833.32740-6-chris@chris-wilson.co.uk>
On 07/12/2016 13:58, Chris Wilson wrote:
> Third retroactive test, make sure that the seqno waiters are woken.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/intel_breadcrumbs.c | 171 +++++++++++++++++++++++++++++++
> 1 file changed, 171 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> index fc950f7ff322..1374a54e41c9 100644
> --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> @@ -966,11 +966,182 @@ static int igt_insert_complete(void *ignore)
> return err;
> }
>
> +struct igt_wakeup {
> + struct task_struct *tsk;
> + atomic_t *ready, *set, *done;
> + struct intel_engine_cs *engine;
> + unsigned long flags;
> + wait_queue_head_t *wq;
> + u32 seqno;
> +};
> +
> +static int wait_atomic(atomic_t *p)
> +{
> + schedule();
> + return 0;
> +}
> +
> +static int wait_atomic_timeout(atomic_t *p)
> +{
> + return schedule_timeout(10 * HZ) ? 0 : -ETIMEDOUT;
> +}
> +
> +static int igt_wakeup_thread(void *arg)
> +{
> + struct igt_wakeup *w = arg;
> + struct intel_wait wait;
> +
> + while (!kthread_should_stop()) {
> + DEFINE_WAIT(ready);
> +
> + for (;;) {
> + prepare_to_wait(w->wq, &ready, TASK_INTERRUPTIBLE);
> + if (atomic_read(w->ready) == 0)
> + break;
> +
> + schedule();
> + }
> + finish_wait(w->wq, &ready);
Have to say this is the first time I've learnt about wake_up_atomic_t &
co. You couldn't use wait_on_atomic_t instead of the loop above?
> + if (atomic_dec_and_test(w->set))
> + wake_up_atomic_t(w->set);
> +
Okay, all the threads have observed that all other threads have been
started, yes?
> + if (test_bit(0, &w->flags))
> + break;
One thread failed to start = bailout.
Do you intend to use the flags for something more which precludes a more
descriptive name for its single purpose here?
> +
> + intel_wait_init(&wait, w->seqno);
> + intel_engine_add_wait(w->engine, &wait);
> + for (;;) {
> + set_current_state(TASK_UNINTERRUPTIBLE);
> + if (i915_seqno_passed(intel_engine_get_seqno(w->engine),
> + w->seqno))
> + break;
> +
> + schedule();
> + }
> + intel_engine_remove_wait(w->engine, &wait);
> + __set_current_state(TASK_RUNNING);
> +
> + if (atomic_dec_and_test(w->done))
> + wake_up_atomic_t(w->done);
> + }
> +
> + if (atomic_dec_and_test(w->done))
> + wake_up_atomic_t(w->done);
Must be a special reason done is decremented in the loop and outside the
loop?
> + return 0;
> +}
> +
> +static void igt_wake_all_sync(atomic_t *ready,
> + atomic_t *set,
> + atomic_t *done,
> + wait_queue_head_t *wq,
> + int count)
> +{
> + atomic_set(set, count);
> + atomic_set(done, count);
> +
> + atomic_set(ready, 0);
> + wake_up_all(wq);
> +
> + wait_on_atomic_t(set, wait_atomic, TASK_UNINTERRUPTIBLE);
> + atomic_set(ready, count);
> +}
> +
> +static int igt_wakeup(void *ignore)
> +{
> + const int state = TASK_UNINTERRUPTIBLE;
> + struct intel_engine_cs *engine;
> + struct igt_wakeup *waiters;
> + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
> + const int count = 4096;
> + const u32 max_seqno = count / 4;
> + atomic_t ready, set, done;
> + int err = -ENOMEM;
> + int n, step;
> +
> + engine = mock_engine("mock");
> + if (!engine)
> + goto out;
> +
> + waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
> + if (!waiters)
> + goto out_engines;
> +
> + atomic_set(&ready, count);
> + for (n = 0; n < count; n++) {
> + waiters[n].wq = &wq;
> + waiters[n].ready = &ready;
> + waiters[n].set = &set;
> + waiters[n].done = &done;
> + waiters[n].engine = engine;
> + waiters[n].flags = 0;
> +
> + waiters[n].tsk = kthread_run(igt_wakeup_thread, &waiters[n],
> + "i915/igt:%d", n);
> + if (IS_ERR(waiters[n].tsk))
> + goto out_waiters;
> +
> + get_task_struct(waiters[n].tsk);
> + }
> +
It is time to start documenting the tests I think via nice comments at
strategic places. Probably a short commentary on the test as a whole and
then separately at interesting steps.
> + for (step = 1; step <= max_seqno; step <<= 1) {
> + u32 seqno;
> +
> + for (n = 0; n < count; n++)
> + waiters[n].seqno = 1 + get_random_int() % max_seqno;
So you have 4096 waiters but some are waiting on the same seqno, since
there are at most 1024 unique seqnos. Took me a while to figure this one
out.
> +
> + mock_seqno_advance(engine, 0);
> + igt_wake_all_sync(&ready, &set, &done, &wq, count);
> +
> + for (seqno = 1; seqno <= max_seqno + step; seqno += step) {
First step wakes up all seqnos one by one, the other steps do it in
chunks with a larger and larger skip. All the way to waking the whole
bunch at once?
> + usleep_range(50, 500);
Why sleep? It should work without it, no?
> + mock_seqno_advance(engine, seqno);
> + }
> + GEM_BUG_ON(intel_engine_get_seqno(engine) < 1 + max_seqno);
> +
> + err = wait_on_atomic_t(&done, wait_atomic_timeout, state);
> + if (err) {
> + pr_err("Timed out waiting for %d remaining waiters\n",
> + atomic_read(&done));
> + break;
> + }
> +
> + err = check_rbtree_empty(engine);
> + if (err)
> + break;
> + }
> +
> +out_waiters:
> + for (n = 0; n < count; n++) {
> + if (IS_ERR(waiters[n].tsk))
> + break;
> +
> + set_bit(0, &waiters[n].flags);
> + }
> +
> + igt_wake_all_sync(&ready, &set, &done, &wq, n);
> + wait_on_atomic_t(&done, wait_atomic, state);
C-O-M-M-E-N-T-S! :D
> +
> + for (n = 0; n < count; n++) {
> + if (IS_ERR(waiters[n].tsk))
> + break;
> +
> + kthread_stop(waiters[n].tsk);
> + put_task_struct(waiters[n].tsk);
> + }
> +
> + drm_free_large(waiters);
> +out_engines:
> + kfree(engine);
> +out:
> + return err;
> +}
> +
> int intel_breadcrumbs_selftest(void)
> {
> static const struct i915_subtest tests[] = {
> SUBTEST(igt_random_insert_remove),
> SUBTEST(igt_insert_complete),
> + SUBTEST(igt_wakeup),
> };
>
> return i915_subtests(tests, NULL);
>
Phew, looks mostly OK. I think only one thing I am unsure of.
This was quite smart, please start adding comments when you come up with
similar things. :)
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-12-08 17:38 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-07 13:58 [RFC] Smattering of selftests Chris Wilson
2016-12-07 13:58 ` [PATCH 01/16] drm/i915: Provide a hook for selftests Chris Wilson
2016-12-08 10:47 ` Tvrtko Ursulin
2016-12-08 11:15 ` Chris Wilson
2016-12-08 12:30 ` Tvrtko Ursulin
2016-12-08 12:40 ` Chris Wilson
2016-12-07 13:58 ` [PATCH 02/16] kselftests: Exercise hw-independent mock tests for i915.ko Chris Wilson
2016-12-07 14:09 ` Chris Wilson
2016-12-08 15:50 ` Shuah Khan
2016-12-08 16:01 ` Chris Wilson
2016-12-08 16:44 ` Shuah Khan
2016-12-07 13:58 ` [PATCH 03/16] drm/i915: Add unit tests for the breadcrumb rbtree, insert/remove Chris Wilson
2016-12-08 11:00 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 04/16] drm/i915: Add unit tests for the breadcrumb rbtree, completion Chris Wilson
2016-12-08 11:47 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 05/16] drm/i915: Add unit tests for the breadcrumb rbtree, wakeups Chris Wilson
2016-12-08 17:38 ` Tvrtko Ursulin [this message]
2016-12-08 21:04 ` Chris Wilson
2016-12-09 9:33 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 06/16] drm/i915: Add a reminder that i915_vma_move_to_active() requires struct_mutex Chris Wilson
2016-12-08 17:40 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 07/16] drm/i915: Move intel_lrc_context_pin() to avoid the forward declaration Chris Wilson
2016-12-08 17:45 ` Tvrtko Ursulin
2016-12-08 20:55 ` Chris Wilson
2016-12-07 13:58 ` [PATCH 08/16] drm/i915: Unify active context tracking between legacy/execlists/guc Chris Wilson
2016-12-09 11:48 ` Tvrtko Ursulin
2016-12-09 12:17 ` Chris Wilson
2016-12-07 13:58 ` [PATCH 09/16] drm/i915: Simplify releasing context reference Chris Wilson
2016-12-09 15:03 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 10/16] drm/i915: Mark the shadow gvt context as closed Chris Wilson
2016-12-09 15:07 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 11/16] drm/i915/execlists: Request the kernel context be pinned high Chris Wilson
2016-12-09 15:08 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 12/16] drm/i915: Swap if(enable_execlists) in i915_gem_request_alloc for a vfunc Chris Wilson
2016-12-09 15:16 ` Tvrtko Ursulin
2016-12-09 15:25 ` Chris Wilson
2016-12-09 15:53 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 13/16] drm/i915: Add selftests for i915_gem_request Chris Wilson
2016-12-09 15:51 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 14/16] drm/i915: Add a simple request selftest for waiting Chris Wilson
2016-12-09 15:59 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 15/16] drm/i915: Add a simple fence selftest to i915_gem_request Chris Wilson
2016-12-09 16:02 ` Tvrtko Ursulin
2016-12-07 13:58 ` [PATCH 16/16] drm/i915: Add selftests for object allocation, phys Chris Wilson
2016-12-13 17:10 ` Tvrtko Ursulin
2016-12-17 13:55 ` Chris Wilson
2016-12-07 14:04 ` [RFC] Smattering of selftests Chris Wilson
2016-12-07 15:45 ` ✓ Fi.CI.BAT: success for series starting with [01/16] drm/i915: Provide a hook for selftests Patchwork
2016-12-07 18:52 ` [PATCH 1/2] drm/i915: Move uncore selfchecks to late selftest infrastructure Chris Wilson
2016-12-07 18:52 ` [PATCH 2/2] drm/i915: Test all fw tables during mock selftests Chris Wilson
2016-12-08 12:14 ` Tvrtko Ursulin
2016-12-08 12:28 ` Chris Wilson
2016-12-08 13:11 ` Joonas Lahtinen
2016-12-08 16:52 ` Tvrtko Ursulin
2016-12-08 22:29 ` Chris Wilson
2016-12-09 9:41 ` Tvrtko Ursulin
2016-12-09 10:18 ` Chris Wilson
2016-12-09 10:35 ` Tvrtko Ursulin
2016-12-09 10:51 ` Chris Wilson
2016-12-08 11:58 ` [PATCH 1/2] drm/i915: Move uncore selfchecks to late selftest infrastructure Tvrtko Ursulin
2016-12-07 19:56 ` [RFC] Smattering of selftests Paulo Zanoni
2016-12-07 20:52 ` ✓ Fi.CI.BAT: success for series starting with [01/16] drm/i915: Provide a hook for selftests (rev2) Patchwork
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=9f55b4fa-e6a5-857e-9728-37f1a718a1e6@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