AMD General

Except for the eeprom table compatibility is pending for validation, the others 
look good to me in general.

The series is

Reviewed-by: Hawking Zhang <[email protected]>

Regards,
Hawking
-----Original Message-----
From: Sun, Ce(Overlord) <[email protected]>
Sent: Thursday, June 25, 2026 16:19
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Chai, Thomas <[email protected]>; 
Zhou1, Tao <[email protected]>; Yang, Stanley <[email protected]>; Sun, 
Ce(Overlord) <[email protected]>
Subject: [PATCH v3 01/44] drm/amdgpu: Retire legacy page retirement RAS code

Remove the deprecated legacy RAS code path for page retirement

Signed-off-by: Ce Sun <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 304 +-----------------------  
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h |  23 --  
drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c |  13 +-  
drivers/gpu/drm/amd/amdgpu/umc_v12_0.c  |  17 --
 4 files changed, 2 insertions(+), 355 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 8a49ae4c0132..8095f284d531 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -128,12 +128,6 @@ const char *get_ras_block_str(struct ras_common_if 
*ras_block)
 /* typical ECC bad page rate is 1 bad page per 100MB VRAM */
 #define RAS_BAD_PAGE_COVER              (100 * 1024 * 1024ULL)

-#define MAX_UMC_POISON_POLLING_TIME_ASYNC  10
-
-#define AMDGPU_RAS_RETIRE_PAGE_INTERVAL 100  //ms
-
-#define MAX_FLUSH_RETIRE_DWORK_TIMES  100
-
 #define BYPASS_ALLOCATED_ADDRESS        0x0
 #define BYPASS_INITIALIZATION_ADDRESS   0x1

@@ -2489,14 +2483,6 @@ static void 
amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj
        event_id = amdgpu_ras_acquire_event_id(adev, type);
        RAS_EVENT_LOG(adev, event_id, "Poison is created\n");

-       if (amdgpu_ip_version(obj->adev, UMC_HWIP, 0) >= IP_VERSION(12, 0, 0)) {
-               struct amdgpu_ras *con = amdgpu_ras_get_context(obj->adev);
-
-               atomic_inc(&con->page_retirement_req_cnt);
-               atomic_inc(&con->poison_creation_count);
-
-               wake_up(&con->page_retirement_wq);
-       }
 }

 static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj, @@ 
-3550,38 +3536,6 @@ static void amdgpu_ras_validate_threshold(struct 
amdgpu_device *adev,
        }
 }

-int amdgpu_ras_put_poison_req(struct amdgpu_device *adev,
-               enum amdgpu_ras_block block, uint16_t pasid,
-               pasid_notify pasid_fn, void *data, uint32_t reset)
-{
-       int ret = 0;
-       struct ras_poison_msg poison_msg;
-       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-
-       memset(&poison_msg, 0, sizeof(poison_msg));
-       poison_msg.block = block;
-       poison_msg.pasid = pasid;
-       poison_msg.reset = reset;
-       poison_msg.pasid_fn = pasid_fn;
-       poison_msg.data = data;
-
-       ret = kfifo_put(&con->poison_fifo, poison_msg);
-       if (!ret) {
-               dev_err(adev->dev, "Poison message fifo is full!\n");
-               return -ENOSPC;
-       }
-
-       return 0;
-}
-
-static int amdgpu_ras_get_poison_req(struct amdgpu_device *adev,
-               struct ras_poison_msg *poison_msg)
-{
-       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-
-       return kfifo_get(&con->poison_fifo, poison_msg);
-}
-
 static void amdgpu_ras_ecc_log_init(struct ras_ecc_log_info *ecc_log)  {
        mutex_init(&ecc_log->lock);
@@ -3611,232 +3565,6 @@ static void amdgpu_ras_ecc_log_fini(struct 
ras_ecc_log_info *ecc_log)
        ecc_log->consumption_q_count = 0;
 }

-static bool amdgpu_ras_schedule_retirement_dwork(struct amdgpu_ras *con,
-                               uint32_t delayed_ms)
-{
-       int ret;
-
-       mutex_lock(&con->umc_ecc_log.lock);
-       ret = radix_tree_tagged(&con->umc_ecc_log.de_page_tree,
-                       UMC_ECC_NEW_DETECTED_TAG);
-       mutex_unlock(&con->umc_ecc_log.lock);
-
-       if (ret)
-               schedule_delayed_work(&con->page_retirement_dwork,
-                       msecs_to_jiffies(delayed_ms));
-
-       return ret ? true : false;
-}
-
-static void amdgpu_ras_do_page_retirement(struct work_struct *work) -{
-       struct amdgpu_ras *con = container_of(work, struct amdgpu_ras,
-                                             page_retirement_dwork.work);
-       struct amdgpu_device *adev = con->adev;
-       struct ras_err_data err_data;
-
-       /* If gpu reset is ongoing, delay retiring the bad pages */
-       if (amdgpu_in_reset(adev) || amdgpu_ras_in_recovery(adev)) {
-               amdgpu_ras_schedule_retirement_dwork(con,
-                               AMDGPU_RAS_RETIRE_PAGE_INTERVAL * 3);
-               return;
-       }
-
-       amdgpu_ras_error_data_init(&err_data);
-
-       amdgpu_umc_handle_bad_pages(adev, &err_data);
-
-       amdgpu_ras_error_data_fini(&err_data);
-
-       amdgpu_ras_schedule_retirement_dwork(con,
-                       AMDGPU_RAS_RETIRE_PAGE_INTERVAL);
-}
-
-static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev,
-                               uint32_t poison_creation_count)
-{
-       int ret = 0;
-       struct ras_ecc_log_info *ecc_log;
-       struct ras_query_if info;
-       u32 timeout = MAX_UMC_POISON_POLLING_TIME_ASYNC;
-       struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
-       u64 de_queried_count;
-       u64 consumption_q_count;
-       enum ras_event_type type = RAS_EVENT_TYPE_POISON_CREATION;
-
-       memset(&info, 0, sizeof(info));
-       info.head.block = AMDGPU_RAS_BLOCK__UMC;
-
-       ecc_log = &ras->umc_ecc_log;
-       ecc_log->de_queried_count = 0;
-       ecc_log->consumption_q_count = 0;
-
-       do {
-               ret = amdgpu_ras_query_error_status_with_event(adev, &info, 
type);
-               if (ret)
-                       return ret;
-
-               de_queried_count = ecc_log->de_queried_count;
-               consumption_q_count = ecc_log->consumption_q_count;
-
-               if (de_queried_count && consumption_q_count)
-                       break;
-
-               msleep(100);
-       } while (--timeout);
-
-       if (de_queried_count)
-               schedule_delayed_work(&ras->page_retirement_dwork, 0);
-
-       if (amdgpu_ras_is_rma(adev) && atomic_cmpxchg(&ras->rma_in_recovery, 0, 
1) == 0)
-               amdgpu_ras_reset_gpu(adev);
-
-       return 0;
-}
-
-static void amdgpu_ras_clear_poison_fifo(struct amdgpu_device *adev) -{
-       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-       struct ras_poison_msg msg;
-       int ret;
-
-       do {
-               ret = kfifo_get(&con->poison_fifo, &msg);
-       } while (ret);
-}
-
-static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev,
-                       uint32_t msg_count, uint32_t *gpu_reset)
-{
-       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-       uint32_t reset_flags = 0, reset = 0;
-       struct ras_poison_msg msg;
-       int ret, i;
-
-       kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
-
-       for (i = 0; i < msg_count; i++) {
-               ret = amdgpu_ras_get_poison_req(adev, &msg);
-               if (!ret)
-                       continue;
-
-               if (msg.pasid_fn)
-                       msg.pasid_fn(adev, msg.pasid, msg.data);
-
-               reset_flags |= msg.reset;
-       }
-
-       /*
-        * Try to ensure poison creation handler is completed first
-        * to set rma if bad page exceed threshold.
-        */
-       flush_delayed_work(&con->page_retirement_dwork);
-
-       /* for RMA, amdgpu_ras_poison_creation_handler will trigger gpu reset */
-       if (reset_flags && !amdgpu_ras_is_rma(adev)) {
-               if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET)
-                       reset = AMDGPU_RAS_GPU_RESET_MODE1_RESET;
-               else if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE2_RESET)
-                       reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET;
-               else
-                       reset = reset_flags;
-
-               con->gpu_reset_flags |= reset;
-               amdgpu_ras_reset_gpu(adev);
-
-               *gpu_reset = reset;
-
-               /* Wait for gpu recovery to complete */
-               flush_work(&con->recovery_work);
-       }
-
-       return 0;
-}
-
-static int amdgpu_ras_page_retirement_thread(void *param) -{
-       struct amdgpu_device *adev = (struct amdgpu_device *)param;
-       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-       uint32_t poison_creation_count, msg_count;
-       uint32_t gpu_reset;
-       int ret;
-
-       while (!kthread_should_stop()) {
-
-               wait_event_interruptible(con->page_retirement_wq,
-                               kthread_should_stop() ||
-                               atomic_read(&con->page_retirement_req_cnt));
-
-               if (kthread_should_stop())
-                       break;
-
-               mutex_lock(&con->poison_lock);
-               gpu_reset = 0;
-
-               do {
-                       poison_creation_count = 
atomic_read(&con->poison_creation_count);
-                       ret = amdgpu_ras_poison_creation_handler(adev, 
poison_creation_count);
-                       if (ret == -EIO)
-                               break;
-
-                       if (poison_creation_count) {
-                               atomic_sub(poison_creation_count, 
&con->poison_creation_count);
-                               atomic_sub(poison_creation_count, 
&con->page_retirement_req_cnt);
-                       }
-               } while (atomic_read(&con->poison_creation_count) &&
-                       !atomic_read(&con->poison_consumption_count));
-
-               if (ret != -EIO) {
-                       msg_count = kfifo_len(&con->poison_fifo);
-                       if (msg_count) {
-                               ret = 
amdgpu_ras_poison_consumption_handler(adev,
-                                               msg_count, &gpu_reset);
-                               if ((ret != -EIO) &&
-                                   (gpu_reset != 
AMDGPU_RAS_GPU_RESET_MODE1_RESET))
-                                       atomic_sub(msg_count, 
&con->page_retirement_req_cnt);
-                       }
-               }
-
-               if ((ret == -EIO) || (gpu_reset == 
AMDGPU_RAS_GPU_RESET_MODE1_RESET)) {
-                       /* gpu mode-1 reset is ongoing or just completed ras 
mode-1 reset */
-                       /* Clear poison creation request */
-                       atomic_set(&con->poison_creation_count, 0);
-                       atomic_set(&con->poison_consumption_count, 0);
-
-                       /* Clear poison fifo */
-                       amdgpu_ras_clear_poison_fifo(adev);
-
-                       /* Clear all poison requests */
-                       atomic_set(&con->page_retirement_req_cnt, 0);
-
-                       if (ret == -EIO) {
-                               /* Wait for mode-1 reset to complete */
-                               down_read(&adev->reset_domain->sem);
-                               up_read(&adev->reset_domain->sem);
-                       }
-
-                       /* Wake up work to save bad pages to eeprom */
-                       schedule_delayed_work(&con->page_retirement_dwork, 0);
-               } else if (gpu_reset) {
-                       /* gpu just completed mode-2 reset or other reset */
-                       /* Clear poison consumption messages cached in fifo */
-                       msg_count = kfifo_len(&con->poison_fifo);
-                       if (msg_count) {
-                               amdgpu_ras_clear_poison_fifo(adev);
-                               atomic_sub(msg_count, 
&con->page_retirement_req_cnt);
-                       }
-
-                       atomic_set(&con->poison_consumption_count, 0);
-
-                       /* Wake up work to save bad pages to eeprom */
-                       schedule_delayed_work(&con->page_retirement_dwork, 0);
-               }
-               mutex_unlock(&con->poison_lock);
-       }
-
-       return 0;
-}
-
 int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev)  {
        struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -3917,10 
+3645,8 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool 
init_bp_info)
        }

        mutex_init(&con->recovery_lock);
-       mutex_init(&con->poison_lock);
        INIT_WORK(&con->recovery_work, amdgpu_ras_do_recovery);
        atomic_set(&con->in_recovery, 0);
-       atomic_set(&con->rma_in_recovery, 0);
        con->eeprom_control.bad_channel_bitmap = 0;

        max_eeprom_records_count = 
amdgpu_ras_eeprom_max_record_count(&con->eeprom_control);
@@ -3933,20 +3659,8 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev, 
bool init_bp_info)
        }

        mutex_init(&con->page_rsv_lock);
-       INIT_KFIFO(con->poison_fifo);
        mutex_init(&con->page_retirement_lock);
-       init_waitqueue_head(&con->page_retirement_wq);
-       atomic_set(&con->page_retirement_req_cnt, 0);
-       atomic_set(&con->poison_creation_count, 0);
-       atomic_set(&con->poison_consumption_count, 0);
-       con->page_retirement_thread =
-               kthread_run(amdgpu_ras_page_retirement_thread, adev, 
"umc_page_retirement");
-       if (IS_ERR(con->page_retirement_thread)) {
-               con->page_retirement_thread = NULL;
-               dev_warn(adev->dev, "Failed to create umc_page_retirement 
thread!!!\n");
-       }
-
-       INIT_DELAYED_WORK(&con->page_retirement_dwork, 
amdgpu_ras_do_page_retirement);
+
        amdgpu_ras_ecc_log_init(&con->umc_ecc_log);
 #ifdef CONFIG_X86_MCE_AMD
        if ((adev->asic_type == CHIP_ALDEBARAN) && @@ -3978,31 +3692,15 @@ 
static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev)  {
        struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
        struct ras_err_handler_data *data = con->eh_data;
-       int max_flush_timeout = MAX_FLUSH_RETIRE_DWORK_TIMES;
-       bool ret;

        /* recovery_init failed to init it, fini is useless */
        if (!data)
                return 0;

-       /* Save all cached bad pages to eeprom */
-       do {
-               flush_delayed_work(&con->page_retirement_dwork);
-               ret = amdgpu_ras_schedule_retirement_dwork(con, 0);
-       } while (ret && max_flush_timeout--);
-
-       if (con->page_retirement_thread)
-               kthread_stop(con->page_retirement_thread);
-
-       atomic_set(&con->page_retirement_req_cnt, 0);
-       atomic_set(&con->poison_creation_count, 0);
-
        mutex_destroy(&con->page_rsv_lock);

        cancel_work_sync(&con->recovery_work);

-       cancel_delayed_work_sync(&con->page_retirement_dwork);
-
        amdgpu_ras_ecc_log_fini(&con->umc_ecc_log);

        mutex_lock(&con->recovery_lock);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index a86ab65aa2f0..1629a242d58e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -466,14 +466,6 @@ struct ras_query_context {  typedef int 
(*pasid_notify)(struct amdgpu_device *adev,
                uint16_t pasid, void *data);

-struct ras_poison_msg {
-       enum amdgpu_ras_block block;
-       uint16_t pasid;
-       uint32_t reset;
-       pasid_notify pasid_fn;
-       void *data;
-};
-
 struct ras_err_pages {
        uint32_t count;
        uint64_t *pfn;
@@ -549,7 +541,6 @@ struct amdgpu_ras {
        /* gpu recovery */
        struct work_struct recovery_work;
        atomic_t in_recovery;
-       atomic_t rma_in_recovery;
        struct amdgpu_device *adev;
        /* error handler data */
        struct ras_err_handler_data *eh_data;
@@ -587,16 +578,9 @@ struct amdgpu_ras {
        /* Record special requirements of gpu reset caller */
        uint32_t  gpu_reset_flags;

-       struct task_struct *page_retirement_thread;
-       wait_queue_head_t page_retirement_wq;
        struct mutex page_retirement_lock;
-       atomic_t page_retirement_req_cnt;
-       atomic_t poison_creation_count;
-       atomic_t poison_consumption_count;
        struct mutex page_rsv_lock;
-       DECLARE_KFIFO(poison_fifo, struct ras_poison_msg, 128);
        struct ras_ecc_log_info  umc_ecc_log;
-       struct delayed_work page_retirement_dwork;

        /* ras errors detected */
        unsigned long ras_err_state;
@@ -615,9 +599,6 @@ struct amdgpu_ras {
        struct list_head critical_region_head;
        struct mutex critical_region_lock;

-       /* Protect poison injection */
-       struct mutex poison_lock;
-
        /* Disable/Enable uniras switch */
        bool uniras_enabled;
        const struct ras_smu_drv *ras_smu_drv; @@ -1029,10 +1010,6 @@ int 
amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn);  int 
amdgpu_ras_add_critical_region(struct amdgpu_device *adev, struct amdgpu_bo 
*bo);  bool amdgpu_ras_check_critical_address(struct amdgpu_device *adev, 
uint64_t addr);

-int amdgpu_ras_put_poison_req(struct amdgpu_device *adev,
-               enum amdgpu_ras_block block, uint16_t pasid,
-               pasid_notify pasid_fn, void *data, uint32_t reset);
-
 bool amdgpu_ras_in_recovery(struct amdgpu_device *adev);

 __printf(3, 4)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index a250109edb63..f22d07e9c29c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -276,7 +276,7 @@ int amdgpu_umc_pasid_poison_handler(struct amdgpu_device 
*adev,
                        }

                        amdgpu_ras_error_data_fini(&err_data);
-               } else if (amdgpu_uniras_enabled(adev)) {
+               } else {
                        struct ras_ih_info ih_info = {0};

                        ih_info.block = block;
@@ -285,17 +285,6 @@ int amdgpu_umc_pasid_poison_handler(struct amdgpu_device 
*adev,
                        ih_info.pasid_fn = pasid_fn;
                        ih_info.data = data;
                        amdgpu_ras_mgr_handle_consumer_interrupt(adev, 
&ih_info);
-               } else {
-                       struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-                       int ret;
-
-                       ret = amdgpu_ras_put_poison_req(adev,
-                               block, pasid, pasid_fn, data, reset);
-                       if (!ret) {
-                               atomic_inc(&con->page_retirement_req_cnt);
-                               atomic_inc(&con->poison_consumption_count);
-                               wake_up(&con->page_retirement_wq);
-                       }
                }
        } else {
                if (adev->virt.ops && adev->virt.ops->ras_poison_handler)
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
index a6df6a778f50..749c1f845ac6 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
@@ -656,23 +656,6 @@ static int umc_v12_0_update_ecc_status(struct 
amdgpu_device *adev,
        for (i = 0; i < count; i++)
                amdgpu_ras_reserve_page(adev, page_pfn[i]);

-       /* The problem case is as follows:
-        * 1. GPU A triggers a gpu ras reset, and GPU A drives
-        *    GPU B to also perform a gpu ras reset.
-        * 2. After gpu B ras reset started, gpu B queried a DE
-        *    data. Since the DE data was queried in the ras reset
-        *    thread instead of the page retirement thread, bad
-        *    page retirement work would not be triggered. Then
-        *    even if all gpu resets are completed, the bad pages
-        *    will be cached in RAM until GPU B's bad page retirement
-        *    work is triggered again and then saved to eeprom.
-        * Trigger delayed work to save the bad pages to eeprom in time
-        * after gpu ras reset is completed.
-        */
-       if (amdgpu_ras_in_recovery(adev))
-               schedule_delayed_work(&con->page_retirement_dwork,
-                       msecs_to_jiffies(DELAYED_TIME_FOR_GPU_RESET));
-
        return 0;
 }

--
2.34.1

Reply via email to