From: Matthew Brost <matthew.brost@intel.com>
To: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
daniel.vetter@ffwll.ch, tony.ye@intel.com, zhengguo.xu@intel.com
Subject: Re: [Intel-gfx] [PATCH 08/27] drm/i915: Add logical engine mapping
Date: Mon, 13 Sep 2021 09:50:30 -0700 [thread overview]
Message-ID: <20210913165029.GA8526@jons-linux-dev-box> (raw)
In-Reply-To: <d95ee5e5-7118-cd98-49c0-964f22ade45d@linux.intel.com>
On Mon, Sep 13, 2021 at 10:24:43AM +0100, Tvrtko Ursulin wrote:
>
> On 10/09/2021 20:49, Matthew Brost wrote:
> > On Fri, Sep 10, 2021 at 12:12:42PM +0100, Tvrtko Ursulin wrote:
> > >
> > > On 20/08/2021 23:44, Matthew Brost wrote:
> > > > Add logical engine mapping. This is required for split-frame, as
> > > > workloads need to be placed on engines in a logically contiguous manner.
> > > >
> > > > v2:
> > > > (Daniel Vetter)
> > > > - Add kernel doc for new fields
> > > >
> > > > Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> > > > ---
> > > > drivers/gpu/drm/i915/gt/intel_engine_cs.c | 60 ++++++++++++++++---
> > > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 5 ++
> > > > .../drm/i915/gt/intel_execlists_submission.c | 1 +
> > > > drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 2 +-
> > > > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 21 +------
> > > > 5 files changed, 60 insertions(+), 29 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > > index 0d9105a31d84..4d790f9a65dd 100644
> > > > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
> > > > @@ -290,7 +290,8 @@ static void nop_irq_handler(struct intel_engine_cs *engine, u16 iir)
> > > > GEM_DEBUG_WARN_ON(iir);
> > > > }
> > > > -static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
> > > > +static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
> > > > + u8 logical_instance)
> > > > {
> > > > const struct engine_info *info = &intel_engines[id];
> > > > struct drm_i915_private *i915 = gt->i915;
> > > > @@ -334,6 +335,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
> > > > engine->class = info->class;
> > > > engine->instance = info->instance;
> > > > + engine->logical_mask = BIT(logical_instance);
> > > > __sprint_engine_name(engine);
> > > > engine->props.heartbeat_interval_ms =
> > > > @@ -572,6 +574,37 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt)
> > > > return info->engine_mask;
> > > > }
> > > > +static void populate_logical_ids(struct intel_gt *gt, u8 *logical_ids,
> > > > + u8 class, const u8 *map, u8 num_instances)
> > > > +{
> > > > + int i, j;
> > > > + u8 current_logical_id = 0;
> > > > +
> > > > + for (j = 0; j < num_instances; ++j) {
> > > > + for (i = 0; i < ARRAY_SIZE(intel_engines); ++i) {
> > > > + if (!HAS_ENGINE(gt, i) ||
> > > > + intel_engines[i].class != class)
> > > > + continue;
> > > > +
> > > > + if (intel_engines[i].instance == map[j]) {
> > > > + logical_ids[intel_engines[i].instance] =
> > > > + current_logical_id++;
> > > > + break;
> > > > + }
> > > > + }
> > > > + }
> > > > +}
> > > > +
> > > > +static void setup_logical_ids(struct intel_gt *gt, u8 *logical_ids, u8 class)
> > > > +{
> > > > + int i;
> > > > + u8 map[MAX_ENGINE_INSTANCE + 1];
> > > > +
> > > > + for (i = 0; i < MAX_ENGINE_INSTANCE + 1; ++i)
> > > > + map[i] = i;
> > >
> > > What's the point of the map array since it is 1:1 with instance?
> > >
> >
> > Future products do not have a 1 to 1 mapping and that mapping can change
> > based on fusing, e.g. XeHP SDV.
> >
> > Also technically ICL / TGL / ADL physical instance 2 maps to logical
> > instance 1.
>
> I don't follow the argument. All I can see is that "map[i] = i" always in
> the proposed code, which is then used to check "instance == map[instance]".
> So I'd suggest to remove this array from the code until there is a need for
> it.
>
Ok, this logic is slightly confusing and makes more sense once we have
non-standard mappings. Yes, map is setup in a 1 to 1 mapping by default
with the value in map[i] being a physical instance. Populate_logical_ids
searches the map finding all physical instances present in the map
assigning each found instance a new logical id increasing by 1 each
time.
e.g. If the map is setup 0-N and only physical instance 0 / 2 are
present they will get logical mapping 0 / 1 respectfully.
This algorithm works for non-standard mappings too /w fused parts. e.g.
on XeHP SDV the map is: { 0, 2, 4, 6, 1, 3, 5, 7 } and if any of the
physical instances can't be found due to fusing the logical mapping is
still correct per the bspec.
This array is absolutely needed for multi-lrc submission to work, even
on ICL / TGL / ADL as the GuC only supports logically contiguous engine
instances.
> > > > + populate_logical_ids(gt, logical_ids, class, map, ARRAY_SIZE(map));
> > > > +}
> > > > +
> > > > /**
> > > > * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers
> > > > * @gt: pointer to struct intel_gt
> > > > @@ -583,7 +616,8 @@ int intel_engines_init_mmio(struct intel_gt *gt)
> > > > struct drm_i915_private *i915 = gt->i915;
> > > > const unsigned int engine_mask = init_engine_mask(gt);
> > > > unsigned int mask = 0;
> > > > - unsigned int i;
> > > > + unsigned int i, class;
> > > > + u8 logical_ids[MAX_ENGINE_INSTANCE + 1];
> > > > int err;
> > > > drm_WARN_ON(&i915->drm, engine_mask == 0);
> > > > @@ -593,15 +627,23 @@ int intel_engines_init_mmio(struct intel_gt *gt)
> > > > if (i915_inject_probe_failure(i915))
> > > > return -ENODEV;
> > > > - for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
> > > > - if (!HAS_ENGINE(gt, i))
> > > > - continue;
> > > > + for (class = 0; class < MAX_ENGINE_CLASS + 1; ++class) {
> > > > + setup_logical_ids(gt, logical_ids, class);
> > > > - err = intel_engine_setup(gt, i);
> > > > - if (err)
> > > > - goto cleanup;
> > > > + for (i = 0; i < ARRAY_SIZE(intel_engines); ++i) {
> > > > + u8 instance = intel_engines[i].instance;
> > > > +
> > > > + if (intel_engines[i].class != class ||
> > > > + !HAS_ENGINE(gt, i))
> > > > + continue;
> > > > - mask |= BIT(i);
> > > > + err = intel_engine_setup(gt, i,
> > > > + logical_ids[instance]);
> > > > + if (err)
> > > > + goto cleanup;
> > > > +
> > > > + mask |= BIT(i);
> > >
> > > I still this there is a less clunky way to set this up in less code and more
> > > readable at the same time. Like do it in two passes so you can iterate
> > > gt->engine_class[] array instead of having to implement a skip condition
> > > (both on class and HAS_ENGINE at two places) and also avoid walking the flat
> > > intel_engines array recursively.
> > >
> >
> > Kinda a bikeshed arguing about a pretty simple loop structure, don't you
> > think? I personally like the way it laid out.
> >
> > Pseudo code for your suggestion?
>
> Leave the existing setup loop as is and add an additional "for engine class"
> walk after it. That way you can walk already setup gt->engine_class[] array
> so wouldn't need to skip wrong classes and have HAS_ENGINE checks when
> walking the flat intel_engines[] array several times. It also applies to the
> helper which counts logical instances per class.
>
Ok, I think I see what you are getting at. Again IMO this is a total
bikeshed as this is 1 time setup step that we really should only care if
the loop works or not rather than it being optimized / looks a way a
certain person wants. I can change this if you really insist but again
IMO disucssing this is a total waste of energy.
> > > > + }
> > > > }
> > > > /*
> > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > > > index ed91bcff20eb..fddf35546b58 100644
> > > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> > > > @@ -266,6 +266,11 @@ struct intel_engine_cs {
> > > > unsigned int guc_id;
> > > > intel_engine_mask_t mask;
> > > > + /**
> > > > + * @logical_mask: logical mask of engine, reported to user space via
> > > > + * query IOCTL and used to communicate with the GuC in logical space
> > > > + */
> > > > + intel_engine_mask_t logical_mask;
> > >
> > > You could prefix the new field with uabi_ to match the existing scheme and
> > > to signify to anyone who might be touching it in the future it should not be
> > > changed.
> >
> > This is kinda uabi, but also kinda isn't. We do report a logical
> > instance via IOCTL but it also really is tied the GuC backend as we only
> > can communicate with the GuC in logical space. IMO we should leave as
> > is.
>
> Perhaps it would be best to call the new field uabi_logical_instance so it's
> clear it is reported in the query directly and do the BIT() transformation
> in the GuC backend?
>
Virtual engines can have a multiple bits set in this mask, so this is
used for both the query on physical engines via UABI and submission in
the GuC backend.
> >
> > >
> > > Also, I think comment should explain what is logical space ie. how the
> > > numbering works.
> > >
> >
> > Don't I already do that? I suppose I could add something like:
>
> Where is it? Can't see it in the uapi kerneldoc AFAICS (for the new query)
> or here.
>
/**
* @logical_mask: logical mask of engine, reported to user space via
* query IOCTL and used to communicate with the GuC in logical space
*/
> >
> > The logical mask within engine class must be contiguous across all
> > instances.
>
> Best not to start mentioning the mask for the first time. Just explain what
> logical numbering is in terms of how engines are enumerated in order of
> physical instances but skipping the fused off ones. In the kerneldoc for the
> new query is I think the right place.
>
Maybe I can add:
The logical mapping is defined on per part basis in the bspec and can
very based the parts fusing.
> > > Not sure the part about GuC needs to be in the comment since uapi is
> > > supposed to be backend agnostic.
> > >
> >
> > Communicating with the GuC in logical space is a pretty key point here.
> > The communication with the GuC in logical space is backend specific but
> > how our hardware works (e.g. split frame workloads must be placed
> > logical contiguous) is not. Mentioning the GuC requirement here makes
> > sense to me for completeness.
>
> Yeah might be, I was thinking more about the new query. Query definitely is
> backend agnostic but yes it is fine to say in the comment here the new field
> is used both for the query and for communicating with GuC.
>
Sounds good, will make it clear it used for the query and from
communicating with the GuC.
Matt
> Regards,
>
> Tvrtko
>
> >
> > Matt
> >
> > > Regards,
> > >
> > > Tvrtko
> > >
> > > > u8 class;
> > > > u8 instance;
> > > > diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> > > > index cafb0608ffb4..813a6de01382 100644
> > > > --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> > > > +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
> > > > @@ -3875,6 +3875,7 @@ execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count)
> > > > ve->siblings[ve->num_siblings++] = sibling;
> > > > ve->base.mask |= sibling->mask;
> > > > + ve->base.logical_mask |= sibling->logical_mask;
> > > > /*
> > > > * All physical engines must be compatible for their emission
> > > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > > > index 6926919bcac6..9f5f43a16182 100644
> > > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > > > @@ -176,7 +176,7 @@ static void guc_mapping_table_init(struct intel_gt *gt,
> > > > for_each_engine(engine, gt, id) {
> > > > u8 guc_class = engine_class_to_guc_class(engine->class);
> > > > - system_info->mapping_table[guc_class][engine->instance] =
> > > > + system_info->mapping_table[guc_class][ilog2(engine->logical_mask)] =
> > > > engine->instance;
> > > > }
> > > > }
> > > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > index e0eed70f9b92..ffafbac7335e 100644
> > > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > @@ -1401,23 +1401,6 @@ static int deregister_context(struct intel_context *ce, u32 guc_id, bool loop)
> > > > return __guc_action_deregister_context(guc, guc_id, loop);
> > > > }
> > > > -static intel_engine_mask_t adjust_engine_mask(u8 class, intel_engine_mask_t mask)
> > > > -{
> > > > - switch (class) {
> > > > - case RENDER_CLASS:
> > > > - return mask >> RCS0;
> > > > - case VIDEO_ENHANCEMENT_CLASS:
> > > > - return mask >> VECS0;
> > > > - case VIDEO_DECODE_CLASS:
> > > > - return mask >> VCS0;
> > > > - case COPY_ENGINE_CLASS:
> > > > - return mask >> BCS0;
> > > > - default:
> > > > - MISSING_CASE(class);
> > > > - return 0;
> > > > - }
> > > > -}
> > > > -
> > > > static void guc_context_policy_init(struct intel_engine_cs *engine,
> > > > struct guc_lrc_desc *desc)
> > > > {
> > > > @@ -1459,8 +1442,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, bool loop)
> > > > desc = __get_lrc_desc(guc, desc_idx);
> > > > desc->engine_class = engine_class_to_guc_class(engine->class);
> > > > - desc->engine_submit_mask = adjust_engine_mask(engine->class,
> > > > - engine->mask);
> > > > + desc->engine_submit_mask = engine->logical_mask;
> > > > desc->hw_context_desc = ce->lrc.lrca;
> > > > desc->priority = ce->guc_state.prio;
> > > > desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD;
> > > > @@ -3260,6 +3242,7 @@ guc_create_virtual(struct intel_engine_cs **siblings, unsigned int count)
> > > > }
> > > > ve->base.mask |= sibling->mask;
> > > > + ve->base.logical_mask |= sibling->logical_mask;
> > > > if (n != 0 && ve->base.class != sibling->class) {
> > > > DRM_DEBUG("invalid mixing of engine class, sibling %d, already %d\n",
> > > >
next prev parent reply other threads:[~2021-09-13 16:55 UTC|newest]
Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-20 22:44 [PATCH 00/27] Parallel submission aka multi-bb execbuf Matthew Brost
2021-08-20 22:44 ` [PATCH 01/27] drm/i915/guc: Squash Clean up GuC CI failures, simplify locking, and kernel DOC Matthew Brost
2021-08-20 22:44 ` [PATCH 02/27] drm/i915/guc: Allow flexible number of context ids Matthew Brost
2021-09-09 22:13 ` [Intel-gfx] " John Harrison
2021-09-10 0:14 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 03/27] drm/i915/guc: Connect the number of guc_ids to debugfs Matthew Brost
2021-09-09 22:16 ` [Intel-gfx] " John Harrison
2021-09-10 0:16 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 04/27] drm/i915/guc: Take GT PM ref when deregistering context Matthew Brost
2021-09-09 22:28 ` [Intel-gfx] " John Harrison
2021-09-10 0:21 ` Matthew Brost
2021-09-13 9:55 ` Tvrtko Ursulin
2021-09-13 17:12 ` Matthew Brost
2021-09-14 8:41 ` Tvrtko Ursulin
2021-08-20 22:44 ` [PATCH 05/27] drm/i915: Add GT PM unpark worker Matthew Brost
2021-09-09 22:36 ` [Intel-gfx] " John Harrison
2021-09-10 0:34 ` Matthew Brost
2021-09-10 8:36 ` Tvrtko Ursulin
2021-09-10 20:09 ` Matthew Brost
2021-09-13 10:33 ` Tvrtko Ursulin
2021-09-13 17:20 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 06/27] drm/i915/guc: Take engine PM when a context is pinned with GuC submission Matthew Brost
2021-09-09 22:46 ` [Intel-gfx] " John Harrison
2021-09-10 0:41 ` Matthew Brost
2021-09-13 22:26 ` John Harrison
2021-09-14 1:12 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 07/27] drm/i915/guc: Don't call switch_to_kernel_context " Matthew Brost
2021-09-09 22:51 ` [Intel-gfx] " John Harrison
2021-09-13 16:54 ` Matthew Brost
2021-09-13 22:38 ` John Harrison
2021-09-14 5:02 ` Matthew Brost
2021-09-13 16:55 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 08/27] drm/i915: Add logical engine mapping Matthew Brost
2021-09-10 11:12 ` [Intel-gfx] " Tvrtko Ursulin
2021-09-10 19:49 ` Matthew Brost
2021-09-13 9:24 ` Tvrtko Ursulin
2021-09-13 16:50 ` Matthew Brost [this message]
2021-09-14 8:34 ` Tvrtko Ursulin
2021-09-14 18:04 ` Matthew Brost
2021-09-15 8:24 ` Tvrtko Ursulin
2021-09-15 16:58 ` Matthew Brost
2021-09-16 8:31 ` Tvrtko Ursulin
2021-08-20 22:44 ` [PATCH 09/27] drm/i915: Expose logical engine instance to user Matthew Brost
2021-09-13 23:06 ` [Intel-gfx] " John Harrison
2021-09-14 1:08 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 10/27] drm/i915/guc: Introduce context parent-child relationship Matthew Brost
2021-09-13 23:19 ` [Intel-gfx] " John Harrison
2021-09-14 1:18 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 11/27] drm/i915/guc: Implement parallel context pin / unpin functions Matthew Brost
2021-08-20 22:44 ` [PATCH 12/27] drm/i915/guc: Add multi-lrc context registration Matthew Brost
2021-09-15 19:21 ` [Intel-gfx] " John Harrison
2021-09-15 19:31 ` Matthew Brost
2021-09-15 20:23 ` John Harrison
2021-09-15 20:33 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 13/27] drm/i915/guc: Ensure GuC schedule operations do not operate on child contexts Matthew Brost
2021-09-15 19:24 ` [Intel-gfx] " John Harrison
2021-09-15 19:34 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 14/27] drm/i915/guc: Assign contexts in parent-child relationship consecutive guc_ids Matthew Brost
2021-09-15 20:04 ` [Intel-gfx] " John Harrison
2021-09-15 20:55 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 15/27] drm/i915/guc: Implement multi-lrc submission Matthew Brost
2021-08-21 14:04 ` kernel test robot
2021-08-22 2:18 ` kernel test robot
2021-09-20 21:48 ` [Intel-gfx] " John Harrison
2021-09-22 16:25 ` Matthew Brost
2021-09-22 20:15 ` John Harrison
2021-09-23 2:44 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 16/27] drm/i915/guc: Insert submit fences between requests in parent-child relationship Matthew Brost
2021-09-20 21:57 ` [Intel-gfx] " John Harrison
2021-08-20 22:44 ` [PATCH 17/27] drm/i915/guc: Implement multi-lrc reset Matthew Brost
2021-09-20 22:44 ` [Intel-gfx] " John Harrison
2021-09-22 16:16 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 18/27] drm/i915/guc: Update debugfs for GuC multi-lrc Matthew Brost
2021-09-20 22:48 ` [Intel-gfx] " John Harrison
2021-09-21 19:13 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 19/27] drm/i915: Fix bug in user proto-context creation that leaked contexts Matthew Brost
2021-09-20 22:57 ` [Intel-gfx] " John Harrison
2021-09-21 14:49 ` Tvrtko Ursulin
2021-09-21 19:28 ` Matthew Brost
2021-09-21 19:28 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 20/27] drm/i915/guc: Connect UAPI to GuC multi-lrc interface Matthew Brost
2021-08-29 4:00 ` [Intel-gfx] " kernel test robot
2021-08-29 19:59 ` kernel test robot
2021-09-21 0:09 ` John Harrison
2021-09-22 16:38 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 21/27] drm/i915/doc: Update parallel submit doc to point to i915_drm.h Matthew Brost
2021-09-21 0:12 ` [Intel-gfx] " John Harrison
2021-08-20 22:44 ` [PATCH 22/27] drm/i915/guc: Add basic GuC multi-lrc selftest Matthew Brost
2021-09-28 20:47 ` [Intel-gfx] " John Harrison
2021-08-20 22:44 ` [PATCH 23/27] drm/i915/guc: Implement no mid batch preemption for multi-lrc Matthew Brost
2021-09-10 11:25 ` [Intel-gfx] " Tvrtko Ursulin
2021-09-10 20:49 ` Matthew Brost
2021-09-13 10:52 ` Tvrtko Ursulin
2021-09-28 22:20 ` John Harrison
2021-09-28 22:33 ` Matthew Brost
2021-09-28 23:33 ` John Harrison
2021-09-29 0:22 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 24/27] drm/i915: Multi-BB execbuf Matthew Brost
2021-08-21 19:01 ` [Intel-gfx] " kernel test robot
2021-08-30 3:46 ` kernel test robot
2021-09-30 22:16 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 25/27] drm/i915/guc: Handle errors in multi-lrc requests Matthew Brost
2021-09-29 20:44 ` [Intel-gfx] " John Harrison
2021-09-29 20:58 ` Matthew Brost
2021-08-20 22:44 ` [PATCH 26/27] drm/i915: Enable multi-bb execbuf Matthew Brost
2021-08-20 22:44 ` [PATCH 27/27] drm/i915/execlists: Weak parallel submission support for execlists Matthew Brost
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=20210913165029.GA8526@jons-linux-dev-box \
--to=matthew.brost@intel.com \
--cc=daniel.vetter@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=tony.ye@intel.com \
--cc=tvrtko.ursulin@linux.intel.com \
--cc=zhengguo.xu@intel.com \
/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;
as well as URLs for NNTP newsgroup(s).