]> Git Repo - linux.git/commitdiff
Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
authorLinus Torvalds <[email protected]>
Thu, 2 Apr 2020 00:57:52 +0000 (17:57 -0700)
committerLinus Torvalds <[email protected]>
Thu, 2 Apr 2020 00:57:52 +0000 (17:57 -0700)
Pull hmm updates from Jason Gunthorpe:
 "This series focuses on corner case bug fixes and general clarity
  improvements to hmm_range_fault(). It arose from a review of
  hmm_range_fault() by Christoph, Ralph and myself.

  hmm_range_fault() is being used by these 'SVM' style drivers to
  non-destructively read the page tables. It is very similar to
  get_user_pages() except that the output is an array of PFNs and
  per-pfn flags, and it has various modes of reading.

  This is necessary before RDMA ODP can be converted, as we don't want
  to have weird corner case regressions, which is still a looking
  forward item. Ralph has a nice tester for this routine, but it is
  waiting for feedback from the selftests maintainers.

  Summary:

   - 9 bug fixes

   - Allow pgmap to track the 'owner' of a DEVICE_PRIVATE - in this case
     the owner tells the driver if it can understand the DEVICE_PRIVATE
     page or not. Use this to resolve a bug in nouveau where it could
     touch DEVICE_PRIVATE pages from other drivers.

   - Remove a bunch of dead, redundant or unused code and flags

   - Clarity improvements to hmm_range_fault()"

* tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (25 commits)
  mm/hmm: return error for non-vma snapshots
  mm/hmm: do not set pfns when returning an error code
  mm/hmm: do not unconditionally set pfns when returning EBUSY
  mm/hmm: use device_private_entry_to_pfn()
  mm/hmm: remove HMM_FAULT_SNAPSHOT
  mm/hmm: remove unused code and tidy comments
  mm/hmm: return the fault type from hmm_pte_need_fault()
  mm/hmm: remove pgmap checking for devmap pages
  mm/hmm: check the device private page owner in hmm_range_fault()
  mm: simplify device private page handling in hmm_range_fault
  mm: handle multiple owners of device private pages in migrate_vma
  memremap: add an owner field to struct dev_pagemap
  mm: merge hmm_vma_do_fault into into hmm_vma_walk_hole_
  mm/hmm: don't handle the non-fault case in hmm_vma_walk_hole_()
  mm/hmm: simplify hmm_vma_walk_hugetlb_entry()
  mm/hmm: remove the unused HMM_FAULT_ALLOW_RETRY flag
  mm/hmm: don't provide a stub for hmm_range_fault()
  mm/hmm: do not check pmd_protnone twice in hmm_vma_handle_pmd()
  mm/hmm: add missing call to hmm_pte_need_fault in HMM_PFN_SPECIAL handling
  mm/hmm: return -EFAULT when setting HMM_PFN_ERROR on requested valid pages
  ...

1  2 
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

index 9f44ba7d9d972b5e2651761f11a65c102fd4abd1,c520290709371b58a5337b49381ed9a18178148e..6309ff72bd78765f45baa9772058becc52dbf12e
  #include "amdgpu_ras.h"
  #include "bif/bif_4_1_d.h"
  
 +#define AMDGPU_TTM_VRAM_MAX_DW_READ   (size_t)128
 +
  static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
                             struct ttm_mem_reg *mem, unsigned num_pages,
                             uint64_t offset, unsigned window,
                             struct amdgpu_ring *ring,
                             uint64_t *addr);
  
 -static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
 -static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev);
 -
 -static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
 -{
 -      return 0;
 -}
 -
  /**
   * amdgpu_init_mem_type - Initialize a memory manager for a specific type of
   * memory request.
@@@ -770,7 -776,6 +770,6 @@@ struct amdgpu_ttm_tt 
  static const uint64_t hmm_range_flags[HMM_PFN_FLAG_MAX] = {
        (1 << 0), /* HMM_PFN_VALID */
        (1 << 1), /* HMM_PFN_WRITE */
-       0 /* HMM_PFN_DEVICE_PRIVATE */
  };
  
  static const uint64_t hmm_range_values[HMM_PFN_VALUE_MAX] = {
@@@ -851,7 -856,7 +850,7 @@@ retry
        range->notifier_seq = mmu_interval_read_begin(&bo->notifier);
  
        down_read(&mm->mmap_sem);
-       r = hmm_range_fault(range, 0);
+       r = hmm_range_fault(range);
        up_read(&mm->mmap_sem);
        if (unlikely(r <= 0)) {
                /*
@@@ -968,7 -973,7 +967,7 @@@ static int amdgpu_ttm_tt_pin_userptr(st
        /* Map SG to device */
        r = -ENOMEM;
        nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
 -      if (nents != ttm->sg->nents)
 +      if (nents == 0)
                goto release_sg;
  
        /* convert SG to linear array of pages and dma addresses */
@@@ -1028,7 -1033,7 +1027,7 @@@ int amdgpu_ttm_gart_bind(struct amdgpu_
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
        int r;
  
 -      if (abo->flags & AMDGPU_GEM_CREATE_MQD_GFX9) {
 +      if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
                uint64_t page_idx = 1;
  
                r = amdgpu_gart_bind(adev, gtt->offset, page_idx,
                if (r)
                        goto gart_bind_fail;
  
 -              /* Patch mtype of the second part BO */
 +              /* The memory type of the first page defaults to UC. Now
 +               * modify the memory type to NC from the second page of
 +               * the BO onward.
 +               */
                flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK;
                flags |= AMDGPU_PTE_MTYPE_VG10(AMDGPU_MTYPE_NC);
  
@@@ -1593,7 -1595,7 +1592,7 @@@ static int amdgpu_ttm_access_memory(str
  
        while (len && pos < adev->gmc.mc_vram_size) {
                uint64_t aligned_pos = pos & ~(uint64_t)3;
 -              uint32_t bytes = 4 - (pos & 3);
 +              uint64_t bytes = 4 - (pos & 3);
                uint32_t shift = (pos & 3) * 8;
                uint32_t mask = 0xffffffff << shift;
  
                        bytes = len;
                }
  
 -              spin_lock_irqsave(&adev->mmio_idx_lock, flags);
 -              WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
 -              WREG32_NO_KIQ(mmMM_INDEX_HI, aligned_pos >> 31);
 -              if (!write || mask != 0xffffffff)
 -                      value = RREG32_NO_KIQ(mmMM_DATA);
 -              if (write) {
 -                      value &= ~mask;
 -                      value |= (*(uint32_t *)buf << shift) & mask;
 -                      WREG32_NO_KIQ(mmMM_DATA, value);
 -              }
 -              spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
 -              if (!write) {
 -                      value = (value & mask) >> shift;
 -                      memcpy(buf, &value, bytes);
 +              if (mask != 0xffffffff) {
 +                      spin_lock_irqsave(&adev->mmio_idx_lock, flags);
 +                      WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
 +                      WREG32_NO_KIQ(mmMM_INDEX_HI, aligned_pos >> 31);
 +                      if (!write || mask != 0xffffffff)
 +                              value = RREG32_NO_KIQ(mmMM_DATA);
 +                      if (write) {
 +                              value &= ~mask;
 +                              value |= (*(uint32_t *)buf << shift) & mask;
 +                              WREG32_NO_KIQ(mmMM_DATA, value);
 +                      }
 +                      spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
 +                      if (!write) {
 +                              value = (value & mask) >> shift;
 +                              memcpy(buf, &value, bytes);
 +                      }
 +              } else {
 +                      bytes = (nodes->start + nodes->size) << PAGE_SHIFT;
 +                      bytes = min(bytes - pos, (uint64_t)len & ~0x3ull);
 +
 +                      amdgpu_device_vram_access(adev, pos, (uint32_t *)buf,
 +                                                bytes, write);
                }
  
                ret += bytes;
@@@ -1643,6 -1637,7 +1642,6 @@@ static struct ttm_bo_driver amdgpu_bo_d
        .ttm_tt_create = &amdgpu_ttm_tt_create,
        .ttm_tt_populate = &amdgpu_ttm_tt_populate,
        .ttm_tt_unpopulate = &amdgpu_ttm_tt_unpopulate,
 -      .invalidate_caches = &amdgpu_invalidate_caches,
        .init_mem_type = &amdgpu_init_mem_type,
        .eviction_valuable = amdgpu_ttm_bo_eviction_valuable,
        .evict_flags = &amdgpu_evict_flags,
@@@ -1840,11 -1835,9 +1839,11 @@@ int amdgpu_ttm_init(struct amdgpu_devic
         *The reserved vram for memory training must be pinned to the specified
         *place on the VRAM, so reserve it early.
         */
 -      r = amdgpu_ttm_training_reserve_vram_init(adev);
 -      if (r)
 -              return r;
 +      if (!amdgpu_sriov_vf(adev)) {
 +              r = amdgpu_ttm_training_reserve_vram_init(adev);
 +              if (r)
 +                      return r;
 +      }
  
        /* allocate memory as required for VGA
         * This is used for VGA emulation and pre-OS scanout buffers to
                return r;
        }
  
 -      /* Register debugfs entries for amdgpu_ttm */
 -      r = amdgpu_ttm_debugfs_init(adev);
 -      if (r) {
 -              DRM_ERROR("Failed to init debugfs\n");
 -              return r;
 -      }
        return 0;
  }
  
@@@ -1938,6 -1937,7 +1937,6 @@@ void amdgpu_ttm_fini(struct amdgpu_devi
        if (!adev->mman.initialized)
                return;
  
 -      amdgpu_ttm_debugfs_fini(adev);
        amdgpu_ttm_training_reserve_vram_fini(adev);
        /* return the IP Discovery TMR memory back to VRAM */
        amdgpu_bo_free_kernel(&adev->discovery_memory, NULL, NULL);
@@@ -2112,8 -2112,8 +2111,8 @@@ int amdgpu_copy_buffer(struct amdgpu_ri
        }
        if (resv) {
                r = amdgpu_sync_resv(adev, &job->sync, resv,
 -                                   AMDGPU_FENCE_OWNER_UNDEFINED,
 -                                   false);
 +                                   AMDGPU_SYNC_ALWAYS,
 +                                   AMDGPU_FENCE_OWNER_UNDEFINED);
                if (r) {
                        DRM_ERROR("sync failed (%d).\n", r);
                        goto error_free;
@@@ -2197,8 -2197,7 +2196,8 @@@ int amdgpu_fill_buffer(struct amdgpu_b
  
        if (resv) {
                r = amdgpu_sync_resv(adev, &job->sync, resv,
 -                                   AMDGPU_FENCE_OWNER_UNDEFINED, false);
 +                                   AMDGPU_SYNC_ALWAYS,
 +                                   AMDGPU_FENCE_OWNER_UNDEFINED);
                if (r) {
                        DRM_ERROR("sync failed (%d).\n", r);
                        goto error_free;
@@@ -2279,6 -2278,7 +2278,6 @@@ static ssize_t amdgpu_ttm_vram_read(str
  {
        struct amdgpu_device *adev = file_inode(f)->i_private;
        ssize_t result = 0;
 -      int r;
  
        if (size & 0x3 || *pos & 0x3)
                return -EINVAL;
        if (*pos >= adev->gmc.mc_vram_size)
                return -ENXIO;
  
 +      size = min(size, (size_t)(adev->gmc.mc_vram_size - *pos));
        while (size) {
 -              unsigned long flags;
 -              uint32_t value;
 -
 -              if (*pos >= adev->gmc.mc_vram_size)
 -                      return result;
 -
 -              spin_lock_irqsave(&adev->mmio_idx_lock, flags);
 -              WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)*pos) | 0x80000000);
 -              WREG32_NO_KIQ(mmMM_INDEX_HI, *pos >> 31);
 -              value = RREG32_NO_KIQ(mmMM_DATA);
 -              spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
 +              size_t bytes = min(size, AMDGPU_TTM_VRAM_MAX_DW_READ * 4);
 +              uint32_t value[AMDGPU_TTM_VRAM_MAX_DW_READ];
  
 -              r = put_user(value, (uint32_t *)buf);
 -              if (r)
 -                      return r;
 +              amdgpu_device_vram_access(adev, *pos, value, bytes, false);
 +              if (copy_to_user(buf, value, bytes))
 +                      return -EFAULT;
  
 -              result += 4;
 -              buf += 4;
 -              *pos += 4;
 -              size -= 4;
 +              result += bytes;
 +              buf += bytes;
 +              *pos += bytes;
 +              size -= bytes;
        }
  
        return result;
@@@ -2535,7 -2543,7 +2534,7 @@@ static const struct 
  
  #endif
  
 -static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev)
 +int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev)
  {
  #if defined(CONFIG_DEBUG_FS)
        unsigned count;
        return 0;
  #endif
  }
 -
 -static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev)
 -{
 -#if defined(CONFIG_DEBUG_FS)
 -      unsigned i;
 -
 -      for (i = 0; i < ARRAY_SIZE(ttm_debugfs_entries); i++)
 -              debugfs_remove(adev->mman.debugfs_entries[i]);
 -#endif
 -}
This page took 0.090869 seconds and 4 git commands to generate.