<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
p.msipheaderdf3d92d6, li.msipheaderdf3d92d6, div.msipheaderdf3d92d6
        {mso-style-name:msipheaderdf3d92d6;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="msipheaderdf3d92d6" style="margin:0in"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:blue">[AMD Official Use Only - General]</span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">>> On 2022-06-22 11:36, Graham Sider wrote:<o:p></o:p></p>
<p class="MsoNormal">>> Starting with GFX11, MES requires wptr BOs to be GTT allocated/mapped to<o:p></o:p></p>
<p class="MsoNormal">>> GART for usermode queues in order to support oversubscription. In the<o:p></o:p></p>
<p class="MsoNormal">>> case that work is submitted to an unmapped queue, MES must have a GART<o:p></o:p></p>
<p class="MsoNormal">>> wptr address to determine whether the queue should be mapped.<o:p></o:p></p>
<p class="MsoNormal">>> <o:p></o:p></p>
<p class="MsoNormal">>> This change is accompanied with changes in MES and is applicable for<o:p></o:p></p>
<p class="MsoNormal">>> MES_API_VERSION >= 2.<o:p></o:p></p>
<p class="MsoNormal">>> <o:p></o:p></p>
<p class="MsoNormal">>> v3:<o:p></o:p></p>
<p class="MsoNormal">>> - Use amdgpu_vm_bo_lookup_mapping for wptr_bo mapping lookup<o:p></o:p></p>
<p class="MsoNormal">>> - Move wptr_bo refcount increment to amdgpu_amdkfd_map_gtt_bo_to_gart<o:p></o:p></p>
<p class="MsoNormal">>> - Remove list_del_init from amdgpu_amdkfd_map_gtt_bo_to_gart<o:p></o:p></p>
<p class="MsoNormal">>> - Cleanup/fix create_queue wptr_bo error handling<o:p></o:p></p>
<p class="MsoNormal">>> v4:<o:p></o:p></p>
<p class="MsoNormal">>> - Add MES version shift/mask defines to amdgpu_mes.h<o:p></o:p></p>
<p class="MsoNormal">>> - Change version check from MES_VERSION to MES_API_VERSION<o:p></o:p></p>
<p class="MsoNormal">>> - Add check in kfd_ioctl_create_queue before wptr bo pin/GART map to<o:p></o:p></p>
<p class="MsoNormal">>> ensure bo is a single page.<o:p></o:p></p>
<p class="MsoNormal">>> <o:p></o:p></p>
<p class="MsoNormal">>> Signed-off-by: Graham Sider <a href="mailto:Graham.Sider@amd.com">
Graham.Sider@amd.com</a><o:p></o:p></p>
<p class="MsoNormal">>> Acked-by: Alex Deucher <a href="mailto:alexander.deucher@amd.com">
alexander.deucher@amd.com</a><o:p></o:p></p>
<p class="MsoNormal">>> Reviewed-by: Philip Yang <a href="mailto:Philip.Yang@amd.com">
Philip.Yang@amd.com</a><o:p></o:p></p>
<p class="MsoNormal">>> ---<o:p></o:p></p>
<p class="MsoNormal">>>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h    |  2 +<o:p></o:p></p>
<p class="MsoNormal">>>  .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 48 +++++++++++++++++++<o:p></o:p></p>
<p class="MsoNormal">>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  7 +++<o:p></o:p></p>
<p class="MsoNormal">>>  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      | 45 ++++++++++++++++-<o:p></o:p></p>
<p class="MsoNormal">>>  .../drm/amd/amdkfd/kfd_device_queue_manager.c |  9 +++-<o:p></o:p></p>
<p class="MsoNormal">>>  .../gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c  |  2 +<o:p></o:p></p>
<p class="MsoNormal">>>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  3 ++<o:p></o:p></p>
<p class="MsoNormal">>>  .../amd/amdkfd/kfd_process_queue_manager.c    | 20 +++++---<o:p></o:p></p>
<p class="MsoNormal">>>  8 files changed, 127 insertions(+), 9 deletions(-)<o:p></o:p></p>
<p class="MsoNormal">>> <o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h<o:p></o:p></p>
<p class="MsoNormal">>> index 648c031942e9..b25b41f50213 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h<o:p></o:p></p>
<p class="MsoNormal">>> @@ -286,6 +286,8 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,<o:p></o:p></p>
<p class="MsoNormal">>>                                                                                void **kptr, uint64_t *size);<o:p></o:p></p>
<p class="MsoNormal">>>  void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> +int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>>  int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,<o:p></o:p></p>
<p class="MsoNormal">>>                                                                               struct dma_fence **ef);<o:p></o:p></p>
<p class="MsoNormal">>>  int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c<o:p></o:p></p>
<p class="MsoNormal">>> index afd6e6923189..615ac2895d62 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c<o:p></o:p></p>
<p class="MsoNormal">>> @@ -2148,6 +2148,54 @@ int amdgpu_amdkfd_gpuvm_sync_memory(<o:p></o:p></p>
<p class="MsoNormal">>>           return ret;<o:p></o:p></p>
<p class="MsoNormal">>>  }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> +/**<o:p></o:p></p>
<p class="MsoNormal">>> + * amdgpu_amdkfd_map_gtt_bo_to_gart - Map BO to GART and increment reference count<o:p></o:p></p>
<p class="MsoNormal">>> + * @adev: Device to which allocated BO belongs<o:p></o:p></p>
<p class="MsoNormal">>> + * @bo: Buffer object to be mapped<o:p></o:p></p>
<p class="MsoNormal">>> + *<o:p></o:p></p>
<p class="MsoNormal">>> + * Before return, bo reference count is incremented. To release the reference and unpin/<o:p></o:p></p>
<p class="MsoNormal">>> + * unmap the BO, call amdgpu_amdkfd_free_gtt_mem.<o:p></o:p></p>
<p class="MsoNormal">>> + */<o:p></o:p></p>
<p class="MsoNormal">>> +int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)<o:p></o:p></p>
<p class="MsoNormal">>> +{<o:p></o:p></p>
<p class="MsoNormal">>> +       int ret;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       ret = amdgpu_bo_reserve(bo, true);<o:p></o:p></p>
<p class="MsoNormal">>> +       if (ret) {<o:p></o:p></p>
<p class="MsoNormal">>> +                       pr_err("Failed to reserve bo. ret %d\n", ret);<o:p></o:p></p>
<p class="MsoNormal">>> +                       goto err_reserve_bo_failed;<o:p></o:p></p>
<p class="MsoNormal">>> +       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);<o:p></o:p></p>
<p class="MsoNormal">>> +       if (ret) {<o:p></o:p></p>
<p class="MsoNormal">>> +                       pr_err("Failed to pin bo. ret %d\n", ret);<o:p></o:p></p>
<p class="MsoNormal">>> +                       goto err_pin_bo_failed;<o:p></o:p></p>
<p class="MsoNormal">>> +       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       ret = amdgpu_ttm_alloc_gart(&bo->tbo);<o:p></o:p></p>
<p class="MsoNormal">>> +       if (ret) {<o:p></o:p></p>
<p class="MsoNormal">>> +                       pr_err("Failed to bind bo to GART. ret %d\n", ret);<o:p></o:p></p>
<p class="MsoNormal">>> +                       goto err_map_bo_gart_failed;<o:p></o:p></p>
<p class="MsoNormal">>> +       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       amdgpu_amdkfd_remove_eviction_fence(<o:p></o:p></p>
<p class="MsoNormal">>> +                       bo, bo->kfd_bo->process_info->eviction_fence);<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       amdgpu_bo_unreserve(bo);<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       bo = amdgpu_bo_ref(bo);<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       return 0;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +err_map_bo_gart_failed:<o:p></o:p></p>
<p class="MsoNormal">>> +       amdgpu_bo_unpin(bo);<o:p></o:p></p>
<p class="MsoNormal">>> +err_pin_bo_failed:<o:p></o:p></p>
<p class="MsoNormal">>> +       amdgpu_bo_unreserve(bo);<o:p></o:p></p>
<p class="MsoNormal">>> +err_reserve_bo_failed:<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       return ret;<o:p></o:p></p>
<p class="MsoNormal">>> +}<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>>  /** amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel() - Map a GTT BO for kernel CPU access<o:p></o:p></p>
<p class="MsoNormal">>>   *<o:p></o:p></p>
<p class="MsoNormal">>>   * @mem: Buffer object to be mapped for CPU access<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h<o:p></o:p></p>
<p class="MsoNormal">>> index be4b51a5b5c7..137a2cc2e807 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h<o:p></o:p></p>
<p class="MsoNormal">>> @@ -32,6 +32,13 @@<o:p></o:p></p>
<p class="MsoNormal">>>  #define AMDGPU_MES_MAX_GFX_PIPES            2<o:p></o:p></p>
<p class="MsoNormal">>>  #define AMDGPU_MES_MAX_SDMA_PIPES           2<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> +#define AMDGPU_MES_API_VERSION_SHIFT              12<o:p></o:p></p>
<p class="MsoNormal">>> +#define AMDGPU_MES_FEAT_VERSION_SHIFT          24<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +#define AMDGPU_MES_VERSION_MASK                      0x00000fff<o:p></o:p></p>
<p class="MsoNormal">>> +#define AMDGPU_MES_API_VERSION_MASK             0x00fff000<o:p></o:p></p>
<p class="MsoNormal">>> +#define AMDGPU_MES_FEAT_VERSION_MASK          0xff000000<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>>  enum amdgpu_mes_priority_level {<o:p></o:p></p>
<p class="MsoNormal">>>           AMDGPU_MES_PRIORITY_LEVEL_LOW       = 0,<o:p></o:p></p>
<p class="MsoNormal">>>           AMDGPU_MES_PRIORITY_LEVEL_NORMAL    = 1,<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c<o:p></o:p></p>
<p class="MsoNormal">>> index 625e837f0119..a0246b4bae6b 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c<o:p></o:p></p>
<p class="MsoNormal">>> @@ -299,6 +299,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,<o:p></o:p></p>
<p class="MsoNormal">>>           struct kfd_process_device *pdd;<o:p></o:p></p>
<p class="MsoNormal">>>           struct queue_properties q_properties;<o:p></o:p></p>
<p class="MsoNormal">>>           uint32_t doorbell_offset_in_process = 0;<o:p></o:p></p>
<p class="MsoNormal">>> +       struct amdgpu_bo *wptr_bo = NULL;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>           memset(&q_properties, 0, sizeof(struct queue_properties));<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> @@ -326,12 +327,49 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,<o:p></o:p></p>
<p class="MsoNormal">>>                           goto err_bind_process;<o:p></o:p></p>
<p class="MsoNormal">>>           }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> +       /* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work<o:p></o:p></p>
<p class="MsoNormal">>> +       * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)<o:p></o:p></p>
<p class="MsoNormal">>> +       */<o:p></o:p></p>
<p class="MsoNormal">>> +       if (dev->shared_resources.enable_mes &&<o:p></o:p></p>
<p class="MsoNormal">>> +                                       ((dev->adev->mes.sched_version & AMDGPU_MES_API_VERSION_MASK)<o:p></o:p></p>
<p class="MsoNormal">>> +                                       >> AMDGPU_MES_API_VERSION_SHIFT) >= 2) {<o:p></o:p></p>
<p class="MsoNormal">>> +                       struct amdgpu_bo_va_mapping *wptr_mapping;<o:p></o:p></p>
<p class="MsoNormal">>> +                       struct amdgpu_vm *wptr_vm;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                       wptr_vm = drm_priv_to_vm(pdd->drm_priv);<o:p></o:p></p>
<p class="MsoNormal">>> +                       err = amdgpu_bo_reserve(wptr_vm->root.bo, false);<o:p></o:p></p>
<p class="MsoNormal">>> +                       if (err)<o:p></o:p></p>
<p class="MsoNormal">>> +                                       goto err_wptr_map_gart;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                       wptr_mapping = amdgpu_vm_bo_lookup_mapping(<o:p></o:p></p>
<p class="MsoNormal">>> +                                                       wptr_vm, args->write_pointer_address >> PAGE_SHIFT);<o:p></o:p></p>
<p class="MsoNormal">>> +                       amdgpu_bo_unreserve(wptr_vm->root.bo);<o:p></o:p></p>
<p class="MsoNormal">>> +                       if (!wptr_mapping) {<o:p></o:p></p>
<p class="MsoNormal">>> +                                       pr_err("Failed to lookup wptr bo\n");<o:p></o:p></p>
<p class="MsoNormal">>> +                                       err = -EINVAL;<o:p></o:p></p>
<p class="MsoNormal">>> +                                       goto err_wptr_map_gart;<o:p></o:p></p>
<p class="MsoNormal">>> +                       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                       wptr_bo = wptr_mapping->bo_va->base.bo;<o:p></o:p></p>
<p class="MsoNormal">>> +                       if (wptr_bo->tbo.base.size > PAGE_SIZE) {<o:p></o:p></p>
<p class="MsoNormal">>> +                                       pr_err("Requested GART mapping for wptr bo larger than one page\n");<o:p></o:p></p>
<p class="MsoNormal">>> +                                       err = -EINVAL;<o:p></o:p></p>
<p class="MsoNormal">>> +                                       goto err_wptr_map_gart;<o:p></o:p></p>
<p class="MsoNormal">>> +                       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                       err = amdgpu_amdkfd_map_gtt_bo_to_gart(dev->adev, wptr_bo);<o:p></o:p></p>
<p class="MsoNormal">>> +                       if (err) {<o:p></o:p></p>
<p class="MsoNormal">>> +                                       pr_err("Failed to map wptr bo to GART\n");<o:p></o:p></p>
<p class="MsoNormal">>> +                                       goto err_wptr_map_gart;<o:p></o:p></p>
<p class="MsoNormal">>> +                       }<o:p></o:p></p>
<p class="MsoNormal">>> +       }<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>>           pr_debug("Creating queue for PASID 0x%x on gpu 0x%x\n",<o:p></o:p></p>
<p class="MsoNormal">>>                                           p->pasid,<o:p></o:p></p>
<p class="MsoNormal">>>                                           dev->id);<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> -        err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, &queue_id, NULL, NULL, NULL,<o:p></o:p></p>
<p class="MsoNormal">>> -                                        &doorbell_offset_in_process);<o:p></o:p></p>
<p class="MsoNormal">>> +       err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, &queue_id, wptr_bo,<o:p></o:p></p>
<p class="MsoNormal">>> +                                       NULL, NULL, NULL, &doorbell_offset_in_process);<o:p></o:p></p>
<p class="MsoNormal">>>           if (err != 0)<o:p></o:p></p>
<p class="MsoNormal">>>                           goto err_create_queue;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> @@ -363,6 +401,9 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,<o:p></o:p></p>
<p class="MsoNormal">>>           return 0;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>  err_create_queue:<o:p></o:p></p>
<p class="MsoNormal">>> +       if (wptr_bo)<o:p></o:p></p>
<p class="MsoNormal">>> +                       amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);<o:p></o:p></p>
<p class="MsoNormal">>> +err_wptr_map_gart:<o:p></o:p></p>
<p class="MsoNormal">>>  err_bind_process:<o:p></o:p></p>
<p class="MsoNormal">>>  err_pdd:<o:p></o:p></p>
<p class="MsoNormal">>>           mutex_unlock(&p->mutex);<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> index 213246a5b4e4..299927a4959b 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> @@ -177,6 +177,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q,<o:p></o:p></p>
<p class="MsoNormal">>>           struct kfd_process_device *pdd = qpd_to_pdd(qpd);<o:p></o:p></p>
<p class="MsoNormal">>>           struct mes_add_queue_input queue_input;<o:p></o:p></p>
<p class="MsoNormal">>>           int r, queue_type;<o:p></o:p></p>
<p class="MsoNormal">>> +       uint64_t wptr_addr_off;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>           if (dqm->is_hws_hang)<o:p></o:p></p>
<p class="MsoNormal">>>                           return -EIO;<o:p></o:p></p>
<p class="MsoNormal">>> @@ -196,7 +197,13 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q,<o:p></o:p></p>
<p class="MsoNormal">>>                                                                           AMDGPU_MES_PRIORITY_LEVEL_NORMAL;<o:p></o:p></p>
<p class="MsoNormal">>>           queue_input.doorbell_offset = q->properties.doorbell_off;<o:p></o:p></p>
<p class="MsoNormal">>>           queue_input.mqd_addr = q->gart_mqd_addr;<o:p></o:p></p>
<p class="MsoNormal">>> -        queue_input.wptr_addr = (uint64_t)q->properties.write_ptr;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       if (q->wptr_bo) {<o:p></o:p></p>
<p class="MsoNormal">>> +                       wptr_addr_off = (uint64_t)q->properties.write_ptr - (uint64_t)q->wptr_bo->kfd_bo->va;<o:p></o:p></p>
<p class="MsoNormal">>> +                       queue_input.wptr_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off;<o:p></o:p></p>
<p class="MsoNormal">>> +       } else<o:p></o:p></p>
<p class="MsoNormal">>> +                       queue_input.wptr_addr = (uint64_t)q->properties.write_ptr;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>>           queue_input.paging = false;<o:p></o:p></p>
<p class="MsoNormal">>>           queue_input.tba_addr = qpd->tba_addr;<o:p></o:p></p>
<p class="MsoNormal">>>           queue_input.tma_addr = qpd->tma_addr;<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c<o:p></o:p></p>
<p class="MsoNormal">>> index 4e0387f591be..b8e14c2cc295 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c<o:p></o:p></p>
<p class="MsoNormal">>> @@ -377,6 +377,8 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,<o:p></o:p></p>
<p class="MsoNormal">>>           m->sdmax_rlcx_rb_base_hi = upper_32_bits(q->queue_address >> 8);<o:p></o:p></p>
<p class="MsoNormal">>>           m->sdmax_rlcx_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr);<o:p></o:p></p>
<p class="MsoNormal">>>           m->sdmax_rlcx_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr);<o:p></o:p></p>
<p class="MsoNormal">>> +       m->sdmax_rlcx_rb_wptr_poll_addr_lo = lower_32_bits((uint64_t)q->write_ptr);<o:p></o:p></p>
<p class="MsoNormal">>> +       m->sdmax_rlcx_rb_wptr_poll_addr_hi = upper_32_bits((uint64_t)q->write_ptr);<o:p></o:p></p>
<p class="MsoNormal">>>           m->sdmax_rlcx_doorbell_offset =<o:p></o:p></p>
<p class="MsoNormal">>>                           q->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h<o:p></o:p></p>
<p class="MsoNormal">>> index 91e5fa56f0a2..59ba50ce54d3 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h<o:p></o:p></p>
<p class="MsoNormal">>> @@ -570,6 +570,8 @@ struct queue {<o:p></o:p></p>
<p class="MsoNormal">>>           void *gang_ctx_bo;<o:p></o:p></p>
<p class="MsoNormal">>>           uint64_t gang_ctx_gpu_addr;<o:p></o:p></p>
<p class="MsoNormal">>>           void *gang_ctx_cpu_ptr;<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +       struct amdgpu_bo *wptr_bo;<o:p></o:p></p>
<p class="MsoNormal">>>  };<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>  enum KFD_MQD_TYPE {<o:p></o:p></p>
<p class="MsoNormal">>> @@ -1205,6 +1207,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                                               struct file *f,<o:p></o:p></p>
<p class="MsoNormal">>>                                               struct queue_properties *properties,<o:p></o:p></p>
<p class="MsoNormal">>>                                               unsigned int *qid,<o:p></o:p></p>
<p class="MsoNormal">>> +                                           struct amdgpu_bo *wptr_bo,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const struct kfd_criu_queue_priv_data *q_data,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const void *restore_mqd,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const void *restore_ctl_stack,<o:p></o:p></p>
<p class="MsoNormal">>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> index 99f2a6412201..8db58348de98 100644<o:p></o:p></p>
<p class="MsoNormal">>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c<o:p></o:p></p>
<p class="MsoNormal">>> @@ -180,7 +180,8 @@ void pqm_uninit(struct process_queue_manager *pqm)<o:p></o:p></p>
<p class="MsoNormal">>>  static int init_user_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                                                           struct kfd_dev *dev, struct queue **q,<o:p></o:p></p>
<p class="MsoNormal">>>                                                           struct queue_properties *q_properties,<o:p></o:p></p>
<p class="MsoNormal">>> -                                                        struct file *f, unsigned int qid)<o:p></o:p></p>
<p class="MsoNormal">>> +                                                       struct file *f, struct amdgpu_bo *wptr_bo,<o:p></o:p></p>
<p class="MsoNormal">>> +                                                       unsigned int qid)<o:p></o:p></p>
<p class="MsoNormal">>>  {<o:p></o:p></p>
<p class="MsoNormal">>>           int retval;<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> @@ -210,6 +211,7 @@ static int init_user_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                                           goto cleanup;<o:p></o:p></p>
<p class="MsoNormal">>>                           }<o:p></o:p></p>
<p class="MsoNormal">>>                           memset((*q)->gang_ctx_cpu_ptr, 0, AMDGPU_MES_GANG_CTX_SIZE);<o:p></o:p></p>
<p class="MsoNormal">>> +                       (*q)->wptr_bo = wptr_bo;<o:p></o:p></p>
<p class="MsoNormal">>>           }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>           pr_debug("PQM After init queue");<o:p></o:p></p>
<p class="MsoNormal">>> @@ -226,6 +228,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                                               struct file *f,<o:p></o:p></p>
<p class="MsoNormal">>>                                               struct queue_properties *properties,<o:p></o:p></p>
<p class="MsoNormal">>>                                               unsigned int *qid,<o:p></o:p></p>
<p class="MsoNormal">>> +                                           struct amdgpu_bo *wptr_bo,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const struct kfd_criu_queue_priv_data *q_data,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const void *restore_mqd,<o:p></o:p></p>
<p class="MsoNormal">>>                                               const void *restore_ctl_stack,<o:p></o:p></p>
<p class="MsoNormal">>> @@ -288,7 +291,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                            * allocate_sdma_queue() in create_queue() has the<o:p></o:p></p>
<p class="MsoNormal">>>                            * corresponding check logic.<o:p></o:p></p>
<p class="MsoNormal">>>                            */<o:p></o:p></p>
<p class="MsoNormal">>> -                        retval = init_user_queue(pqm, dev, &q, properties, f, *qid);<o:p></o:p></p>
<p class="MsoNormal">>> +                       retval = init_user_queue(pqm, dev, &q, properties, f, wptr_bo, *qid);<o:p></o:p></p>
<p class="MsoNormal">>>                           if (retval != 0)<o:p></o:p></p>
<p class="MsoNormal">>>                                           goto err_create_queue;<o:p></o:p></p>
<p class="MsoNormal">>>                           pqn->q = q;<o:p></o:p></p>
<p class="MsoNormal">>> @@ -309,7 +312,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,<o:p></o:p></p>
<p class="MsoNormal">>>                                           goto err_create_queue;<o:p></o:p></p>
<p class="MsoNormal">>>                           }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> -                        retval = init_user_queue(pqm, dev, &q, properties, f, *qid);<o:p></o:p></p>
<p class="MsoNormal">>> +                       retval = init_user_queue(pqm, dev, &q, properties, f, wptr_bo, *qid);<o:p></o:p></p>
<p class="MsoNormal">>>                           if (retval != 0)<o:p></o:p></p>
<p class="MsoNormal">>>                                           goto err_create_queue;<o:p></o:p></p>
<p class="MsoNormal">>>                           pqn->q = q;<o:p></o:p></p>
<p class="MsoNormal">>> @@ -435,10 +438,15 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)<o:p></o:p></p>
<p class="MsoNormal">>>                                           pdd->qpd.num_gws = 0;<o:p></o:p></p>
<p class="MsoNormal">>>                           }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> -                        if (dev->shared_resources.enable_mes)<o:p></o:p></p>
<p class="MsoNormal">>> +                       if (dev->shared_resources.enable_mes) {<o:p></o:p></p>
<p class="MsoNormal">>>                                           amdgpu_amdkfd_free_gtt_mem(dev->adev,<o:p></o:p></p>
<p class="MsoNormal">>>                                                                                              pqn->q->gang_ctx_bo);<o:p></o:p></p>
<p class="MsoNormal">>> -                        kfd_procfs_del_queue(pqn->q);<o:p></o:p></p>
<p class="MsoNormal">>> +                                       if (pqn->q->wptr_bo)<o:p></o:p></p>
<p class="MsoNormal">>> +                                                       amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->wptr_bo);<o:p></o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                                       kfd_procfs_del_queue(pqn->q);<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> Seems rebase issue, kfd_procfs_del_queue(pqn->q) should be outside if (dev->shared_resources.enable_mes) {<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Yeah this was a rebase issue. Fixed – thanks!<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">>> +<o:p></o:p></p>
<p class="MsoNormal">>> +                       }<o:p></o:p></p>
<p class="MsoNormal">>>                           uninit_queue(pqn->q);<o:p></o:p></p>
<p class="MsoNormal">>>           }<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> @@ -844,7 +852,7 @@ int kfd_criu_restore_queue(struct kfd_process *p,<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>>           print_queue_properties(&qp);<o:p></o:p></p>
<p class="MsoNormal">>>  <o:p></o:p></p>
<p class="MsoNormal">>> -        ret = pqm_create_queue(&p->pqm, pdd->dev, NULL, &qp, &queue_id, q_data, mqd, ctl_stack,<o:p></o:p></p>
<p class="MsoNormal">>> +       ret = pqm_create_queue(&p->pqm, pdd->dev, NULL, &qp, &queue_id, NULL, q_data, mqd, ctl_stack,<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> CRIU restore user queues should create struct queue wptr_bo GART mapping based on MES API version.<o:p></o:p></p>
<p class="MsoNormal">> Regards,<o:p></o:p></p>
<p class="MsoNormal">> Philip<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As discussed offline since this is somewhat separated this will be modified in a future patch.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best,<o:p></o:p></p>
<p class="MsoNormal">Graham<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">>> <o:p></o:p></p>
<p class="MsoNormal">>>                                                           NULL);<o:p></o:p></p>
<p class="MsoNormal">>>           if (ret) {<o:p></o:p></p>
<p class="MsoNormal">>>                           pr_err("Failed to create new queue err:%d\n", ret);<o:p></o:p></p>
</div>
</body>
</html>