From: "Lis, Tomasz" <tomasz.lis@intel.com>
To: Matthew Brost <matthew.brost@intel.com>,
<intel-xe@lists.freedesktop.org>
Subject: Re: [PATCH v3 11/36] drm/xe/guc: Document GuC submission backend
Date: Tue, 30 Sep 2025 05:28:55 +0200 [thread overview]
Message-ID: <a0b50db8-77bd-481e-bf80-2e8b762a1de5@intel.com> (raw)
In-Reply-To: <20250929025542.1486303-12-matthew.brost@intel.com>
[-- Attachment #1: Type: text/plain, Size: 17216 bytes --]
On 9/29/2025 4:55 AM, Matthew Brost wrote:
> Add kernel-doc to xe_guc_submit.c describing the submission path,
> the per-queue single-threaded model with pause/resume, the driver shadow
> state machine and lost-H2G replay, job timeout handling, recovery flows
> (GT reset, PM resume, VF resume), and reclaim constraints.
>
> v2:
> - Mirror tweaks for clarity
> - Add new doc to Xe rst files
> v3:
> - Clarify global vs per-queue stop / start
> - Clarify VF resume flow
> - Add section for 'Waiters during VF resume'
> - Add section for 'Page-faulting queues during VF migration'
> - Add section for 'GuC-ID assignment'
> - Add section for 'Reference counting and final queue destruction'
> v4:
> - s/VF resume/VF post migration recovery (Tomasz)
>
> Signed-off-by: Matthew Brost<matthew.brost@intel.com>
> ---
> Documentation/gpu/xe/index.rst | 1 +
> drivers/gpu/drm/xe/xe_guc_submit.c | 282 +++++++++++++++++++++++++++++
> 2 files changed, 283 insertions(+)
>
> diff --git a/Documentation/gpu/xe/index.rst b/Documentation/gpu/xe/index.rst
> index 88b22fad880e..692c544b164c 100644
> --- a/Documentation/gpu/xe/index.rst
> +++ b/Documentation/gpu/xe/index.rst
> @@ -28,3 +28,4 @@ DG2, etc is provided to prototype the driver.
> xe_device
> xe-drm-usage-stats.rst
> xe_configfs
> + xe_guc_submit
> diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
> index 70306f902ba5..cd5e506527fe 100644
> --- a/drivers/gpu/drm/xe/xe_guc_submit.c
> +++ b/drivers/gpu/drm/xe/xe_guc_submit.c
> @@ -46,6 +46,288 @@
> #include "xe_trace.h"
> #include "xe_vm.h"
>
> +/*
> + * DOC: Overview
> + *
> + * The GuC submission backend is responsible for submitting GPU jobs to the GuC
> + * firmware, assigning per-queue GuC IDs, tracking submission state via a
> + * driver-side state machine, handling GuC-to-host (G2H) messages, tracking
> + * outstanding jobs, managing job timeouts and queue teardown, and providing
> + * recovery when GuC state is lost. It is built on top of the DRM scheduler
> + * (drm_sched).
> + *
> + * GuC ID assignment:
> + * ------------------
> + * Each queue is assigned a unique GuC ID at queue init. The ID is used in all
> + * H2G/G2H to identify the queue and remains reserved until final destruction,
> + * when the GuC is known to hold no references to it.
> + *
> + * The backend maintains a reverse map GuC-ID -> queue to resolve targets for
> + * G2H handlers and to iterate all queues when required (e.g., recovery). This
> + * map is protected by submission_state.lock, a global (per-GT) lock. Lockless
> + * lookups are acceptable in paths where the queue’s lifetime is otherwise
> + * pinned and it cannot disappear underneath the operation (e.g., G2H handlers).
> + *
> + * Basic submission flow
> + * ---------------------
> + * Submission is driven by the DRM scheduler vfunc ->run_job(). The flow is:
> + *
> + * 1) Emit the job's ring instructions.
> + * 2) Advance the LRC ring tail:
> + * - width == 1: simple memory write,
> + * - width > 1: append a GuC workqueue (WQ) item.
> + * 3) If the queue is unregistered, issue a register H2G for the context.
> + * 4) Trigger execution via a scheduler enable or context submit command.
> + * 5) Return the job's hardware fence to the DRM scheduler.
> + *
> + * Registration, scheduler enable, and submit commands are issued as host-to-GuC
> + * (H2G) messages over the Command Transport (CT) layer, like all GuC
> + * interactions.
> + *
> + * Completion path
> + * ---------------
> + * When the job's hardware fence signals, the DRM scheduler vfunc ->free_job()
> + * is called; it drops the job's reference, typically freeing it.
> + *
> + * Control-plane messages:
> + * -----------------------
> + * GuC submission scheduler messages form the control plane for queue cleanup,
> + * toggling runnability, and modifying queue properties (e.g., scheduler
> + * priority, timeslice, preemption timeout). Messages are initiated via queue
> + * vfuncs that append a control message to the queue. They are processed on the
> + * same single-threaded DRM scheduler workqueue that runs ->run_job() and
> + * ->free_job().
> + *
> + * Lockless model:
> + * ---------------
> + * ->run_job(), ->free_job(), and the message handlers execute as work items on
> + * a single-threaded DRM scheduler workqueue. Per queue, this provides built-in
> + * mutual exclusion: only one of these items can run at a time. As a result,
> + * these paths are lockless with respect to per-queue state tracking. (Global
> + * or cross-queue data structures still use their own synchronization.)
> + *
> + * Stopping / starting:
> + * --------------------
> + * The submission backend supports two scopes of quiesce control:
> + *
> + * - Per-queue stop/start:
> + * The single-threaded DRM scheduler workqueue for a specific queue can be
> + * stopped and started dynamically. Stopping synchronously quiesces that
> + * queue's worker (lets any in-flight item finish and prevents new items from
> + * starting), yielding a stable snapshot while an external operation (e.g.,
> + * job timeout handling) inspects/updates state and performs any required
> + * fixups. While stopped, no submission, message, or ->free_job() work runs
> + * for that queue. When the operation completes, the queue is started; any
> + * pending items are then processed in order on the same worker. Other queues
> + * continue to run unaffected.
> + *
> + * - Global (per-GT) stop/start:
> + * Implemented on top of the per-queue stop/start primitive: the driver
> + * stops (or starts) each queue on the GT to obtain a device-wide stable
> + * snapshot. This is used by coordinated recovery flows (GT reset, PM resume,
> + * VF post migration recovery). Queues created while the global stop is in
> + * effect (i.e., future queues) initialize in the stopped state and remain
> + * stopped until the global start. After recovery fixups are complete, a
> + * global start iterates queues to start all eligible ones and resumes normal
> + * submission.
> + *
> + * State machine:
> + * --------------
> + * The submission state machine is the driver's shadow of the GuC-visible queue
> + * state (e.g., registered, runnable, scheduler properties). It tracks the
> + * transitions we intend to make (issued as H2G commands), marking them pending
> + * until acknowledged via G2H or otherwise observed as applied. It also records
> + * the origin of each transition (->run_job(), timeout handler, explicit control
> + * message, etc.).
> + *
> + * Because H2G commands and/or GuC submission state can be lost across GT reset,
> + * PM resume, or VF post migration recovery, this bookkeeping lets recovery
> + * decide which operations to replay, which to elide, and which need fixups,
> + * restoring a consistent queue state without additional per-queue locks.
> + *
> + * Job timeouts:
> + * -------------
> + * To prevent jobs from running indefinitely and violating dma-fence signaling
> + * rules, the DRM scheduler tracks how long each job has been running. If a
> + * threshold is exceeded, it calls ->timeout_job().
> + *
> + * ->timeout_job() stops the queue, samples the LRC context timestamps to
> + * confirm the job actually started and has exceeded the allowed runtime, and
> + * then, if confirmed, signals all pending jobs' fences and initiates queue
> + * teardown. Finally, the queue is started.
> + *
> + * Job timeout handling runs on a per-GT, single-threaded recovery workqueue
> + * that is shared with other recovery paths (e.g., GT reset handling, VF
> + * resume). This guarantees only one recovery action executes at a time.
> + *
> + * Queue teardown:
> + * ---------------
> + * Teardown can be triggered by: (1) userspace closing the queue; (2) a G2H
> + * queue-reset notification; (3) a G2H memory_cat_error for the queue; or (4)
> + * in-flight jobs detected on the queue during GT reset.
> + *
> + * In all cases teardown is driven via the timeout path by setting the queue's
> + * DRM scheduler timeout to zero, forcing an immediate ->timeout_job() pass.
> + *
> + * Reference counting and final queue destruction:
> + * -----------------------------------------------
> + * Jobs reference-count the queue; queues hold a reference to the VM. When a
> + * queue's reference count reaches zero (e.g., all jobs are freed and the
> + * userspace handle is closed), the queue is not destroyed immediately because
> + * the GuC may still reference its state.
> + *
> + * Instead, a control-plane cleanup message is appended to remove GuC-side
> + * references (e.g., disable runnability, deregister). Once the final G2H
> + * confirming that GuC no longer references the queue is eligible for
> + * destruction.
> + *
> + * To avoid freeing the queue from within its own DRM scheduler workqueue (which
> + * would risk use-after-free), the actual destruction is deferred to a separate
> + * work item queued on a dedicated destruction workqueue.
> + *
> + * GT resets:
> + * ----------
> + * GT resets are triggered by catastrophic errors (e.g., CT channel failure).
> + * The GuC is reset and all GuC-side submission state is lost. Recovery proceeds
> + * as follows:
> + *
> + * 1) Quiesce:
> + * - Stop all queues (global submission stop). Per-queue workers finish any
> + * in-flight item and then stop; newly created queues during the window
> + * initialize in the stopped state.
> + * - Abort any waits on CT/G2H to avoid deadlock.
> + *
> + * 2) Sanitize driver shadow state:
> + * - For each queue, clear GuC-derived bits in the submission state machine
> + * (e.g., registered/enabled) and mark in-flight H2G transitions as lost.
> + * - Convert/flush any side effects of lost H2G.
> + *
> + * 3) Decide teardown vs. replay:
> + * - If a queue's LRC seqno indicates that a job started but did not
> + * complete, initiate teardown for that queue via the timeout path.
> + * - If no job started, keep the queue for replay.
> + *
> + * 4) Resume:
> + * - Start remaining queues; resubmit pending jobs.
> + * - Queues marked for teardown remain stopped/destroyed.
> + *
> + * The entire sequence runs on the per-GT single-threaded recovery worker,
> + * ensuring only one recovery action executes at a time; a runtime PM reference
> + * is held for the duration.
> + *
> + * PM resume:
> + * ----------
> + * PM resume assumes all GuC state is lost (the device may have been powered
> + * down). It reuses the GT reset recovery path, but executes in the context of
> + * the caller that wakes the device (runtime PM or system resume).
> + *
> + * Suspend entry:
> + * - Control-plane message work is quiesced; state toggles that require an
> + * active device are not enqueued while suspended.
> + * - Per-queue scheduler workers are stopped before the device is allowed to
> + * suspend.
> + * - Barring driver bugs, no queues should have in-flight jobs at
> + * suspend/resume..
> + *
> + * On resume, run the GT reset recovery flow and then start eligible queues.
> + *
> + * Runtime PM and state-change ordering:
> + * -------------------------------------
> + * Runtime/system PM transitions must not race with per-queue submission and
> + * state updates.
> + *
> + * Execution contexts and RPM sources:
> + * - Scheduler callbacks (->run_job(), ->free_job(), ->timeout_job()):
> + * executed with an active RPM ref held by the in-flight job.
> + * - Control-plane message work:
> + * enqueued from IOCTL paths that already hold an RPM ref; the message path
> + * itself does not get/put RPM. State toggles are only issued while active.
> + * During suspend entry, message work is quiesced and no new toggles are
> + * enqueued until after resume.
> + * - G2H handlers:
> + * dispatched with an RPM ref guaranteed by the CT layer.
> + * - Recovery phases (GT reset/VF post migration recovery):
> + * explicitly get/put an RPM ref for their duration on the per-GT recovery
> + * worker.
> + *
> + * Consequence:
> + * - All submission/state mutations run with an RPM reference. The PM core
> + * cannot enter suspend while these updates are in progress, and resume is
> + * complete before updates execute. This prevents PM state changes from
> + * racing with queue state changes.
> + *
> + * VF post migration recovery:
> + * ---------------------------
> + * VF post migration recovery resembles a GT reset, but GuC submission state is
> + * expected to persist across migration; in-flight H2G commands may be lost
I don't think H2Gs can be lost. GuC is expected to either finish or not
read them, and
after recovery they can be all executed. They only require GGTT fixups.
It is our decision that we scrap them, then re-assess and re-issue the
commands by manipulating
states of entities which issued them. Maybe:
---
expected to persist across migration; GGTT base/offsets may change,
requiring update of all references to it, including in CTBs, LRCs, and
on rings.
For a wider view on that, see `VF restore procedure in PF KMD and VF
KMD`_.Recovery proceeds as follows:
---
-Tomasz
> , and
> + * GGTT base/offsets may change. Recovery proceeds as follows:
> + *
> + * 1) Quiesce:
> + * - Stop all queues and abort waits (as with GT reset) to obtain a stable
> + * snapshot.
> + * - Queues created while VF post migration recovery is in-flight initialize
> + * in the stopped state.
> + *
> + * 2) Treat H2G as lost and prepare in-place resubmission (GuC/CT down):
> + * - Treat in-flight H2G (enable/disable, etc.) as dropped; update shadow
> + * bits to a safe baseline and tag the ops as "needs replay".
> + * - Quarantine device-visible submission state: set the GuC-visible LRC ring
> + * tail equal to the head (and, for WQ-based submission, set the WQ
> + * descriptor head == tail) so that when the GuC comes up it will not process
> + * any entries that were built with stale GGTT addresses.
> + * - Reset the software ring tail to the original value captured at the
> + * submission of the oldest pending job, so the write pointer sits exactly
> + * where that job was originally emitted.
> + *
> + * 3) Replay and resubmit once GuC/CT is live:
> + * - VF post migration recovery invokes ->run_job() for pending jobs;
> + * ->emit_job() overwrites ring instructions in place, fixes GGTT fields,
> + * then advances the LRC tail (and WQ descriptor for width > 1). Required
> + * submission H2G(s) are reissued and fresh WQ entries are written.
> + * - Queue lost control-plane operations (scheduling-state toggles, cleanup)
> + * in order via the message path.
> + * - Start the queues to process the queued control-plane operations and run
> + * the resubmitted jobs.
> + *
> + * The goal is to preserve both job and queue state; no teardown is performed
> + * in this flow. The sequence runs on the per-GT single-threaded recovery
> + * worker with a held runtime PM reference.
> + *
> + * Waiters during VF post migration recovery
> + * -----------------------------------------
> + * The submission backend frequently uses wait_event_timeout() to wait on
> + * GuC-driven conditions. Across VF migration/recovery two issues arise:
> + * 1) The timeout does not account for migration downtime and may expire
> + * prematurely, triggering undesired actions (e.g., GT reset, prematurely
> + * signaling a fence).
> + * 2) Some waits target GuC work that cannot complete until VF recovery
> + * finishes; these typically sit on the queue-stopping path.
> + *
> + * To handle this, all waiters must atomically test the "GuC down / VF-recovery
> + * in progress" condition (e.g., VF_RESFIX_BLOCKED) both before sleeping and
> + * after wakeup. The flag is coherent with VF migration: vCPUs observe it
> + * immediately on unhalt, and it is cleared only after the GuC/CT is live again.
> + * If set, the waiter must either (a) abort the wait without side effects, or
> + * (b) re-arm the wait with a fresh timeout once the GuC/CT is live. Timeouts
> + * that occur while GuC/CT are down are non-fatal—the VF-recovery path will
> + * rebuild state—and must not trigger recovery or teardown.
> + *
> + * Relation to reclaim:
> + * --------------------
> + * Jobs signal dma-fences, and the MM may wait on those fences during reclaim.
> + * As a consequence, the entire GuC submission backend (DRM scheduler callbacks,
> + * message handling, and all recovery paths) lies on the reclaim path and must
> + * be reclaim-safe.
> + *
> + * Practical implications:
> + * - No memory allocations in these paths (avoid any allocation that could
> + * recurse into reclaim or sleep).
> + * - The global submission-state lock may be taken from reclaim-tainted contexts
> + * (timeout/recovery). Any path that acquires it (including queue init/destroy)
> + * must not allocate or take locks that can recurse into reclaim while holding
> + * it; keep the critical section to state/xarray updates.
> + */
> +
> static struct xe_guc *
> exec_queue_to_guc(struct xe_exec_queue *q)
> {
[-- Attachment #2: Type: text/html, Size: 17651 bytes --]
next prev parent reply other threads:[~2025-09-30 3:29 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-29 2:55 [PATCH v3 00/36] VF migration redesign Matthew Brost
2025-09-29 2:55 ` [PATCH v3 01/36] drm/xe: Add NULL checks to scratch LRC allocation Matthew Brost
2025-09-30 2:06 ` Lis, Tomasz
2025-09-30 22:53 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 02/36] drm/xe/vf: Lock querying GGTT config during driver init Matthew Brost
2025-09-29 7:42 ` Michal Wajdeczko
2025-09-29 12:15 ` Matthew Brost
2025-09-30 0:42 ` Lis, Tomasz
2025-09-30 10:25 ` Michal Wajdeczko
2025-09-29 8:13 ` Ville Syrjälä
2025-09-30 13:22 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 03/36] Revert "drm/xe/vf: Rebase exec queue parallel commands during migration recovery" Matthew Brost
2025-09-30 15:22 ` Michal Wajdeczko
2025-09-29 2:55 ` [PATCH v3 04/36] Revert "drm/xe/vf: Post migration, repopulate ring area for pending request" Matthew Brost
2025-09-30 15:24 ` Michal Wajdeczko
2025-09-29 2:55 ` [PATCH v3 05/36] Revert "drm/xe/vf: Fixup CTB send buffer messages after migration" Matthew Brost
2025-09-30 15:27 ` Michal Wajdeczko
2025-09-29 2:55 ` [PATCH v3 06/36] drm/xe: Save off position in ring in which a job was programmed Matthew Brost
2025-09-29 2:55 ` [PATCH v3 07/36] drm/xe/guc: Track pending-enable source in submission state Matthew Brost
2025-09-29 2:55 ` [PATCH v3 08/36] drm/xe: Track LR jobs in DRM scheduler pending list Matthew Brost
2025-09-29 2:55 ` [PATCH v3 09/36] drm/xe: Don't change LRC ring head on job resubmission Matthew Brost
2025-09-30 2:38 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 10/36] drm/xe: Make LRC W/A scratch buffer usage consistent Matthew Brost
2025-09-29 2:55 ` [PATCH v3 11/36] drm/xe/guc: Document GuC submission backend Matthew Brost
2025-09-30 3:28 ` Lis, Tomasz [this message]
2025-09-30 6:30 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 12/36] drm/xe/vf: Add xe_gt_recovery_inprogress helper Matthew Brost
2025-09-29 8:04 ` Michal Wajdeczko
2025-09-29 8:52 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 13/36] drm/xe/vf: Make VF recovery run on per-GT worker Matthew Brost
2025-09-30 14:47 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 14/36] drm/xe/vf: Abort H2G sends during VF post-migration recovery Matthew Brost
2025-09-29 8:17 ` Michal Wajdeczko
2025-09-29 2:55 ` [PATCH v3 15/36] drm/xe/vf: Remove memory allocations from VF post migration recovery Matthew Brost
2025-09-30 15:00 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 16/36] drm/xe/vf: Close multi-GT GGTT shift race Matthew Brost
2025-09-29 8:44 ` Michal Wajdeczko
2025-09-29 12:31 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 17/36] drm/xe/vf: Teardown VF post migration worker on driver unload Matthew Brost
2025-09-30 16:24 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 18/36] drm/xe/vf: Don't allow GT reset to be queued during VF post migration recovery Matthew Brost
2025-09-29 9:17 ` Michal Wajdeczko
2025-09-29 12:50 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 19/36] drm/xe/vf: Wakeup in GuC backend on " Matthew Brost
2025-09-29 2:55 ` [PATCH v3 20/36] drm/xe/vf: Avoid indefinite blocking in preempt rebind worker for VFs supporting migration Matthew Brost
2025-10-01 13:45 ` Lis, Tomasz
2025-10-01 13:56 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 21/36] drm/xe/vf: Extra debug on GGTT shift Matthew Brost
2025-09-29 2:55 ` [PATCH v3 22/36] drm/xe/vf: Use GUC_HXG_TYPE_EVENT for GuC context register Matthew Brost
2025-09-29 2:55 ` [PATCH v3 23/36] drm/xe/vf: Flush and stop CTs in VF post migration recovery Matthew Brost
2025-09-29 21:31 ` Michal Wajdeczko
2025-09-29 2:55 ` [PATCH v3 24/36] drm/xe/vf: Reset TLB invalidations during " Matthew Brost
2025-10-01 13:53 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 25/36] drm/xe/vf: Kickstart after resfix in " Matthew Brost
2025-09-29 2:55 ` [PATCH v3 26/36] drm/xe/vf: Start CTs before resfix " Matthew Brost
2025-09-29 21:49 ` Michal Wajdeczko
2025-09-30 6:26 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 27/36] drm/xe/vf: Abort VF post migration recovery on failure Matthew Brost
2025-10-01 14:06 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 28/36] drm/xe/vf: Replay GuC submission state on pause / unpause Matthew Brost
2025-10-01 14:37 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 29/36] drm/xe: Move queue init before LRC creation Matthew Brost
2025-10-02 0:44 ` Lis, Tomasz
2025-10-02 7:36 ` Matthew Brost
2025-10-02 14:54 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 30/36] drm/xe/vf: Add debug prints for GuC replaying state during VF recovery Matthew Brost
2025-10-02 1:02 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 31/36] drm/xe/vf: Workaround for race condition in GuC firmware during VF pause Matthew Brost
2025-10-02 1:09 ` Lis, Tomasz
2025-10-02 6:12 ` Matthew Brost
2025-09-29 2:55 ` [PATCH v3 32/36] drm/xe: Use PPGTT addresses for TLB invalidation to avoid GGTT fixups Matthew Brost
2025-10-02 1:25 ` Lis, Tomasz
2025-09-29 2:55 ` [PATCH v3 33/36] drm/xe/vf: Use primary GT ordered work queue on media GT on PTL VF Matthew Brost
2025-09-29 2:55 ` [PATCH v3 34/36] drm/xe/vf: Ensure media GT VF recovery runs after primary GT on PTL Matthew Brost
2025-09-29 2:55 ` [PATCH v3 35/36] drm/xe/vf: Rebase CCS save/restore BB GGTT addresses Matthew Brost
2025-09-29 2:55 ` [PATCH v3 36/36] drm/xe/guc: Increase wait timeout to 2sec after BUSY reply from GuC Matthew Brost
2025-09-29 15:17 ` K V P, Satyanarayana
2025-09-30 12:39 ` Matthew Brost
2025-09-30 13:38 ` Michal Wajdeczko
2025-09-30 14:39 ` Matthew Brost
2025-09-29 3:06 ` ✗ CI.checkpatch: warning for VF migration redesign (rev3) Patchwork
2025-09-29 3:08 ` ✓ CI.KUnit: success " Patchwork
2025-09-29 6:28 ` ✗ Xe.CI.Full: failure " 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=a0b50db8-77bd-481e-bf80-2e8b762a1de5@intel.com \
--to=tomasz.lis@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.brost@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