From: David Yat Sin <david.yat...@amd.com>

When re-creating queues during CRIU restore, restore the queue with the
same sdma id value used during CRIU dump.

Signed-off-by: David Yat Sin <david.yat...@amd.com>

---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 48 ++++++++++++++-----
 .../drm/amd/amdkfd/kfd_device_queue_manager.h |  3 +-
 .../amd/amdkfd/kfd_process_queue_manager.c    |  4 +-
 3 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 62fe28244a80..7e49f70b81b9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -58,7 +58,7 @@ static inline void deallocate_hqd(struct device_queue_manager 
*dqm,
                                struct queue *q);
 static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q);
 static int allocate_sdma_queue(struct device_queue_manager *dqm,
-                               struct queue *q);
+                               struct queue *q, const uint32_t 
*restore_sdma_id);
 static void kfd_process_hw_exception(struct work_struct *work);
 
 static inline
@@ -308,7 +308,8 @@ static void deallocate_vmid(struct device_queue_manager 
*dqm,
 
 static int create_queue_nocpsch(struct device_queue_manager *dqm,
                                struct queue *q,
-                               struct qcm_process_device *qpd)
+                               struct qcm_process_device *qpd,
+                               const struct kfd_criu_queue_priv_data *qd)
 {
        struct mqd_manager *mqd_mgr;
        int retval;
@@ -348,7 +349,7 @@ static int create_queue_nocpsch(struct device_queue_manager 
*dqm,
                        q->pipe, q->queue);
        } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
                q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
-               retval = allocate_sdma_queue(dqm, q);
+               retval = allocate_sdma_queue(dqm, q, qd ? &qd->sdma_id : NULL);
                if (retval)
                        goto deallocate_vmid;
                dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
@@ -1040,7 +1041,7 @@ static void pre_reset(struct device_queue_manager *dqm)
 }
 
 static int allocate_sdma_queue(struct device_queue_manager *dqm,
-                               struct queue *q)
+                               struct queue *q, const uint32_t 
*restore_sdma_id)
 {
        int bit;
 
@@ -1050,9 +1051,21 @@ static int allocate_sdma_queue(struct 
device_queue_manager *dqm,
                        return -ENOMEM;
                }
 
-               bit = __ffs64(dqm->sdma_bitmap);
-               dqm->sdma_bitmap &= ~(1ULL << bit);
-               q->sdma_id = bit;
+               if (restore_sdma_id) {
+                       /* Re-use existing sdma_id */
+                       if (!(dqm->sdma_bitmap & (1ULL << *restore_sdma_id))) {
+                               pr_err("SDMA queue already in use\n");
+                               return -EBUSY;
+                       }
+                       dqm->sdma_bitmap &= ~(1ULL << *restore_sdma_id);
+                       q->sdma_id = *restore_sdma_id;
+               } else {
+                       /* Find first available sdma_id */
+                       bit = __ffs64(dqm->sdma_bitmap);
+                       dqm->sdma_bitmap &= ~(1ULL << bit);
+                       q->sdma_id = bit;
+               }
+
                q->properties.sdma_engine_id = q->sdma_id %
                                get_num_sdma_engines(dqm);
                q->properties.sdma_queue_id = q->sdma_id /
@@ -1062,9 +1075,19 @@ static int allocate_sdma_queue(struct 
device_queue_manager *dqm,
                        pr_err("No more XGMI SDMA queue to allocate\n");
                        return -ENOMEM;
                }
-               bit = __ffs64(dqm->xgmi_sdma_bitmap);
-               dqm->xgmi_sdma_bitmap &= ~(1ULL << bit);
-               q->sdma_id = bit;
+               if (restore_sdma_id) {
+                       /* Re-use existing sdma_id */
+                       if (!(dqm->xgmi_sdma_bitmap & (1ULL << 
*restore_sdma_id))) {
+                               pr_err("SDMA queue already in use\n");
+                               return -EBUSY;
+                       }
+                       dqm->xgmi_sdma_bitmap &= ~(1ULL << *restore_sdma_id);
+                       q->sdma_id = *restore_sdma_id;
+               } else {
+                       bit = __ffs64(dqm->xgmi_sdma_bitmap);
+                       dqm->xgmi_sdma_bitmap &= ~(1ULL << bit);
+                       q->sdma_id = bit;
+               }
                /* sdma_engine_id is sdma id including
                 * both PCIe-optimized SDMAs and XGMI-
                 * optimized SDMAs. The calculation below
@@ -1293,7 +1316,8 @@ static void destroy_kernel_queue_cpsch(struct 
device_queue_manager *dqm,
 }
 
 static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue 
*q,
-                       struct qcm_process_device *qpd)
+                       struct qcm_process_device *qpd,
+                       const struct kfd_criu_queue_priv_data *qd)
 {
        int retval;
        struct mqd_manager *mqd_mgr;
@@ -1308,7 +1332,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
        if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
                q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
                dqm_lock(dqm);
-               retval = allocate_sdma_queue(dqm, q);
+               retval = allocate_sdma_queue(dqm, q, qd ? &qd->sdma_id : NULL);
                dqm_unlock(dqm);
                if (retval)
                        goto out;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index 499fc0ea387f..6fa43215e3e2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -86,7 +86,8 @@ struct device_process_node {
 struct device_queue_manager_ops {
        int     (*create_queue)(struct device_queue_manager *dqm,
                                struct queue *q,
-                               struct qcm_process_device *qpd);
+                               struct qcm_process_device *qpd,
+                               const struct kfd_criu_queue_priv_data *qd);
 
        int     (*destroy_queue)(struct device_queue_manager *dqm,
                                struct qcm_process_device *qpd,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 275aeebc58fa..25cf97d97d87 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -273,7 +273,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
                        goto err_create_queue;
                pqn->q = q;
                pqn->kq = NULL;
-               retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
+               retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd, 
q_data);
                print_queue(q);
                break;
 
@@ -293,7 +293,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
                        goto err_create_queue;
                pqn->q = q;
                pqn->kq = NULL;
-               retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
+               retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd, 
q_data);
                print_queue(q);
                break;
        case KFD_QUEUE_TYPE_DIQ:
-- 
2.17.1

Reply via email to