tree:   git://people.freedesktop.org/~agd5f/linux.git drm-next-5.2-wip
head:   5666aea3ea494d4dd96df8f092cab32dbeeac321
commit: ba5896bd6a1a175b21609c6c81dea9813cbf296c [19/42] drm/amdgpu: use HMM 
callback to replace mmu notifier
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout ba5896bd6a1a175b21609c6c81dea9813cbf296c
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: the radeon-alex/drm-next-5.2-wip HEAD 
5666aea3ea494d4dd96df8f092cab32dbeeac321 builds fine.
      It only hurts bisectibility.

All error/warnings (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:87:20: error: field 'mirror' has 
>> incomplete type
     struct hmm_mirror mirror;
                       ^~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: In function 'amdgpu_mn_destroy':
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:131:2: error: implicit declaration of 
>> function 'hmm_mirror_unregister'; did you mean 'drm_dp_aux_unregister'? 
>> [-Werror=implicit-function-declaration]
     hmm_mirror_unregister(&amn->mirror);
     ^~~~~~~~~~~~~~~~~~~~~
     drm_dp_aux_unregister
   In file included from include/linux/firmware.h:6,
                    from drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:46:
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: In function 
'amdgpu_hmm_mirror_release':
>> include/linux/kernel.h:979:32: error: dereferencing pointer to incomplete 
>> type 'struct hmm_mirror'
     BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
                                   ^~~~~~
   include/linux/compiler.h:324:9: note: in definition of macro 
'__compiletime_assert'
      if (!(condition))     \
            ^~~~~~~~~
   include/linux/compiler.h:344:2: note: in expansion of macro 
'_compiletime_assert'
     _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
     ^~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 
'compiletime_assert'
    #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
                                        ^~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:979:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
     BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
     ^~~~~~~~~~~~~~~~
   include/linux/kernel.h:979:20: note: in expansion of macro '__same_type'
     BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
                       ^~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:144:26: note: in expansion of macro 
'container_of'
     struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror);
                             ^~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: At top level:
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:238:17: warning: 'struct hmm_update' 
>> declared inside parameter list will not be visible outside of this 
>> definition or declaration
       const struct hmm_update *update)
                    ^~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: In function 
'amdgpu_mn_sync_pagetables_gfx':
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:241:30: error: dereferencing pointer 
>> to incomplete type 'const struct hmm_update'
     unsigned long start = update->start;
                                 ^~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: At top level:
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:286:17: warning: 'struct hmm_update' 
declared inside parameter list will not be visible outside of this definition 
or declaration
       const struct hmm_update *update)
                    ^~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: In function 
'amdgpu_mn_sync_pagetables_hsa':
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:289:30: error: dereferencing pointer 
to incomplete type 'const struct hmm_update'
     unsigned long start = update->start;
                                 ^~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: At top level:
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:333:30: error: array type has 
>> incomplete element type 'struct hmm_mirror_ops'
    static struct hmm_mirror_ops amdgpu_hmm_mirror_ops[] = {
                                 ^~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:334:3: error: array index in 
>> non-array initializer
     [AMDGPU_MN_TYPE_GFX] = {
      ^~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:334:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:335:3: error: field name not in 
>> record or union initializer
      .sync_cpu_device_pagetables = amdgpu_mn_sync_pagetables_gfx,
      ^
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:335:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:336:3: error: field name not in 
record or union initializer
      .release = amdgpu_hmm_mirror_release
      ^
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:336:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:338:3: error: array index in 
non-array initializer
     [AMDGPU_MN_TYPE_HSA] = {
      ^~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:338:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:339:3: error: field name not in 
record or union initializer
      .sync_cpu_device_pagetables = amdgpu_mn_sync_pagetables_hsa,
      ^
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:339:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:340:3: error: field name not in 
record or union initializer
      .release = amdgpu_hmm_mirror_release
      ^
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:340:3: note: (near initialization for 
'amdgpu_hmm_mirror_ops')
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c: In function 'amdgpu_mn_get':
>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:383:6: error: implicit declaration of 
>> function 'hmm_mirror_register'; did you mean 'drm_dp_aux_register'? 
>> [-Werror=implicit-function-declaration]
     r = hmm_mirror_register(&amn->mirror, mm);
         ^~~~~~~~~~~~~~~~~~~
         drm_dp_aux_register
   At top level:
   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c:333:30: warning: 
'amdgpu_hmm_mirror_ops' defined but not used [-Wunused-variable]
    static struct hmm_mirror_ops amdgpu_hmm_mirror_ops[] = {
                                 ^~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/mirror +87 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c

    55  
    56  /**
    57   * struct amdgpu_mn
    58   *
    59   * @adev: amdgpu device pointer
    60   * @mm: process address space
    61   * @type: type of MMU notifier
    62   * @work: destruction work item
    63   * @node: hash table node to find structure by adev and mn
    64   * @lock: rw semaphore protecting the notifier nodes
    65   * @objects: interval tree containing amdgpu_mn_nodes
    66   * @mirror: HMM mirror function support
    67   *
    68   * Data for each amdgpu device and process address space.
    69   */
    70  struct amdgpu_mn {
    71          /* constant after initialisation */
    72          struct amdgpu_device    *adev;
    73          struct mm_struct        *mm;
    74          enum amdgpu_mn_type     type;
    75  
    76          /* only used on destruction */
    77          struct work_struct      work;
    78  
    79          /* protected by adev->mn_lock */
    80          struct hlist_node       node;
    81  
    82          /* objects protected by lock */
    83          struct rw_semaphore     lock;
    84          struct rb_root_cached   objects;
    85  
    86          /* HMM mirror */
  > 87          struct hmm_mirror       mirror;
    88  };
    89  
    90  /**
    91   * struct amdgpu_mn_node
    92   *
    93   * @it: interval node defining start-last of the affected address range
    94   * @bos: list of all BOs in the affected address range
    95   *
    96   * Manages all BOs which are affected of a certain range of address 
space.
    97   */
    98  struct amdgpu_mn_node {
    99          struct interval_tree_node       it;
   100          struct list_head                bos;
   101  };
   102  
   103  /**
   104   * amdgpu_mn_destroy - destroy the HMM mirror
   105   *
   106   * @work: previously sheduled work item
   107   *
   108   * Lazy destroys the notifier from a work item
   109   */
   110  static void amdgpu_mn_destroy(struct work_struct *work)
   111  {
   112          struct amdgpu_mn *amn = container_of(work, struct amdgpu_mn, 
work);
   113          struct amdgpu_device *adev = amn->adev;
   114          struct amdgpu_mn_node *node, *next_node;
   115          struct amdgpu_bo *bo, *next_bo;
   116  
   117          mutex_lock(&adev->mn_lock);
   118          down_write(&amn->lock);
   119          hash_del(&amn->node);
   120          rbtree_postorder_for_each_entry_safe(node, next_node,
   121                                               &amn->objects.rb_root, 
it.rb) {
   122                  list_for_each_entry_safe(bo, next_bo, &node->bos, 
mn_list) {
   123                          bo->mn = NULL;
   124                          list_del_init(&bo->mn_list);
   125                  }
   126                  kfree(node);
   127          }
   128          up_write(&amn->lock);
   129          mutex_unlock(&adev->mn_lock);
   130  
 > 131          hmm_mirror_unregister(&amn->mirror);
   132          kfree(amn);
   133  }
   134  
   135  /**
   136   * amdgpu_hmm_mirror_release - callback to notify about mm destruction
   137   *
   138   * @mirror: the HMM mirror (mm) this callback is about
   139   *
   140   * Shedule a work item to lazy destroy HMM mirror.
   141   */
   142  static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror)
   143  {
 > 144          struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, 
 > mirror);
   145  
   146          INIT_WORK(&amn->work, amdgpu_mn_destroy);
   147          schedule_work(&amn->work);
   148  }
   149  
   150  /**
   151   * amdgpu_mn_lock - take the write side lock for this notifier
   152   *
   153   * @mn: our notifier
   154   */
   155  void amdgpu_mn_lock(struct amdgpu_mn *mn)
   156  {
   157          if (mn)
   158                  down_write(&mn->lock);
   159  }
   160  
   161  /**
   162   * amdgpu_mn_unlock - drop the write side lock for this notifier
   163   *
   164   * @mn: our notifier
   165   */
   166  void amdgpu_mn_unlock(struct amdgpu_mn *mn)
   167  {
   168          if (mn)
   169                  up_write(&mn->lock);
   170  }
   171  
   172  /**
   173   * amdgpu_mn_read_lock - take the read side lock for this notifier
   174   *
   175   * @amn: our notifier
   176   */
   177  static int amdgpu_mn_read_lock(struct amdgpu_mn *amn, bool blockable)
   178  {
   179          if (blockable)
   180                  down_read(&amn->lock);
   181          else if (!down_read_trylock(&amn->lock))
   182                  return -EAGAIN;
   183  
   184          return 0;
   185  }
   186  
   187  /**
   188   * amdgpu_mn_read_unlock - drop the read side lock for this notifier
   189   *
   190   * @amn: our notifier
   191   */
   192  static void amdgpu_mn_read_unlock(struct amdgpu_mn *amn)
   193  {
   194          up_read(&amn->lock);
   195  }
   196  
   197  /**
   198   * amdgpu_mn_invalidate_node - unmap all BOs of a node
   199   *
   200   * @node: the node with the BOs to unmap
   201   * @start: start of address range affected
   202   * @end: end of address range affected
   203   *
   204   * Block for operations on BOs to finish and mark pages as accessed and
   205   * potentially dirty.
   206   */
   207  static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
   208                                        unsigned long start,
   209                                        unsigned long end)
   210  {
   211          struct amdgpu_bo *bo;
   212          long r;
   213  
   214          list_for_each_entry(bo, &node->bos, mn_list) {
   215  
   216                  if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, 
end))
   217                          continue;
   218  
   219                  r = reservation_object_wait_timeout_rcu(bo->tbo.resv,
   220                          true, false, MAX_SCHEDULE_TIMEOUT);
   221                  if (r <= 0)
   222                          DRM_ERROR("(%ld) failed to wait for user bo\n", 
r);
   223  
   224                  amdgpu_ttm_tt_mark_user_pages(bo->tbo.ttm);
   225          }
   226  }
   227  
   228  /**
   229   * amdgpu_mn_sync_pagetables_gfx - callback to notify about mm change
   230   *
   231   * @mirror: the hmm_mirror (mm) is about to update
   232   * @update: the update start, end address
   233   *
   234   * Block for operations on BOs to finish and mark pages as accessed and
   235   * potentially dirty.
   236   */
   237  static int amdgpu_mn_sync_pagetables_gfx(struct hmm_mirror *mirror,
 > 238                          const struct hmm_update *update)
   239  {
   240          struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, 
mirror);
 > 241          unsigned long start = update->start;
   242          unsigned long end = update->end;
   243          bool blockable = update->blockable;
   244          struct interval_tree_node *it;
   245  
   246          /* notification is exclusive, but interval is inclusive */
   247          end -= 1;
   248  
   249          /* TODO we should be able to split locking for interval tree and
   250           * amdgpu_mn_invalidate_node
   251           */
   252          if (amdgpu_mn_read_lock(amn, blockable))
   253                  return -EAGAIN;
   254  
   255          it = interval_tree_iter_first(&amn->objects, start, end);
   256          while (it) {
   257                  struct amdgpu_mn_node *node;
   258  
   259                  if (!blockable) {
   260                          amdgpu_mn_read_unlock(amn);
   261                          return -EAGAIN;
   262                  }
   263  
   264                  node = container_of(it, struct amdgpu_mn_node, it);
   265                  it = interval_tree_iter_next(it, start, end);
   266  
   267                  amdgpu_mn_invalidate_node(node, start, end);
   268          }
   269  
   270          amdgpu_mn_read_unlock(amn);
   271  
   272          return 0;
   273  }
   274  
   275  /**
   276   * amdgpu_mn_sync_pagetables_hsa - callback to notify about mm change
   277   *
   278   * @mirror: the hmm_mirror (mm) is about to update
   279   * @update: the update start, end address
   280   *
   281   * We temporarily evict all BOs between start and end. This
   282   * necessitates evicting all user-mode queues of the process. The BOs
   283   * are restorted in amdgpu_mn_invalidate_range_end_hsa.
   284   */
   285  static int amdgpu_mn_sync_pagetables_hsa(struct hmm_mirror *mirror,
 > 286                          const struct hmm_update *update)
   287  {
   288          struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, 
mirror);
   289          unsigned long start = update->start;
   290          unsigned long end = update->end;
   291          bool blockable = update->blockable;
   292          struct interval_tree_node *it;
   293  
   294          /* notification is exclusive, but interval is inclusive */
   295          end -= 1;
   296  
   297          if (amdgpu_mn_read_lock(amn, blockable))
   298                  return -EAGAIN;
   299  
   300          it = interval_tree_iter_first(&amn->objects, start, end);
   301          while (it) {
   302                  struct amdgpu_mn_node *node;
   303                  struct amdgpu_bo *bo;
   304  
   305                  if (!blockable) {
   306                          amdgpu_mn_read_unlock(amn);
   307                          return -EAGAIN;
   308                  }
   309  
   310                  node = container_of(it, struct amdgpu_mn_node, it);
   311                  it = interval_tree_iter_next(it, start, end);
   312  
   313                  list_for_each_entry(bo, &node->bos, mn_list) {
   314                          struct kgd_mem *mem = bo->kfd_bo;
   315  
   316                          if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm,
   317                                                           start, end))
   318                                  amdgpu_amdkfd_evict_userptr(mem, 
amn->mm);
   319                  }
   320          }
   321  
   322          amdgpu_mn_read_unlock(amn);
   323  
   324          return 0;
   325  }
   326  

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Attachment: .config.gz
Description: application/gzip

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to