[PATCH 2/2] drm/amdkfd: implement restore_mqd callbacks for GFX12/12.1

"Marioukhine, Vladimir" <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <SA1PR12MB860060695EBBCE15BD0FCBBA9FDB2@SA1PR12MB8600.namprd12.prod.outlook.com>
AMD General

kfd_mqd_manager_v12.c (GFX 12.0) and kfd_mqd_manager_v12_1.c (GFX 12.1)
do not implement restore_mqd or checkpoint_mqd callbacks, leaving the
function pointers NULL and making CRIU restore non-functional on GFX12.

Implement restore_mqd and checkpoint_mqd for both compute and SDMA
queues in kfd_mqd_manager_v12.c and kfd_mqd_manager_v12_1.c, modeled
after the GFX 11 implementation. Only restore_mqd is registered for
now; checkpoint_mqd registration is deferred until get_checkpoint_info
is implemented to avoid silently dropping the CWSR control stack.

Fixes: 48f0bdf4e38e ("drm/amdkfd: Added MQD manager files for GFX12.")
Fixes: 01bbc4a4b947 ("drm/amdkfd: Add MQD manager for GFX 12.1.0")
Signed-off-by: Vladimir Marioukhine <[email protected]>
---
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c   | 87 +++++++++++++++++++++
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c | 87 +++++++++++++++++++++
2 files changed, 174 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
index 7c387fa90076..a9a2dc4a0a75 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
@@ -380,6 +380,87 @@ static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
 #endif
+static void checkpoint_mqd(struct mqd_manager *mm, void *mqd,
+                                              void *mqd_dst, void *ctl_stack_dst)
+{
+            /*
+            * GFXv12 control stack checkpoint is not yet implemented;
+            * get_checkpoint_info is unset, so ctl_stack_dst is always unused.
+            */
+            struct v12_compute_mqd *m;
+
+            m = get_mqd(mqd);
+
+            memcpy(mqd_dst, m, sizeof(struct v12_compute_mqd));
+}
+
+static void restore_mqd(struct mqd_manager *mm, void **mqd,
+                                          struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+                                          struct queue_properties *qp, const void *mqd_src,
+                                          const void *ctl_stack_src, const u32 ctl_stack_size)
+{
+            u64 addr;
+            struct v12_compute_mqd *m;
+
+            if (ctl_stack_size)
+                           pr_debug("GFX12 ctl stack restore not supported\n");
+
+            m = (struct v12_compute_mqd *)mqd_mem_obj->cpu_ptr;
+            addr = mqd_mem_obj->gpu_addr;
+
+            memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
+            memcpy(m, mqd_src, sizeof(*m));
+
+            *mqd = m;
+            if (gart_addr)
+                           *gart_addr = addr;
+
+            m->cp_hqd_pq_doorbell_control =
+                           qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+            pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
+
+            qp->is_active = 0;
+}
+
+static void checkpoint_mqd_sdma(struct mqd_manager *mm, void *mqd,
+                                                         void *mqd_dst, void *ctl_stack_dst)
+{
+            struct v12_sdma_mqd *m;
+
+            m = get_sdma_mqd(mqd);
+
+            memcpy(mqd_dst, m, sizeof(struct v12_sdma_mqd));
+}
+
+static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
+                                               struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+                                               struct queue_properties *qp,
+                                               const void *mqd_src,
+                                               const void *ctl_stack_src,
+                                               const u32 ctl_stack_size)
+{
+            u64 addr;
+            struct v12_sdma_mqd *m;
+
+            if (ctl_stack_size)
+                           pr_debug("GFX12 ctl stack restore not supported\n");
+
+            m = (struct v12_sdma_mqd *)mqd_mem_obj->cpu_ptr;
+            addr = mqd_mem_obj->gpu_addr;
+
+            memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
+            memcpy(m, mqd_src, sizeof(*m));
+
+            m->sdmax_rlcx_doorbell_offset =
+                           qp->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
+
+            *mqd = m;
+            if (gart_addr)
+                           *gart_addr = addr;
+
+            qp->is_active = 0;
+}
+
struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
                             struct kfd_node *dev)
{
@@ -407,6 +488,7 @@ struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
                             mqd->mqd_size = sizeof(struct v12_compute_mqd);
                             mqd->get_wave_state = get_wave_state;
                             mqd->mqd_stride = kfd_mqd_stride;
+                           mqd->restore_mqd = restore_mqd;
#if defined(CONFIG_DEBUG_FS)
                             mqd->debugfs_show_mqd = debugfs_show_mqd;
#endif
@@ -453,6 +535,7 @@ struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type,
                             mqd->is_occupied = kfd_is_occupied_sdma;
                             mqd->mqd_size = sizeof(struct v12_sdma_mqd);
                             mqd->mqd_stride = kfd_mqd_stride;
+                           mqd->restore_mqd = restore_mqd_sdma;
#if defined(CONFIG_DEBUG_FS)
                             mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
index 431a940f91f3..daca9e39468e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
@@ -641,6 +641,87 @@ static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
 #endif
+static void checkpoint_mqd_v12_1(struct mqd_manager *mm, void *mqd,
+                                                         void *mqd_dst, void *ctl_stack_dst)
+{
+            /*
+            * GFXv12 control stack checkpoint is not yet implemented;
+            * get_checkpoint_info is unset, so ctl_stack_dst is always unused.
+            */
+            struct v12_1_compute_mqd *m;
+
+            m = get_mqd(mqd);
+
+            memcpy(mqd_dst, m, sizeof(struct v12_1_compute_mqd));
+}
+
+static void restore_mqd_v12_1(struct mqd_manager *mm, void **mqd,
+                                                struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+                                                struct queue_properties *qp, const void *mqd_src,
+                                                const void *ctl_stack_src, const u32 ctl_stack_size)
+{
+            u64 addr;
+            struct v12_1_compute_mqd *m;
+
+            if (ctl_stack_size)
+                           pr_debug("GFX12 ctl stack restore not supported\n");
+
+            m = (struct v12_1_compute_mqd *)mqd_mem_obj->cpu_ptr;
+            addr = mqd_mem_obj->gpu_addr;
+
+            memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
+            memcpy(m, mqd_src, sizeof(*m));
+
+            *mqd = m;
+            if (gart_addr)
+                           *gart_addr = addr;
+
+            m->cp_hqd_pq_doorbell_control =
+                           qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+            pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
+
+            qp->is_active = 0;
+}
+
+static void checkpoint_mqd_sdma_v12_1(struct mqd_manager *mm, void *mqd,
+                                                               void *mqd_dst, void *ctl_stack_dst)
+{
+            struct v12_sdma_mqd *m;
+
+            m = get_sdma_mqd(mqd);
+
+            memcpy(mqd_dst, m, sizeof(struct v12_sdma_mqd));
+}
+
+static void restore_mqd_sdma_v12_1(struct mqd_manager *mm, void **mqd,
+                                                            struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+                                                            struct queue_properties *qp,
+                                                            const void *mqd_src,
+                                                            const void *ctl_stack_src,
+                                                            const u32 ctl_stack_size)
+{
+            u64 addr;
+            struct v12_sdma_mqd *m;
+
+            if (ctl_stack_size)
+                           pr_debug("GFX12 ctl stack restore not supported\n");
+
+            m = (struct v12_sdma_mqd *)mqd_mem_obj->cpu_ptr;
+            addr = mqd_mem_obj->gpu_addr;
+
+            memset(m, 0, AMDGPU_MQD_SIZE_ALIGN(mm->mqd_size));
+            memcpy(m, mqd_src, sizeof(*m));
+
+            m->sdmax_rlcx_doorbell_offset =
+                           qp->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
+
+            *mqd = m;
+            if (gart_addr)
+                           *gart_addr = addr;
+
+            qp->is_active = 0;
+}
+
struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
                             struct kfd_node *dev)
{
@@ -668,6 +749,7 @@ struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
                             mqd->mqd_size = sizeof(struct v12_1_compute_mqd);
                             mqd->get_wave_state = get_wave_state_v12_1;
                             mqd->mqd_stride = kfd_mqd_stride;
+                           mqd->restore_mqd = restore_mqd_v12_1;
#if defined(CONFIG_DEBUG_FS)
                             mqd->debugfs_show_mqd = debugfs_show_mqd;
#endif
@@ -714,6 +796,7 @@ struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type,
                             mqd->is_occupied = kfd_is_occupied_sdma;
                             mqd->mqd_size = sizeof(struct v12_sdma_mqd);
                             mqd->mqd_stride = kfd_mqd_stride;
+                           mqd->restore_mqd = restore_mqd_sdma_v12_1;
#if defined(CONFIG_DEBUG_FS)
                             mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
#endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.