Skip to content

Topic/drm amdgpu kfd pin reaper#216

Open
chun-wan wants to merge 2668 commits into
ROCm:masterfrom
chun-wan:topic/drm-amdgpu-kfd-pin-reaper
Open

Topic/drm amdgpu kfd pin reaper#216
chun-wan wants to merge 2668 commits into
ROCm:masterfrom
chun-wan:topic/drm-amdgpu-kfd-pin-reaper

Conversation

@chun-wan
Copy link
Copy Markdown

@chun-wan chun-wan commented May 20, 2026

Introduce a new KFD-side subsystem that lets multi-tenant HIP/AMDGPU
serving workloads opt the free / unpin paths into bounded-wait failure
modes instead of either silently orphaning RDMA-pinned BOs or
deadlocking on a wedged peer driver. All five new module parameters
default to 0 (feature off); the resulting code paths are byte-identical
to the existing upstream behaviour when none are set.

amdgpu_kfd_free_wait_ms max ms to bounded-wait on pin_count==0
in amdgpu_amdkfd_gpuvm_free_memory_of_gpu()
when hipFree() hits an RDMA-pinned BO

amdgpu_kfd_unpin_drain_ms strict dma_resv_wait_timeout deadline
in the unpin path -- prevents an
in-flight peer-RDMA WR from racing the
pin_count drop and faulting the peer

amdgpu_kfd_free_on_pinned policy switch (0 = legacy orphan,
1 = bounded wait + queue for reaper)

amdgpu_pin_orphan_timeout_ms age (ms) at which the reaper force-
unpins a BO parked on the orphan list

amdgpu_pin_reaper_interval_ms tick interval (ms) of the reaper
background delayed_work

Motivation

In multi-tenant HIP serving workloads, RDMA peer drivers (e.g. the
NIC-side rdma_pin or peer-mem shim) hold pin_count > 0 on KFD BOs
across the lifetime of in-flight RDMA WRs. When userspace calls
hipFree() on such a BO upstream amdgpu either:

  1. silently keeps the BO alive until process exit (memory leak
    that accumulates over hours of serving), or
  2. blocks the unpin path indefinitely if the peer driver is
    wedged (one stuck NIC turns into a process-wide free-path stall).

The five knobs introduced here let operators opt the KFD layer into a
controlled non-leak / non-deadlock policy:

  • hipFree() bounded-waits up to amdgpu_kfd_free_wait_ms for the peer
    to drop the pin (typical: 2-4 seconds);
  • if the peer is still holding, the BO is queued for the orphan
    reaper, which periodically (amdgpu_pin_reaper_interval_ms) walks
    the list and force-unpins entries older than
    amdgpu_pin_orphan_timeout_ms;
  • the unpin path itself uses amdgpu_kfd_unpin_drain_ms to bound the
    dma_resv_wait_timeout() that drains in-flight fences before
    pin_count is decremented, so a wedged peer cannot park the unpin
    caller indefinitely.

Technical Details

NEW FILE

  • drivers/gpu/drm/amd/amdgpu/amdgpu_kfd_pin_reaper.c
    amdgpu_kfd_unpin_drain() bounded dma_resv_wait_timeout()
    amdgpu_kfd_wait_pin_drop() exp-backoff poll on pin_count==0
    amdgpu_kfd_orphan_queue() queue BO onto adev->kfd.orphan_list
    amdgpu_kfd_reaper_fn() delayed_work callback that walks the
    orphan list and force-unpins aged
    entries
    amdgpu_kfd_reaper_start() one-shot init from device_init
    amdgpu_kfd_reaper_stop() one-shot teardown from device_fini

MODIFIED

  • drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
    Add struct kfd_orphan_pin (queue node).
    Add 9 new fields to struct amdgpu_kfd_dev: orphan list spinlock,
    list head, reaper delayed_work, atomic64 stat counters
    (rdma_pin_orphans_queued/reaped, free_wait_pinned_count/timeout,
    unpin_drain_timeouts), reaper_started bool.
    Add function declarations for the helpers + reaper lifecycle.

  • drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
    amdgpu_amdkfd_device_init() -> amdgpu_kfd_reaper_start(adev)
    amdgpu_amdkfd_device_fini_sw() -> amdgpu_kfd_reaper_stop(adev)
    (reaper_stop is called first so the worker exits before
    adev->kfd.dev is torn down).

  • drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
    amdgpu_amdkfd_gpuvm_free_memory_of_gpu() gains a small policy
    block that runs only when mem->bo->tbo.pin_count > 0 AND
    amdgpu_kfd_free_on_pinned >= 1. When the bounded wait times
    out the BO is queued via amdgpu_kfd_orphan_queue() and
    hipFree() returns success to userspace; the BO is reclaimed
    either when the peer releases the pin or forcibly by the reaper.

  • drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
    Five new module_param_named() declarations with DOC comments.

  • drivers/gpu/drm/amd/amdgpu/amdgpu.h
    Five new extern int declarations.

  • drivers/gpu/drm/amd/amdgpu/Makefile
    Add amdgpu_kfd_pin_reaper.o to amdgpu-y.

Default behaviour

All five module parameters default to 0. When none are set:

  • amdgpu_kfd_reaper_start() initialises the orphan list and atomic
    counters but does NOT schedule the reaper delayed_work (because
    amdgpu_pin_reaper_interval_ms == 0); the worker never runs.
  • The free-on-pinned policy block in free_memory_of_gpu() is gated
    by amdgpu_kfd_free_on_pinned >= 1, so it is a no-op.
  • amdgpu_kfd_unpin_drain() returns 0 immediately when its timeout
    argument is 0.

Net behavioural diff on stock callers: zero.

JIRA ID

ROCM-21571

Test Plan

Reproducer: multi-tenant HIP serving with RDMA peer driver holding
pin_count across hipFree(). Open-source reproducer to be added in a
follow-up test patch.

Expected behaviour:

  • All five envs unset (default): unchanged. hipFree() on a pinned
    BO leaks (legacy) as before.
  • amdgpu_kfd_free_on_pinned=1, kfd_free_wait_ms=4000,
    pin_orphan_timeout_ms=10000, pin_reaper_interval_ms=2000:
    hipFree on a pinned BO either waits up to 4 s for the peer to
    release (and then frees cleanly), or queues the BO for the
    reaper. The reaper ticks every 2 s and force-unpins anything
    older than 10 s.

Test Result

11+ hours of multi-tenant HIP serving load on a customer MI300X
stable with the five envs set per the recipe above; orphan reaper
queued / reaped counters match expectations (queued == reaped over
the run), and no memory leak observed across 32-cycle stress
sweep. Default-off run passes existing KFD self-tests
byte-identically.

Submission Checklist

Signed-off-by: chun-wan chun-wan@users.noreply.github.com

superm1 and others added 30 commits October 28, 2025 10:49
Some drivers have different flows for hibernation and suspend. If
the driver opportunistically will skip thaw() then it needs a hint
to know what is happening after the hibernate.

Introduce a new symbol pm_hibernation_mode_is_suspend() that drivers
can call to determine if suspending the system for this purpose.

Tested-by: Ionut Nechita <ionut_n2001@yahoo.com>
Tested-by: Kenneth Crudup <kenny@panix.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
(cherry picked from commit 495c8d3)
[Why]
commit 530694f ("drm/amdgpu: do not resume device in thaw for
normal hibernation") optimized the flow for systems that are going
into S4 where the power would be turned off.  Basically the thaw()
callback wouldn't resume the device if the hibernation image was
successfully created since the system would be powered off.

This however isn't the correct flow for a system entering into
s0i3 after the hibernation image is created.  Some of the amdgpu
callbacks have different behavior depending upon the intended
state of the suspend.

[How]
Use pm_hibernation_mode_is_suspend() as an input to decide whether
to run resume during thaw() callback.

Reported-by: Ionut Nechita <ionut_n2001@yahoo.com>
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4573
Tested-by: Ionut Nechita <ionut_n2001@yahoo.com>
Fixes: 530694f ("drm/amdgpu: do not resume device in thaw for normal hibernation")
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Tested-by: Kenneth Crudup <kenny@panix.com>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Cc: 6.17+ <stable@vger.kernel.org> # 6.17+: 495c8d3: PM: hibernate: Add pm_hibernation_mode_is_suspend()
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
(cherry picked from commit 0a6e9e0)
It's caused by the commit:  1fcbc0b6a8
"drm/amd: Fix hybrid sleep"

Signed-off-by: Chengjun Yao <Chengjun.Yao@amd.com>
Reviewed-by: Bob Zhou <Bob.Zhou@amd.com>
Signed-off-by: Yang Su <Yang.Su2@amd.com>
Signed-off-by: Yang Su <Yang.Su2@amd.com>
Add gpu metrics definition which is only a set of gpu metrics
attributes. A field is encoded by its id, type and number of instances.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Asad Kamal <asad.kamal@amd.com>
a. hmm_range is either NULL or a valid pointer so we
do not need to set range to NULL ever.

b. keep the hmm_range_free in the end irrespective of
the other conditions to avoid some additional checks
and also avoid double free issue.

Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
These were not set so soft recovery was inadvertantly
disabled.

Fixes: 6ac55ea ("drm/amdgpu: move reset support type checks into the caller")
Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Update asic_invalidate_hdp and asic_flush_hdp function to check if ip
function exist, if not return void

v2: Use else/if (Kevin)
    Update function name (Lijo)

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Move everything to the supported resets masks rather than
having an explicit misc checks for this.

Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Remove the NULL check from amdgpu_hmm_range_free for hmm_pfns
as caller is responsible not to call amdgpu_hmm_range_free
more than once.

Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
…EDID"

This reverts commit 11b66b2.
It's caused the Jira ticket: SWDEV-563655, so revert it temporarily.

Signed-off-by: Chengjun Yao <Chengjun.Yao@amd.com>
Read CPER raw data from debugfs node "/sys/kernel/debug/dri/*/
amdgpu_ring_cper".

Signed-off-by: Xiang Liu <xiang.liu@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Change-Id: I01753bf4a1052a22144f6c2758a39d2b91c2212d
Remove amdgpu_asic_flush_hdp & amdgpu_asic_invalidate_hdp functions and
directly use the mapped ones

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Fix the error:
drivers/gpu/drm/amd/amdgpu/../ras/ras_mgr/amdgpu_ras_mgr.c:132:undefined reference to `__udivdi3'

Fixs:b5bae0f01786d("drm/amd/ras: Add amdgpu ras management function")
Reported-by: kernel test robot <lkp@intel.com>
Closes:https://lore.kernel.org/oe-kbuild-all/202510272144.6SUHUoWx-lkp@intel.com/
Signed-off-by: YiPeng Chai <YiPeng.Chai@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Fix error injection parameter error.

Signed-off-by: YiPeng Chai <YiPeng.Chai@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
The IPID register value for bad page threshold CPER holds socket_id info
now according to the latest definition.

Signed-off-by: Xiang Liu <xiang.liu@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Change-Id: I847509f0282e246a171194c4fdbe1dfe0b297bb0
When the EDID of an analog display is not available, we can't
know the possible modes supported by the display. However, we
still need to offer the user to select from a variety of common
modes. It will be up to the user to select the best one, though.

This is how it works on other operating systems as well as the
legacy display code path in amdgpu.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Check if we have an amdgpu_dm_connector->dc_sink first before
adding common modes for analog outputs. If we don't have a
sink yet we can safely skip this.

Fixes: 0c9f9ca99238 ("drm/amd/display: Add common modes to analog displays without EDID")
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Yang Su <Yang.Su2@amd.com>
Signed-off-by: Yang Su <Yang.Su2@amd.com>
v1:
the driver should handle return value of smu_v13_0_6_printk_clk_levels()
to return the correct size for sysfs reads.

v2:
fix the issue of size calculation error in smu_v13_0_6_print_clks()

Fixes: 0354cd650daa ("drm/amd/pm: Avoid writing nulls into `pp_od_clk_voltage`")

Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Use the correct label to complete all cleanup work.

Fixes: 4d154b1 ("drm/amd/pm: Add support for DPM policies")
Fixes: d2e690ff5d3cf ("drm/amd/pm: Add temperature metrics sysfs entry")

Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Add helper macros to define metrics struct definitions. It will define
structs with field type followed by actual field. A helper macro is also
added to initialize the field encoding for all fields and to initialize
the field members to 0xFFs.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Asad Kamal <asad.kamal@amd.com>
Fill and publish GPU metrics in v1.9 format for SMUv13.0.6 SOCs

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Asad Kamal <asad.kamal@amd.com>
The contents of si_dpm.h seem to have been copied from the
old radeon driver, including a lot of structs and fields which
were only relevant to GPU generations even older than SI.

A lot of these can be deleted without causing much churn to the
actual SI DPM code. Let's delete them to make the code easier
to understand.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
No functional modification involved.

./drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c:1674:3-4: Unneeded semicolon.

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=26821
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
No functional modification involved.

./drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c:1850:3-4: Unneeded semicolon.

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=26821
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
No functional modification involved.

./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:7392:3-4: Unneeded semicolon.

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=26821
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Commit e6a8a00 ("drm/amd/display: Rename dml2 to dml2_0 folder")
renames the directory dml2 to dml2_0 in ./drivers/gpu/drm/amd/display/dc,
but misses to adjust the file entry in AMD DISPLAY CORE - DML.

Adjust the file entry after this directory renaming.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Jie1zhang and others added 29 commits February 4, 2026 21:03
Resetting VCN resets the entire tile, including jpeg.
When resetting the VCN, we need to ensure that JPEG data blocks are accessible and we also need to handle the JPEG queue.
Add a helper function to restore the JPEG queue during the VCN reset.

v2: split the jpeg helper in two, in the top helper we can stop the sched workqueues and attempt to wait for any outstanding fences.
    Then in the bottom helper, we can force completion, re-init the rings, and restart the sched workqueues (Alex)

v3: merge patches 4 and 5 into one patch (Alex)

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Fix the vcn reset sequence in vcn_v4_0_3_ring_reset() to restore
JPEG power state and unlock the JPEG powergating mutex before
running the JPEG ring post-reset helper.

Fixes: c50beca39115 ("drm/amdgpu/vcn4.0.3: rework reset handling")

Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Ensure GFX engine is idle before switching PTL state to prevent
register access violations and CP hang. This addresses the race
condition where in-flight GPU commands could conflict with PTL
state changes.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
KIQ access is not guaranteed to work reliably under all reset
situations. Avoid flooding dmesg with HDP flush failure messages.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
sdma ring reset is not supported in SRIOV. kfd driver does not check
reset mask, and could queue sdma ring reset during unmap_queues_cpsch.

Avoid the ring reset for sriov.

Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
v4:
use func "amdgpu_gfx_get_hdp_flush_mask" to get ref_and_mask for
gfx9 through gfx12.

v3:
Unify the get_ref_and_mask function in amdgpu_gfx_funcs,
to support both GFX11 and earlier generations

v2:
place "get_ref_and_mask" in amdgpu_gfx_funcs instead of amdgpu_ring,
since this function only assigns the cp entry.

v1:
both gfx ring and mes ring use cp0 to flush hdp, cause conflict.

use function get_ref_and_mask to assign the cp entry.
reassign mes to use cp8 instead.

Signed-off-by: chong li <chongli2@amd.com>
Acked-by: Lijo Lazar <lijo.lazar@amd.com>
This patch allows kfd driver function correctly when AMD gpu devices got
unplug/replug at run time.

When an AMD gpu device got unplug kfd driver gracefully terminates existing
kfd processes after stops all queues by sending SIGBUS to user process. After
that user space can still use remaining AMD gpu devices. When all AMD gpu
devices at system got removed kfd driver will not response new requests.

Unplugged AMD gpu devices can be re-plugged. kfd driver will use added devices
to function as usual.

The purpose of this patch is having kfd driver behavior as expected during and
after AMD gpu devices unplug/replug at run time.

Signed-off-by: Xiaogang Chen<Xiaogang.Chen@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit a482d054b7e7c7f2a35161d79e6629fa0f7f29d1)

Change-Id: Ie33ea428914708546f7f96a627747f01bc6fcfdd
… paths

Ungate GPU CG/PG in device_fini_hw and device_halt to protect GPU
register accesses, e.g. GC registers are accessed in amdgpu_irq_disable_all()
and amdgpu_fence_driver_hw_fini().

Signed-off-by: Yifan Zhang <yifan1.zhang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
(cherry picked from commit 33fe740db26e0c94791dde8b2926d3ab36c9e6ae)

Change-Id: I09895beaff20b3caf125b15e17bc330392552393
This reverts commit c61fab0.

Reason for revert: revert the patch as it causes performance drop,tested by CE team. revert this patch requested by management team.

Change-Id: I0db3f9f819554566e259bbb1292e7690db958ced
…ntation

Separate the PTL (Peak Tops Limiter) control logic into a stable public
API layer and an internal implementation layer.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Add F8 and VECTOR to amdgpu_ptl_fmt and PSP format mapping.
Update PTL format strings and GFX format enum to keep PSP/KFD in sync.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Use a bitmap to track PTL disable requests from sysfs and profiler.
PTL is only re-enabled once all sources have released their disable
requests, avoiding premature enablement.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Add a new kernel module parameter 'amdgpu.ptl' to allow
users to enable or disable PTL feature at driver loading time.

Parameter values:
  *) 0 or -1: disable PTL (default)
  *) 1: enable PTL
  *) 2: permanently disable PTL

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Add an explicit check on cmd->resp.status after psp_cmd_submit_buf()
returns to ensure PTL state is only updated on actual success.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
…ces"

This reverts commit 1562589.

Reason for revert: <this patch breaks dkms install>

Change-Id: If54b6c5f703eb136db61770d5ddafcba22bf4620
Invalidating a dmabuf will impact other users of the shared BO.
In the scenario where process A moves the BO, it needs to inform
process B about the move and process B will need to update its
page table.

The commit fixes a synchronisation bug caused by the use of the
ticket: it made amdgpu_vm_handle_moved behave as if updating
the page table immediately was correct but in this case it's not.

An example is the following scenario, with 2 GPUs and glxgears
running on GPU0 and Xorg running on GPU1, on a system where P2P
PCI isn't supported:

glxgears:
  export linear buffer from GPU0 and import using GPU1
  submit frame rendering to GPU0
  submit tiled->linear blit
Xorg:
  copy of linear buffer

The sequence of jobs would be:
  drm_sched_job_run                       # GPU0, frame rendering
  drm_sched_job_queue                     # GPU0, blit
  drm_sched_job_done                      # GPU0, frame rendering
  drm_sched_job_run                       # GPU0, blit
  move linear buffer for GPU1 access      #
  amdgpu_dma_buf_move_notify -> update pt # GPU0

It this point the blit job on GPU0 is still running and would
likely produce a page fault.

Cc: stable@vger.kernel.org
Fixes: a448cb0 ("drm/amdgpu: implement amdgpu_gem_prime_move_notify v2")
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Firmware and monitoring tools may not be ready to receive a CPER when we
read the bad pages, so send the CPERs at the end of RAS initialization
to ensure that the FW is ready to receive and process the CPER. This
removes the previous CPER submission that was added during bad page
load, and sends both in-band and out-of-band at the same time.

Signed-off-by: Kent Russell <kent.russell@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
This patch allows kfd driver function correctly when AMD gpu devices got
unplug/replug at run time.

When an AMD gpu device got unplug kfd driver gracefully terminates existing
kfd processes after stops all queues by sending SIGBUS to user process. After
that user space can still use remaining AMD gpu devices. When all AMD gpu
devices at system got removed kfd driver will not response new requests.

Unplugged AMD gpu devices can be re-plugged. kfd driver will use added devices
to function as usual.

The purpose of this patch is having kfd driver behavior as expected during and
after AMD gpu devices unplug/replug at run time.

Signed-off-by: Xiaogang Chen<Xiaogang.Chen@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
GC 9.4.4 uses SPI busy status for idle detection instead of GRBM GUI_ACTIVE.
Add version check to use SPI_BUSY for 9.4.4 while keeping GRBM_STATUS
GUI_ACTIVE check for other GC versions.

v2: move this check into amdgpu_ptl_perf_monitor_ctrl(Lijo)

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Move amdgpu_amdkfd_stop/start_sched calls from kfd_ptl_control()
into amdgpu_ptl_perf_monitor_ctrl() so all PTL callers (KFD ioctl,
sysfs, GFX init) get consistent scheduling management.

Add amdgpu_amdkfd_stop/start_sched_all() wrappers to stop and
restart KFD scheduling on all nodes without assuming node ID ordering.

v3:
 * call start/stop for PTL Set Only
v2:
 * move the stop/start sched function to
   amdgpu_ptl_perf_monitor_ctrl(Lijo)
 * add wrapper amdgpu_amdkfd_stop_sched_all and
   amdgpu_amdkfd_start_sched_all (Lijo)

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Set the AMDGPU_PTL_DISABLE_SYSFS bit in adev->psp.disable_bitmap during
gfx_v9_4_3_perf_monitor_ptl_init(). This ensures that PTL is initially
disabled via the SYSFS mechanism, matching the intended default state
and preventing unintended PTL enablement before explicit user action.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Create PTL sysfs in xgmi_reset_on_init restore path for MINIMAL_XGMI

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Downgrade unhalt_cpsch warning to dev_dbg when sched is already stopped

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
Only set the bit when PTL is actually being disabled (state=0)

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
end the function flow when ras table checksum is error

Signed-off-by: Gangliang Xie <ganglxie@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Kent Russell <kent.russell@amd.com>
Handle RAS eeprom record when UMC_CHANNEL_IDX_V2 is set.

v2: get UMC_CHANNEL_IDX_V2 flag before the clear of it.

Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Make eeprom data and its counter consistent.

Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Fix this by skipping the sysfs disable mapping when the GPU is
currently undergoing a reset or suspend flow.
Additionally, add debug logging in psp_ptl_invoke() to better
trace PTL state and format queries/updates cmd.

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com>
…dparams)

Introduce a new KFD-side subsystem that lets multi-tenant HIP/AMDGPU
serving workloads opt the free / unpin paths into bounded-wait failure
modes instead of either silently orphaning RDMA-pinned BOs or
deadlocking on a wedged peer driver.  All five new module parameters
default to 0 (feature off); the resulting code paths are byte-identical
to the existing upstream behaviour when none are set.

  amdgpu_kfd_free_wait_ms       max ms to bounded-wait on pin_count==0
                                in amdgpu_amdkfd_gpuvm_free_memory_of_gpu()
                                when hipFree() hits an RDMA-pinned BO

  amdgpu_kfd_unpin_drain_ms     strict dma_resv_wait_timeout deadline
                                in the unpin path -- prevents an
                                in-flight peer-RDMA WR from racing the
                                pin_count drop and faulting the peer

  amdgpu_kfd_free_on_pinned     policy switch (0 = legacy orphan,
                                1 = bounded wait + queue for reaper)

  amdgpu_pin_orphan_timeout_ms  age (ms) at which the reaper force-
                                unpins a BO parked on the orphan list

  amdgpu_pin_reaper_interval_ms tick interval (ms) of the reaper
                                background delayed_work

## Motivation

In multi-tenant HIP serving workloads, RDMA peer drivers (e.g. the
NIC-side rdma_pin or peer-mem shim) hold pin_count > 0 on KFD BOs
across the lifetime of in-flight RDMA WRs.  When userspace calls
hipFree() on such a BO upstream amdgpu either:

  1) silently keeps the BO alive until process exit (memory leak
     that accumulates over hours of serving), or
  2) blocks the unpin path indefinitely if the peer driver is
     wedged (one stuck NIC turns into a process-wide free-path stall).

The five knobs introduced here let operators opt the KFD layer into a
controlled non-leak / non-deadlock policy:

  - hipFree() bounded-waits up to amdgpu_kfd_free_wait_ms for the peer
    to drop the pin (typical: 2-4 seconds);
  - if the peer is still holding, the BO is queued for the orphan
    reaper, which periodically (amdgpu_pin_reaper_interval_ms) walks
    the list and force-unpins entries older than
    amdgpu_pin_orphan_timeout_ms;
  - the unpin path itself uses amdgpu_kfd_unpin_drain_ms to bound the
    dma_resv_wait_timeout() that drains in-flight fences before
    pin_count is decremented, so a wedged peer cannot park the unpin
    caller indefinitely.

## Technical Details

NEW FILE
- drivers/gpu/drm/amd/amdgpu/amdgpu_kfd_pin_reaper.c
    amdgpu_kfd_unpin_drain()    bounded dma_resv_wait_timeout()
    amdgpu_kfd_wait_pin_drop()  exp-backoff poll on pin_count==0
    amdgpu_kfd_orphan_queue()   queue BO onto adev->kfd.orphan_list
    amdgpu_kfd_reaper_fn()      delayed_work callback that walks the
                                orphan list and force-unpins aged
                                entries
    amdgpu_kfd_reaper_start()   one-shot init from device_init
    amdgpu_kfd_reaper_stop()    one-shot teardown from device_fini

MODIFIED
- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
    Add `struct kfd_orphan_pin` (queue node).
    Add 9 new fields to `struct amdgpu_kfd_dev`: orphan list spinlock,
    list head, reaper delayed_work, atomic64 stat counters
    (rdma_pin_orphans_queued/reaped, free_wait_pinned_count/timeout,
    unpin_drain_timeouts), `reaper_started` bool.
    Add function declarations for the helpers + reaper lifecycle.

- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
    `amdgpu_amdkfd_device_init()` -> `amdgpu_kfd_reaper_start(adev)`
    `amdgpu_amdkfd_device_fini_sw()` -> `amdgpu_kfd_reaper_stop(adev)`
    (reaper_stop is called first so the worker exits before
    adev->kfd.dev is torn down).

- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
    `amdgpu_amdkfd_gpuvm_free_memory_of_gpu()` gains a small policy
    block that runs only when `mem->bo->tbo.pin_count > 0` AND
    `amdgpu_kfd_free_on_pinned >= 1`.  When the bounded wait times
    out the BO is queued via `amdgpu_kfd_orphan_queue()` and
    hipFree() returns success to userspace; the BO is reclaimed
    either when the peer releases the pin or forcibly by the reaper.

- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
    Five new `module_param_named()` declarations with DOC comments.

- drivers/gpu/drm/amd/amdgpu/amdgpu.h
    Five new `extern int` declarations.

- drivers/gpu/drm/amd/amdgpu/Makefile
    Add `amdgpu_kfd_pin_reaper.o` to `amdgpu-y`.

## Default behaviour

All five module parameters default to 0.  When none are set:
- `amdgpu_kfd_reaper_start()` initialises the orphan list and atomic
  counters but does NOT schedule the reaper delayed_work (because
  `amdgpu_pin_reaper_interval_ms == 0`); the worker never runs.
- The free-on-pinned policy block in `free_memory_of_gpu()` is gated
  by `amdgpu_kfd_free_on_pinned >= 1`, so it is a no-op.
- `amdgpu_kfd_unpin_drain()` returns 0 immediately when its timeout
  argument is 0.

Net behavioural diff on stock callers: zero.

## JIRA ID

N/A

## Test Plan

Reproducer: multi-tenant HIP serving with RDMA peer driver holding
pin_count across hipFree().  Open-source reproducer to be added in a
follow-up test patch.

Expected behaviour:
- All five envs unset (default): unchanged.  hipFree() on a pinned
  BO leaks (legacy) as before.
- amdgpu_kfd_free_on_pinned=1, kfd_free_wait_ms=4000,
  pin_orphan_timeout_ms=10000, pin_reaper_interval_ms=2000:
  hipFree on a pinned BO either waits up to 4 s for the peer to
  release (and then frees cleanly), or queues the BO for the
  reaper.  The reaper ticks every 2 s and force-unpins anything
  older than 10 s.

## Test Result

11+ hours of multi-tenant HIP serving load on a customer MI300X
stable with the five envs set per the recipe above; orphan reaper
queued / reaped counters match expectations (queued == reaped over
the run), and no memory leak observed across 32-cycle stress
sweep.  Default-off run passes existing KFD self-tests
byte-identically.

## Submission Checklist

- [x] Look over the contributing guidelines at https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.

Signed-off-by: chun-wan <chun-wan@users.noreply.github.com>
@chun-wan chun-wan force-pushed the topic/drm-amdgpu-kfd-pin-reaper branch from 05cd26a to 56f0794 Compare May 20, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.