GUC-BASED COMMAND SUBMISSION(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… GuC-based co...d submission(9) πŸ’…

Kernel API Manual β€” bestie, this is the GuC-based command submission page, and we are about to make the whole thing make sense. 🫢✨

Okay so, lowkey, this is deep kernel lore, but it's giving main character energy. Let's go.

🌸 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 triggers an interrupt on the GuC via another register write (0xC4C8). Firmware writes a success/fail code back to the action register after processes the request. The kernel driver polls waiting for this update and then proceeds.

πŸ¦‹ 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. Because this interaction with the GuC takes a non-zero amount of time we delay the disabling of scheduling after the pin count goes to zero by a configurable period of time (see SCHED_DISABLE_DELAY_MS). The thought is this gives the user a window of time to resubmit something on the context before doing this costly operation. This delay is only done if the context isn't closed and the guc_id usage is less than a threshold (see NUM_SCHED_DISABLE_GUC_IDS_THRESHOLD).

πŸ“ 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.

πŸ‘‘ submission_state.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->submission_state.lock β€” Global lock for GuC submission state. Protects guc_ids and destroyed contexts list.
  • 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->submission_state.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.

πŸ‘€ SEE ALSO πŸ‘€

  • Kernel file ./drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

Okay that's the whole page, bestie! πŸ’– Cute little footer energy: source/version is ./drivers/gpu/drm/i915/gt/uc, dated October 2026, and the page is GuC-based co...d submission(9). Slay and goodbye! βœ¨πŸ’…

πŸ“¦ where this page comes from