On 9/3/2021 12:59, Daniele Ceraolo Spurio wrote:
From: Matthew Brost matthew.brost@intel.com
Add GuC kernel doc for all structures added thus far for GuC submission and update the main GuC submission section with the new interface details.
v2:
- Drop guc_active.lock DOC
v3:
- Fixup a few kernel doc comments (Daniele)
v4 (Daniele):
- Implement doc suggestions from John
- Add kerneldoc for all members of the GuC structure and pull the file in i915.rst
v5 (Daniele):
- Implement new doc suggestions from John
Signed-off-by: Matthew Brost matthew.brost@intel.com Signed-off-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Cc: John Harrison John.C.Harrison@Intel.com
Reviewed-by: John Harrison John.C.Harrison@Intel.com
Documentation/gpu/i915.rst | 2 + drivers/gpu/drm/i915/gt/intel_context_types.h | 43 +++++--- drivers/gpu/drm/i915/gt/uc/intel_guc.h | 75 ++++++++++--- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 100 ++++++++++++++---- drivers/gpu/drm/i915/i915_request.h | 21 ++-- 5 files changed, 181 insertions(+), 60 deletions(-)
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 101dde3eb1ea..311e10400708 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -495,6 +495,8 @@ GuC .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c :doc: GuC
+.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.h
- GuC Firmware Layout
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 5285d660eacf..930569a1a01f 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -156,40 +156,51 @@ struct intel_context { u8 wa_bb_page; /* if set, page num reserved for context workarounds */
struct {
/** lock: protects everything in guc_state */
spinlock_t lock; /**/** @lock: protects everything in guc_state */
* sched_state: scheduling state of this context using GuC
* @sched_state: scheduling state of this context using GuC
*/ u32 sched_state; /*
- submission
* fences: maintains of list of requests that have a submit
* fence related to GuC submission
* @fences: maintains a list of requests that are currently
*/ struct list_head fences;* being fenced until a GuC operation completes
/* GuC context blocked fence */
/**
* @blocked: fence used to signal when the blocking of a
* context's submissions is complete.
struct i915_sw_fence blocked;*/
/* GuC committed requests */
int number_committed_requests;/** @number_committed_requests: number of committed requests */
/** requests: active requests on this context */
struct list_head requests;/** @requests: list of active requests on this context */
/*
* GuC priority management
*/
/** @prio: the context's current guc priority */
u8 prio;
/**
* @prio_count: a counter of the number requests in flight in
* each priority bucket
*/
u32 prio_count[GUC_CLIENT_PRIORITY_NUM]; } guc_state;
struct {
/* GuC LRC descriptor ID */
/**
* @id: handle which is used to uniquely identify this context
* with the GuC, protected by guc->contexts_lock
u16 id;*/
/* GuC LRC descriptor reference count */
/**
* @ref: the number of references to the guc_id, when
* transitioning in and out of zero protected by
* guc->contexts_lock
atomic_t ref;*/
/*
* GuC ID link - in list when unpinned but guc_id still valid in GuC
/**
* @link: in guc->guc_id_list when the guc_id has no refs but is
*/ struct list_head link; } guc_id;* still valid, protected by guc->contexts_lock
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 2e27fe59786b..5dd174babf7a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -22,74 +22,121 @@
struct __guc_ads_blob;
-/*
- Top level structure of GuC. It handles firmware loading and manages client
- pool. intel_guc owns a intel_guc_client to replace the legacy ExecList
- submission.
+/**
- struct intel_guc - Top level structure of GuC.
- It handles firmware loading and manages client pool. intel_guc owns an
*/ struct intel_guc {
- i915_sched_engine for submission.
- /** @fw: the GuC firmware */ struct intel_uc_fw fw;
- /** @log: sub-structure containing GuC log related data and objects */ struct intel_guc_log log;
- /** @ct: the command transport communication channel */ struct intel_guc_ct ct;
- /** @slpc: sub-structure containing SLPC related data and objects */ struct intel_guc_slpc slpc;
- /* Global engine used to submit requests to GuC */
/** @sched_engine: Global engine used to submit requests to GuC */ struct i915_sched_engine *sched_engine;
/**
* @stalled_request: if GuC can't process a request for any reason, we
* save it until GuC restarts processing. No other request can be
* submitted until the stalled request is processed.
*/
struct i915_request *stalled_request;
/* intel_guc_recv interrupt related state */
/** @irq_lock: protects GuC irq state */ spinlock_t irq_lock;
/**
* @msg_enabled_mask: mask of events that are processed when receiving
* an INTEL_GUC_ACTION_DEFAULT G2H message.
*/
unsigned int msg_enabled_mask;
/**
* @outstanding_submission_g2h: number of outstanding GuC to Host
* responses related to GuC submission, used to determine if the GT is
* idle
*/
atomic_t outstanding_submission_g2h;
/** @interrupts: pointers to GuC interrupt-managing functions. */ struct { void (*reset)(struct intel_guc *guc); void (*enable)(struct intel_guc *guc); void (*disable)(struct intel_guc *guc); } interrupts;
- /*
* contexts_lock protects the pool of free guc ids and a linked list of
* guc ids available to be stolen
/**
* @contexts_lock: protects guc_ids, guc_id_list, ce->guc_id.id, and
* ce->guc_id.ref when transitioning in and out of zero
*/ spinlock_t contexts_lock;
/** @guc_ids: used to allocate unique ce->guc_id.id values */ struct ida guc_ids;
/**
* @guc_id_list: list of intel_context with valid guc_ids but no refs
*/
struct list_head guc_id_list;
/**
* @submission_supported: tracks whether we support GuC submission on
* the current platform
*/
bool submission_supported;
/** @submission_selected: tracks whether the user enabled GuC submission */ bool submission_selected;
/**
* @rc_supported: tracks whether we support GuC rc on the current platform
*/
bool rc_supported;
/** @rc_selected: tracks whether the user enabled GuC rc */ bool rc_selected;
/** @ads_vma: object allocated to hold the GuC ADS */ struct i915_vma *ads_vma;
/** @ads_blob: contents of the GuC ADS */ struct __guc_ads_blob *ads_blob;
/** @ads_regset_size: size of the save/restore regsets in the ADS */ u32 ads_regset_size;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */ u32 ads_golden_ctxt_size;
/** @lrc_desc_pool: object allocated to hold the GuC LRC descriptor pool */ struct i915_vma *lrc_desc_pool;
/** @lrc_desc_pool_vaddr: contents of the GuC LRC descriptor pool */ void *lrc_desc_pool_vaddr;
- /* guc_id to intel_context lookup */
- /**
* @context_lookup: used to resolve intel_context from guc_id, if a
* context is present in this structure it is registered with the GuC
struct xarray context_lookup;*/
- /* Control params for fw initialization */
- /** @params: Control params for fw initialization */ u32 params[GUC_CTL_MAX_DWORDS];
- /* GuC's FW specific registers used in MMIO send */
- /** @send_regs: GuC's FW specific registers used for sending MMIO H2G */ struct { u32 base; unsigned int count; enum forcewake_domains fw_domains; } send_regs;
- /* register used to send interrupts to the GuC FW */
- /** @notify_reg: register used to send interrupts to the GuC FW */ i915_reg_t notify_reg;
- /* Store msg (e.g. log flush) that we see while CTBs are disabled */
- /**
* @mmio_msg: notification bitmask that the GuC writes in one of its
* registers when the CT channel is disabled, to be processed when the
* channel is back up.
u32 mmio_msg;*/
- /* To serialize the intel_guc_send actions */
- /** @send_mutex: used to serialize the intel_guc_send actions */ struct mutex send_mutex; };
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 6a894c3b7925..6997078ae1ac 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -28,21 +28,6 @@ /**
- DOC: GuC-based command submission
- IMPORTANT NOTE: GuC submission is currently not supported in i915. The GuC
- firmware is moving to an updated submission interface and we plan to
- turn submission back on when that lands. The below documentation (and related
- code) matches the old submission model and will be updated as part of the
- upgrade to the new flow.
- GuC stage descriptor:
- During initialization, the driver allocates a static pool of 1024 such
- descriptors, and shares them with the GuC. Currently, we only use one
- descriptor. This stage descriptor lets the GuC know about the workqueue and
- process descriptor. Theoretically, it also lets the GuC know about our HW
- contexts (context ID, etc...), but we actually employ a kind of submission
- where the GuC uses the LRCA sent via the work item instead. This is called
- a "proxy" submission.
- The Scratch registers:
- There are 16 MMIO-based registers start from 0xC180. The kernel driver writes
- a value to the action register (SOFT_SCRATCH_0) along with any data. It then
@@ -51,14 +36,85 @@
- processes the request. The kernel driver polls waiting for this update and
- then proceeds.
- Work Items:
- There are several types of work items that the host may place into a
- workqueue, each with its own requirements and limitations. Currently only
- WQ_TYPE_INORDER is needed to support legacy submission via GuC, which
- represents in-order queue. The kernel driver packs ring tail pointer and an
- ELSP context descriptor dword into Work Item.
- See guc_add_request()
- Command Transport buffers (CTBs):
- Covered in detail in other sections but CTBs (Host to GuC - H2G, GuC to Host
- G2H) are a message interface between the i915 and GuC.
- Context registration:
- Before a context can be submitted it must be registered with the GuC via a
- H2G. A unique guc_id is associated with each context. The context is either
- registered at request creation time (normal operation) or at submission time
- (abnormal operation, e.g. after a reset).
- Context submission:
- The i915 updates the LRC tail value in memory. The i915 must enable the
- scheduling of the context within the GuC for the GuC to actually consider it.
- Therefore, the first time a disabled context is submitted we use a schedule
- enable H2G, while follow up submissions are done via the context submit H2G,
- which informs the GuC that a previously enabled context has new work
- available.
- Context unpin:
- To unpin a context a H2G is used to disable scheduling. When the
- corresponding G2H returns indicating the scheduling disable operation has
- completed it is safe to unpin the context. While a disable is in flight it
- isn't safe to resubmit the context so a fence is used to stall all future
- requests of that context until the G2H is returned.
- Context deregistration:
- Before a context can be destroyed or if we steal its guc_id we must
- deregister the context with the GuC via H2G. If stealing the guc_id it isn't
- safe to submit anything to this guc_id until the deregister completes so a
- fence is used to stall all requests associated with this guc_id until the
- corresponding G2H returns indicating the guc_id has been deregistered.
- guc_ids:
- Unique number associated with private GuC context data passed in during
- context registration / submission / deregistration. 64k available. Simple ida
- is used for allocation.
- Stealing guc_ids:
- If no guc_ids are available they can be stolen from another context at
- request creation time if that context is unpinned. If a guc_id can't be found
- we punt this problem to the user as we believe this is near impossible to hit
- during normal use cases.
- Locking:
- In the GuC submission code we have 3 basic spin locks which protect
- everything. Details about each below.
- sched_engine->lock
- This is the submission lock for all contexts that share an i915 schedule
- engine (sched_engine), thus only one of the contexts which share a
- sched_engine can be submitting at a time. Currently only one sched_engine is
- used for all of GuC submission but that could change in the future.
- guc->contexts_lock
- Protects guc_id allocation for the given GuC, i.e. only one context can be
- doing guc_id allocation operations at a time for each GuC in the system.
- ce->guc_state.lock
- Protects everything under ce->guc_state. Ensures that a context is in the
- correct state before issuing a H2G. e.g. We don't issue a schedule disable
- on a disabled context (bad idea), we don't issue a schedule enable when a
- schedule disable is in flight, etc... Also protects list of inflight requests
- on the context and the priority management state. Lock is individual to each
- context.
- Lock ordering rules:
- sched_engine->lock -> ce->guc_state.lock
- guc->contexts_lock -> ce->guc_state.lock
- Reset races:
- When a full GT reset is triggered it is assumed that some G2H responses to
- H2Gs can be lost as the GuC is also reset. Losing these G2H can prove to be
- fatal as we do certain operations upon receiving a G2H (e.g. destroy
- contexts, release guc_ids, etc...). When this occurs we can scrub the
- context state and cleanup appropriately, however this is quite racey.
- To avoid races, the reset code must disable submission before scrubbing for
- the missing G2H, while the submission code must check for submission being
- disabled and skip sending H2Gs and updating context states when it is. Both
- sides must also make sure to hold the relevant locks.
*/
/* GuC Virtual Engine */
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index d818cfbfc41d..7bd9ed20623e 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -290,18 +290,23 @@ struct i915_request { struct hrtimer timer; } watchdog;
- /*
* Requests may need to be stalled when using GuC submission waiting for
* certain GuC operations to complete. If that is the case, stalled
* requests are added to a per context list of stalled requests. The
* below list_head is the link in that list.
/**
* @guc_fence_link: Requests may need to be stalled when using GuC
* submission waiting for certain GuC operations to complete. If that is
* the case, stalled requests are added to a per context list of stalled
* requests. The below list_head is the link in that list. Protected by
* ce->guc_state.lock.
*/ struct list_head guc_fence_link;
/**
* Priority level while the request is inflight. Differs from i915
* scheduler priority. See comment above
* I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details.
* @guc_prio: Priority level while the request is in flight. Differs
* from i915 scheduler priority. See comment above
* I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details. Protected by
* ce->guc_active.lock. Two special values (GUC_PRIO_INIT and
* GUC_PRIO_FINI) outside the GuC priority range are used to indicate
* if the priority has not been initialized yet or if no more updates
*/ #define GUC_PRIO_INIT 0xff #define GUC_PRIO_FINI 0xfe* are possible because the request has completed.