kgd_gfx_v11_...cu_occupancy(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ kgd_gfx_v11_...cu_occupancy(9) ✨

okay so this is a page straight outta the Kernel API Manual (yes, that manual, the one your kernel-dev bestie keeps open in a tmux pane 🫢) and it's all about kgd_gfx_v11_get_cu_occupancy. stay with me, it's actually iconic.


🌸 NAME 🌸

kgd_gfx_v11_get_cu_occupancy β€” bestie, this one reads the relevant registers tied to each shader engine and then aggregates the number of waves that are in flight for the process whose pasid is passed in as a parameter. and like, plot twist: that process could have ZERO or more queues running and submitting waves to compute units. zero!! or more!! the range is giving chaos πŸ’€


πŸŽ€ SYNOPSIS πŸŽ€

void kgd_gfx_v11_get_cu_occupancy (struct amdgpu_device *adev , struct kfd_cu_occupancy *cu_occupancy , int *max_waves_per_cu , uint32_t inst );

that's the whole signature, copy it exactly, do not touch it, she is perfect πŸ’…


πŸ¦‹ ARGUMENTS πŸ¦‹

  • adev β€” the handle of the device you're pulling the number of waves in flight from. like, which GPU are we gossiping about today πŸ‘€
  • cu_occupancy β€” an array that gets filled up with wave_cnt and the doorbell offset, so you can compare later. it's literally a little notebook where the results get written down πŸ““
  • max_waves_per_cu β€” output parameter, gets updated with the maximum number of waves possible per Compute Unit. she's an output parameter, so she's leaving with new info, not arriving with it ✨
  • inst β€” the xcc's instance number on a multi-XCC setup. multi-XCC girlies know 🧚

πŸ’œ NOTE πŸ’œ

okay this is the part where you need to actually pay attention, no cap.

It's possible that the device has too many queues (oversubscription, dramatic much?) and in that case a VMID could be remapped to a different PASID. and that? that could lead to an inaccurate wave count 😭. following is the high-level sequence, keep up:

Time T1: vmid = getVmid; vmid is associated with Pasid P1 Time T2: passId = getPasId(vmid); vmid is associated with Pasid P2

so in that sequence above, the wave count obtained from time T1 will be incorrectly lost or added to the total wave count. yeah. it's giving race condition energy, and not the cute kind πŸ’€


⭐ the registers that provide the waves in flight ⭐

  • SPI_CSQ_WF_ACTIVE_STATUS β€” a bit-map of queues per pipe. the bit is ON if a queue is slotted, OFF if there is no queue. a process could have ZERO or more queues slotted and submitting waves to be run on compute units. and even when there is a queue, it's possible there could be zero wave fronts β€” this can happen when the queue is waiting on top-of-pipe events, e.g. a waitRegMem command. so like, slotted β‰  busy, iykyk 🫢

For each bit that is ON from above:

  1. Read the (SPI_CSQ_WF_ACTIVE_COUNT_0 + queue_idx) register. it provides the number of waves that are in flight for the queue at the specified index. the index ranges from 0 to 7. seven! not eight! don't @ me πŸ”₯
  2. If non-zero waves are in flight, store the corresponding doorbell offset of the queue, along with the wave count.
  3. Determine if the queue belongs to the process by comparing the doorbell offset against the process's queues. if it matches, aggregate the wave count for the process. that's your match made in heaven moment πŸ’–
  4. Reading the registers referenced above involves programming GRBM appropriately. periodt.

🌈 SEE ALSO 🌈


and that's the page, bestie, you ate that πŸ“

πŸ’… cute little sign-off: this one lives in ./drivers/gpu/drm/amd/amdgpu, dated October 2026, and she answers to the name kgd_gfx_v11_...cu_occupancy(9). go forth and count waves πŸ‘‘
πŸ“¦ where this page comes from