From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 1/2] drm/i915/selftests: Verify the LRC register layout between init and HW
Date: Tue, 24 Sep 2019 18:07:01 +0300 [thread overview]
Message-ID: <87a7atzqay.fsf@gaia.fi.intel.com> (raw)
In-Reply-To: <156932183753.3684.11723522936667671637@skylake-alporthouse-com>
Chris Wilson <chris@chris-wilson.co.uk> writes:
> Quoting Mika Kuoppala (2019-09-24 11:21:38)
>> Chris Wilson <chris@chris-wilson.co.uk> writes:
>>
>> > Before we submit the first context to HW, we need to construct a valid
>> > image of the register state. This layout is defined by the HW and should
>> > match the layout generated by HW when it saves the context image.
>> > Asserting that this should be equivalent should help avoid any undefined
>> > behaviour and verify that we haven't missed anything important!
>> >
>> > Of course, having insisted that the initial register state within the
>> > LRC should match that returned by HW, we need to ensure that it does.
>> >
>> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>> > Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
>> > Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>
>> > +static u32 *set_offsets(u32 *regs,
>> > + const u8 *data,
>> > + const struct intel_engine_cs *engine)
>> > +#define NOP(x) (BIT(7) | (x))
>> > +#define LRI(count, flags) ((flags) << 6 | (count))
>> > +#define POSTED BIT(0)
>> > +#define REG(x) (((x) >> 2) | BUILD_BUG_ON_ZERO(x >= 0x200))
>> > +#define REG16(x) \
>> > + (((x) >> 9) | BIT(7) | BUILD_BUG_ON_ZERO(x >= 0x10000)), \
>> > + (((x) >> 2) & 0x7f)
>>
>> I am still not sure if the actual saving are worth the complexity.
>>
>> > +#define END() 0
>> > +{
>> > + const u32 base = engine->mmio_base;
>> > +
>> > + while (*data) {
>> > + u8 count, flags;
>> > +
>> > + if (*data & BIT(7)) { /* skip */
>> > + regs += *data++ & ~BIT(7);
>> > + continue;
>> > + }
>> > +
>> > + count = *data & 0x3f;
>> > + flags = *data >> 6;
>> > + data++;
>> > +
>> > + *regs = MI_LOAD_REGISTER_IMM(count);
>> > + if (flags & POSTED)
>> > + *regs |= MI_LRI_FORCE_POSTED;
>> > + if (INTEL_GEN(engine->i915) >= 11)
>> > + *regs |= MI_LRI_CS_MMIO;
>> > + regs++;
>> > +
>> > + GEM_BUG_ON(!count);
>> > + do {
>> > + u32 offset = 0;
>> > + u8 v;
>> > +
>> > + do {
>> > + v = *data++;
>> > + offset <<= 7;
>> > + offset |= v & ~BIT(7);
>> > + } while (v & BIT(7));
>>
>> ...but perhaps this amount of extra can be tolerated.
>>
>> Did you check how this would play out with just REG being wide enough?
>
> When I started, I thought we could get away with only one REG16. Looking
> at the context image I think we might want a few non engine->mmio_base
> regs in there (if I read it right, some of the 0x4000 range are per
> engine). That will need a slightly different encoding as well :|
>
> No, I haven't but since you ask, I shall.
Now we know the bloat diff and the complexity addition
is tiny so I am fine with using the tighter REG/REG16
split.
>
>> > +
>> > + *regs = base + (offset << 2);
>>
>> In here reader is yearning for an asserts of not trampling
>> on wrong territory.
>
> If you have an idea for a good assert, go for it :)
>
> What range should be checked. offset < 0x1000 ?
>
I am fine at selftest trying to take the burden.
(that can be read like that I can't make up good asserts)
>> But I would guess that you want this part to be like
>> oiled lightning and test the machinery with selftest..as the
>> subject seems to promise.
>
> The importance is certainly placed on having a selftest and the
> confidence in keeping our offsets in line with the HW. The goal was to
> have a compact description for the register offsets, in terms of
> readability I think the emphasis should be on the tables
> (gen8_xcs_offsets[]).
>
>> > @@ -3092,7 +3451,7 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
>> > engine->flags |= I915_ENGINE_HAS_PREEMPTION;
>> > }
>> >
>> > - if (engine->class != COPY_ENGINE_CLASS && INTEL_GEN(engine->i915) >= 12)
>> > + if (engine->class != COPY_ENGINE_CLASS && INTEL_GEN(engine->i915) >= 11)
>> > engine->flags |= I915_ENGINE_HAS_RELATIVE_MMIO;
>>
>> Ok, first I thought this was unintentional. But prolly not.
>> Do you need it for the verifier to work?
>
> No, I ended up completely ignoring this flag as the HW does not
> differentiate between engines. On gen11+, it sets the LRI flag everywhere
> in the context image.
>
>> Could we still rip it out to be a first in the series.
>> Just would want to differiante possible icl hickups apart
>> from this patch.
With the relative MMIO for gen11 lifted as a separate
patch prior to this one,
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
>
> Sure.
>
>> > +static int live_lrc_layout(void *arg)
>> > +{
>> > + struct intel_gt *gt = arg;
>> > + struct intel_engine_cs *engine;
>> > + enum intel_engine_id id;
>> > + u32 *mem;
>> > + int err;
>> > +
>> > + /*
>> > + * Check the registers offsets we use to create the initial reg state
>> > + * match the layout saved by HW.
>> > + */
>> > +
>> > + mem = kmalloc(PAGE_SIZE, GFP_KERNEL);
>> > + if (!mem)
>> > + return -ENOMEM;
>> > +
>> > + err = 0;
>> > + for_each_engine(engine, gt->i915, id) {
>> > + u32 *hw, *lrc;
>> > + int dw;
>> > +
>> > + if (!engine->default_state)
>> > + continue;
>> > +
>> > + hw = i915_gem_object_pin_map(engine->default_state,
>> > + I915_MAP_WB);
>>
>> This default state is not pristine as we have trampled
>> it with our first submission, right?
>
> It is the context image saved after the first request.
>
>> But being succeeded at doing so, the next context
>> save should overwrite our trampling and it would
>> then represent the hw accurate context save
>> state.
>>
>> Against which we will compare of our reg state
>> writer.
>
> Right, default_state is the HW version of our init_reg_state.
>
>> > + if (IS_ERR(hw)) {
>> > + err = PTR_ERR(hw);
>> > + break;
>> > + }
>> > + hw += LRC_STATE_PN * PAGE_SIZE / sizeof(*hw);
>> > +
>> > + lrc = memset(mem, 0, PAGE_SIZE);
>> > + execlists_init_reg_state(lrc,
>> > + engine->kernel_context,
>> > + engine,
>> > + engine->kernel_context->ring,
>> > + true);
>> > +
>> > + dw = 0;
>> > + do {
>> > + u32 lri = hw[dw];
>> > +
>> > + if (lri == 0) {
>> > + dw++;
>> > + continue;
>> > + }
>> > +
>> > + if ((lri & GENMASK(31, 23)) != MI_INSTR(0x22, 0)) {
>> > + pr_err("%s: Expected LRI command at dword %d, found %08x\n",
>> > + engine->name, dw, lri);
>> > + err = -EINVAL;
>> > + break;
>> > + }
>> > +
>> > + if (lrc[dw] != lri) {
>> > + pr_err("%s: LRI command mismatch at dword %d, expected %08x found %08x\n",
>> > + engine->name, dw, lri, lrc[dw]);
>> > + err = -EINVAL;
>> > + break;
>> > + }
>> > +
>> > + lri &= 0x7f;
>> > + lri++;
>> > + dw++;
>> > +
>> > + while (lri) {
>> > + if (hw[dw] != lrc[dw]) {
>> > + pr_err("%s: Different registers found at dword %d, expected %x, found %x\n",
>> > + engine->name, dw, hw[dw], lrc[dw]);
>> > + err = -EINVAL;
>> > + break;
>> > + }
>> > +
>> > + /*
>> > + * Skip over the actual register value as we
>> > + * expect that to differ.
>> > + */
>> > + dw += 2;
>> > + lri -= 2;
>>
>> This makes me wonder if we could use this machinery post hang. Just to
>> get a little more triage data out, ie 'your context looks corrupted at
>> offset %x'...
>
> Certainly possible, but what we check here is _mostly_ the privileged
> registers that are not really meant to be changed by the user -- and we
> are only checking the offsets, so unlikely there to be just one wrong.
>
> The general principle was that we should provide raw information and
> have the smarts in userspace (so that we could always enhance our
> processing and reanalyse existing dumps). But at the end of the day,
> whatever allows us to prevent bugs or fix bugs is paramount.
>
> But I'm not yet sold this helps. Maybe if we find an example where it
> proves useful...
>
>> > + }
>> > + } while ((lrc[dw] & ~BIT(0)) != MI_BATCH_BUFFER_END);
>>
>> Ok, you tie up always the generate image. For future work add the hw batch
>> endpoint be a part of checker?
>
> It's not always in the first page, I'm not even sure if a BB_END is
> always included in the older gen. (I have a feeling the HW definitely
> started including it ~gen10.)
> -Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2019-09-24 15:07 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-23 23:02 [PATCH 1/2] drm/i915/selftests: Verify the LRC register layout between init and HW Chris Wilson
2019-09-23 23:02 ` [PATCH 2/2] drm/i915/tgl: Swap engines for rps (gpu reclocking) Chris Wilson
2019-09-24 7:09 ` [PATCH] drm/i915/tgl: Swap engines for no rc6/rps (gpu powersave and reclocking) Chris Wilson
2019-09-23 23:08 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/2] drm/i915/selftests: Verify the LRC register layout between init and HW Patchwork
2019-09-23 23:31 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-24 7:17 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/2] drm/i915/selftests: Verify the LRC register layout between init and HW (rev2) Patchwork
2019-09-24 7:43 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-24 7:59 ` Chris Wilson
2019-09-24 10:21 ` [PATCH 1/2] drm/i915/selftests: Verify the LRC register layout between init and HW Mika Kuoppala
2019-09-24 10:43 ` Chris Wilson
2019-09-24 15:07 ` Mika Kuoppala [this message]
2019-09-24 11:00 ` Chris Wilson
2019-09-24 11:58 ` Mika Kuoppala
2019-09-24 13:23 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/2] drm/i915/selftests: Verify the LRC register layout between init and HW (rev3) Patchwork
2019-09-24 13:48 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-24 13:58 ` Chris Wilson
2019-09-24 14:59 ` [PATCH v2] drm/i915/selftests: Verify the LRC register layout between init and HW Chris Wilson
2019-09-24 15:04 ` Chris Wilson
2019-09-24 15:57 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2] drm/i915/selftests: Verify the LRC register layout between init and HW (rev5) Patchwork
2019-09-24 16:25 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-25 6:56 ` ✓ Fi.CI.IGT: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2019-09-20 19:55 [PATCH 1/2] drm/i915/selftests: Verify the LRC register layout between init and HW 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=87a7atzqay.fsf@gaia.fi.intel.com \
--to=mika.kuoppala@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.