<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 2023-10-19 16:05, Felix Kuehling
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
      <br>
      On 2023-10-18 18:26, Alex Sierra wrote:
      <br>
      <blockquote type="cite">Split SVM ranges that have been mapped
        into 2MB page table entries,
        <br>
        require to be remap in case the split has happened in a
        non-aligned
        <br>
        VA.
        <br>
        [WHY]:
        <br>
        This condition causes the 2MB page table entries be split into
        4KB
        <br>
        PTEs.
        <br>
        <br>
        Signed-off-by: Alex Sierra <a class="moz-txt-link-rfc2396E" href="mailto:alex.sierra@amd.com"><alex.sierra@amd.com></a>
        <br>
        ---
        <br>
          drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 45
        +++++++++++++++++++++-------
        <br>
          1 file changed, 34 insertions(+), 11 deletions(-)
        <br>
        <br>
        diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
        b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
        <br>
        index 7b81233bc9ae..1dd9a1cf2358 100644
        <br>
        --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
        <br>
        +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
        <br>
        @@ -1104,26 +1104,34 @@ svm_range_split(struct svm_range
        *prange, uint64_t start, uint64_t last,
        <br>
          }
        <br>
            static int
        <br>
        -svm_range_split_tail(struct svm_range *prange,
        <br>
        -             uint64_t new_last, struct list_head *insert_list)
        <br>
        +svm_range_split_tail(struct svm_range *prange, uint64_t
        new_last,
        <br>
        +             struct list_head *insert_list, struct list_head
        *remap_list)
        <br>
          {
        <br>
              struct svm_range *tail;
        <br>
              int r = svm_range_split(prange, prange->start,
        new_last, &tail);
        <br>
          -    if (!r)
        <br>
        +    if (!r) {
        <br>
                  list_add(&tail->list, insert_list);
        <br>
        +        if (!IS_ALIGNED(tail->last + 1 - tail->start,
        <br>
        +                1UL << tail->granularity))
        <br>
      </blockquote>
      <br>
      I'm not sure about this condition. I thought this condition should
      be about the point where the range is split, not the size of it.
      So my understanding is that this should be
      <br>
      <br>
              if (!IS_ALIGNED(new_last+1, 1UL <<
      prange->granularity))
      <br>
    </blockquote>
    <p>I think prange->granularity is not always 9, 512 pages, we
      should check the original prange size is larger than 512.<br>
    </p>
    <p>          if (!IS_ALIGNED(new_last + 1, 512) &&
      tail->last - prange->start >= 512)<br>
    </p>
    <blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
      <br>
      <br>
      <blockquote type="cite">+           
        list_add(&tail->update_list, remap_list);
        <br>
        +    }
        <br>
              return r;
        <br>
          }
        <br>
            static int
        <br>
        -svm_range_split_head(struct svm_range *prange,
        <br>
        -             uint64_t new_start, struct list_head *insert_list)
        <br>
        +svm_range_split_head(struct svm_range *prange, uint64_t
        new_start,
        <br>
        +             struct list_head *insert_list, struct list_head
        *remap_list)
        <br>
          {
        <br>
              struct svm_range *head;
        <br>
              int r = svm_range_split(prange, new_start,
        prange->last, &head);
        <br>
          -    if (!r)
        <br>
        +    if (!r) {
        <br>
                  list_add(&head->list, insert_list);
        <br>
        +        if (!IS_ALIGNED(head->last + 1 - head->start,
        <br>
        +                1UL << head->granularity))
        <br>
      </blockquote>
      <br>
      Similar as above.
      <br>
      <br>
              if (!IS_ALIGNED(new_start, 1UL <<
      prange->granularity))
      <br>
    </blockquote>
    <p>          if (!IS_ALIGNED(new_start, 512) &&
      prange->last - head->start >= 512)</p>
    <blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
      <br>
      Regards,
      <br>
        Felix
      <br>
      <br>
      <br>
      <blockquote type="cite">+           
        list_add(&head->update_list, remap_list);
        <br>
        +    }
        <br>
              return r;
        <br>
          }
        <br>
          @@ -2113,7 +2121,7 @@ static int
        <br>
          svm_range_add(struct kfd_process *p, uint64_t start, uint64_t
        size,
        <br>
                    uint32_t nattr, struct kfd_ioctl_svm_attribute
        *attrs,
        <br>
                    struct list_head *update_list, struct list_head
        *insert_list,
        <br>
        -          struct list_head *remove_list)
        <br>
        +          struct list_head *remove_list, struct list_head
        *remap_list)
        <br>
          {
        <br>
              unsigned long last = start + size - 1UL;
        <br>
              struct svm_range_list *svms = &p->svms;
        <br>
        @@ -2129,6 +2137,7 @@ svm_range_add(struct kfd_process *p,
        uint64_t start, uint64_t size,
        <br>
              INIT_LIST_HEAD(insert_list);
        <br>
              INIT_LIST_HEAD(remove_list);
        <br>
              INIT_LIST_HEAD(&new_list);
        <br>
        +    INIT_LIST_HEAD(remap_list);
        <br>
                node = interval_tree_iter_first(&svms->objects,
        start, last);
        <br>
              while (node) {
        <br>
        @@ -2153,6 +2162,7 @@ svm_range_add(struct kfd_process *p,
        uint64_t start, uint64_t size,
        <br>
                      struct svm_range *old = prange;
        <br>
                        prange = svm_range_clone(old);
        <br>
        +
        <br>
      </blockquote>
    </blockquote>
    <p>unnecessary change.</p>
    <p>Regards,</p>
    <p>Philip<br>
    </p>
    <blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
      <blockquote type="cite">              if (!prange) {
        <br>
                          r = -ENOMEM;
        <br>
                          goto out;
        <br>
        @@ -2161,18 +2171,17 @@ svm_range_add(struct kfd_process *p,
        uint64_t start, uint64_t size,
        <br>
                      list_add(&old->update_list, remove_list);
        <br>
                      list_add(&prange->list, insert_list);
        <br>
                      list_add(&prange->update_list,
        update_list);
        <br>
        -
        <br>
                      if (node->start < start) {
        <br>
                          pr_debug("change old range start\n");
        <br>
                          r = svm_range_split_head(prange, start,
        <br>
        -                             insert_list);
        <br>
        +                             insert_list, remap_list);
        <br>
                          if (r)
        <br>
                              goto out;
        <br>
                      }
        <br>
                      if (node->last > last) {
        <br>
                          pr_debug("change old range last\n");
        <br>
                          r = svm_range_split_tail(prange, last,
        <br>
        -                             insert_list);
        <br>
        +                             insert_list, remap_list);
        <br>
                          if (r)
        <br>
                              goto out;
        <br>
                      }
        <br>
        @@ -3565,6 +3574,7 @@ svm_range_set_attr(struct kfd_process *p,
        struct mm_struct *mm,
        <br>
              struct list_head update_list;
        <br>
              struct list_head insert_list;
        <br>
              struct list_head remove_list;
        <br>
        +    struct list_head remap_list;
        <br>
              struct svm_range_list *svms;
        <br>
              struct svm_range *prange;
        <br>
              struct svm_range *next;
        <br>
        @@ -3596,7 +3606,7 @@ svm_range_set_attr(struct kfd_process *p,
        struct mm_struct *mm,
        <br>
                /* Add new range and split existing ranges as needed */
        <br>
              r = svm_range_add(p, start, size, nattr, attrs,
        &update_list,
        <br>
        -              &insert_list, &remove_list);
        <br>
        +              &insert_list, &remove_list,
        &remap_list);
        <br>
              if (r) {
        <br>
                  mutex_unlock(&svms->lock);
        <br>
                  mmap_write_unlock(mm);
        <br>
        @@ -3661,6 +3671,19 @@ svm_range_set_attr(struct kfd_process *p,
        struct mm_struct *mm,
        <br>
                      ret = r;
        <br>
              }
        <br>
          +    list_for_each_entry(prange, &remap_list, update_list)
        {
        <br>
        +        pr_debug("Remapping prange 0x%p [0x%lx 0x%lx]\n",
        <br>
        +             prange, prange->start, prange->last);
        <br>
        +        mutex_lock(&prange->migrate_mutex);
        <br>
        +        r = svm_range_validate_and_map(mm, prange,
        MAX_GPU_INSTANCE,
        <br>
        +                           true, true,
        prange->mapped_to_gpu);
        <br>
        +        if (r)
        <br>
        +            pr_debug("failed %d on remap svm range\n", r);
        <br>
        +        mutex_unlock(&prange->migrate_mutex);
        <br>
        +        if (r)
        <br>
        +            ret = r;
        <br>
        +    }
        <br>
        +
        <br>
              dynamic_svm_range_dump(svms);
        <br>
                mutex_unlock(&svms->lock);
        <br>
      </blockquote>
    </blockquote>
  </body>
</html>