tree:   https://gitlab.freedesktop.org/drm/misc/kernel.git for-linux-next
head:   34e27b90552acf21bd73aac395667c8aae6da480
commit: 34e27b90552acf21bd73aac395667c8aae6da480 [1/1] nouveau/instmem: use 
iomapping interface for instmem handling
config: alpha-randconfig-r122-20260713 
(https://download.01.org/0day-ci/archive/20260713/[email protected]/config)
compiler: alpha-linux-gcc (GCC) 16.1.0
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20260713/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: 
https://lore.kernel.org/oe-kbuild-all/[email protected]/

sparse warnings: (new ones prefixed by >>)
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:109:58: sparse: sparse: 
incorrect type in argument 2 (different address spaces) @@     expected void 
[noderef] __iomem * @@     got void * @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:109:58: sparse:     
expected void [noderef] __iomem *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:109:58: sparse:     got 
void *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:115:58: sparse: sparse: 
incorrect type in argument 1 (different address spaces) @@     expected void 
const [noderef] __iomem * @@     got void * @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:115:58: sparse:     
expected void const [noderef] __iomem *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:115:58: sparse:     got 
void *
>> drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:161:34: sparse: sparse: 
>> incorrect type in argument 1 (different address spaces) @@     expected void 
>> [noderef] __iomem *vaddr @@     got void *[assigned] emap @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:161:34: sparse:     
expected void [noderef] __iomem *vaddr
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:161:34: sparse:     got 
void *[assigned] emap
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:178:19: sparse: sparse: 
incorrect type in assignment (different address spaces) @@     expected void 
*map @@     got void [noderef] __iomem * @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:178:19: sparse:     
expected void *map
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:178:19: sparse:     got 
void [noderef] __iomem *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:240:28: sparse: sparse: 
incorrect type in return expression (different address spaces) @@     expected 
void [noderef] __iomem * @@     got void *map @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:240:28: sparse:     
expected void [noderef] __iomem *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:240:28: sparse:     got 
void *map
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:249:28: sparse: sparse: 
incorrect type in return expression (different address spaces) @@     expected 
void [noderef] __iomem * @@     got void *map @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:249:28: sparse:     
expected void [noderef] __iomem *
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:249:28: sparse:     got 
void *map
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:256:21: sparse: sparse: 
incorrect type in assignment (different address spaces) @@     expected void 
[noderef] __iomem *map @@     got void *map @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:256:21: sparse:     
expected void [noderef] __iomem *map
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:256:21: sparse:     got 
void *map
>> drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:350:34: sparse: sparse: 
>> incorrect type in argument 1 (different address spaces) @@     expected void 
>> [noderef] __iomem *vaddr @@     got void *[assigned] map @@
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:350:34: sparse:     
expected void [noderef] __iomem *vaddr
   drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c:350:34: sparse:     got 
void *[assigned] map

vim +161 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c

   123  
   124  static void
   125  nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm)
   126  {
   127          struct nv50_instmem *imem = iobj->imem;
   128          struct nv50_instobj *eobj;
   129          struct nvkm_memory *memory = &iobj->base.memory;
   130          struct nvkm_subdev *subdev = &imem->base.subdev;
   131          struct nvkm_vma *bar = NULL, *ebar;
   132          u64 size = nvkm_memory_size(memory);
   133          void *emap;
   134          int ret;
   135  
   136          /* Attempt to allocate BAR2 address-space and map the object
   137           * into it.  The lock has to be dropped while doing this due
   138           * to the possibility of recursion for page table allocation.
   139           */
   140          mutex_unlock(&imem->base.mutex);
   141          while ((ret = nvkm_vmm_get(vmm, 12, size, &bar))) {
   142                  /* Evict unused mappings, and keep retrying until we 
either
   143                   * succeed,or there's no more objects left on the LRU.
   144                   */
   145                  mutex_lock(&imem->base.mutex);
   146                  eobj = list_first_entry_or_null(&imem->lru, 
typeof(*eobj), lru);
   147                  if (eobj) {
   148                          nvkm_debug(subdev, "evict %016llx %016llx @ 
%016llx\n",
   149                                     nvkm_memory_addr(&eobj->base.memory),
   150                                     nvkm_memory_size(&eobj->base.memory),
   151                                     eobj->bar->addr);
   152                          list_del_init(&eobj->lru);
   153                          ebar = eobj->bar;
   154                          eobj->bar = NULL;
   155                          emap = eobj->map;
   156                          eobj->map = NULL;
   157                  }
   158                  mutex_unlock(&imem->base.mutex);
   159                  if (!eobj)
   160                          break;
 > 161                  io_mapping_unmap(emap);
   162                  nvkm_vmm_put(vmm, &ebar);
   163          }
   164  
   165          if (ret == 0)
   166                  ret = nvkm_memory_map(memory, 0, vmm, bar, NULL, 0);
   167          mutex_lock(&imem->base.mutex);
   168          if (ret || iobj->bar) {
   169                  /* We either failed, or another thread beat us. */
   170                  mutex_unlock(&imem->base.mutex);
   171                  nvkm_vmm_put(vmm, &bar);
   172                  mutex_lock(&imem->base.mutex);
   173                  return;
   174          }
   175  
   176          /* Make the mapping visible to the host. */
   177          iobj->bar = bar;
   178          iobj->map = io_mapping_map_wc(&imem->iomap, 
(u32)iobj->bar->addr, size);
   179          if (!iobj->map) {
   180                  nvkm_warn(subdev, "PRAMIN ioremap failed\n");
   181                  nvkm_vmm_put(vmm, &iobj->bar);
   182          }
   183  }
   184  
   185  static int
   186  nv50_instobj_map(struct nvkm_memory *memory, u64 offset, struct 
nvkm_vmm *vmm,
   187                   struct nvkm_vma *vma, void *argv, u32 argc)
   188  {
   189          memory = nv50_instobj(memory)->ram;
   190          return nvkm_memory_map(memory, offset, vmm, vma, argv, argc);
   191  }
   192  
   193  static bool
   194  check_io_mapping(struct nv50_instmem *imem)
   195  {
   196          struct nvkm_device *device = imem->base.subdev.device;
   197  
   198          return io_mapping_init_wc(&imem->iomap,
   199                                    device->func->resource_addr(device, 
NVKM_BAR2_INST),
   200                                    device->func->resource_size(device, 
NVKM_BAR2_INST)) != NULL;
   201  }
   202  
   203  static void
   204  nv50_instobj_release(struct nvkm_memory *memory)
   205  {
   206          struct nv50_instobj *iobj = nv50_instobj(memory);
   207          struct nv50_instmem *imem = iobj->imem;
   208          struct nvkm_subdev *subdev = &imem->base.subdev;
   209  
   210          wmb();
   211          nvkm_bar_flush(subdev->device->bar);
   212  
   213          if (refcount_dec_and_mutex_lock(&iobj->maps, 
&imem->base.mutex)) {
   214                  /* Add the now-unused mapping to the LRU instead of 
directly
   215                   * unmapping it here, in case we need to map it again 
later.
   216                   */
   217                  if (likely(iobj->lru.next) && iobj->map) {
   218                          BUG_ON(!list_empty(&iobj->lru));
   219                          list_add_tail(&iobj->lru, &imem->lru);
   220                  }
   221  
   222                  /* Switch back to NULL accessors when last map is gone. 
*/
   223                  iobj->base.memory.ptrs = NULL;
   224                  mutex_unlock(&imem->base.mutex);
   225          }
   226  }
   227  
   228  static void __iomem *
   229  nv50_instobj_acquire(struct nvkm_memory *memory)
   230  {
   231          struct nv50_instobj *iobj = nv50_instobj(memory);
   232          struct nvkm_instmem *imem = &iobj->imem->base;
   233          struct nvkm_vmm *vmm;
   234          void __iomem *map = NULL;
   235  
   236          /* Already mapped? */
   237          if (refcount_inc_not_zero(&iobj->maps)) {
   238                  /* read barrier match the wmb on refcount set */
   239                  smp_rmb();
   240                  return iobj->map;
   241          }
   242  
   243          /* Take the lock, and re-check that another thread hasn't
   244           * already mapped the object in the meantime.
   245           */
   246          mutex_lock(&imem->mutex);
   247          if (refcount_inc_not_zero(&iobj->maps)) {
   248                  mutex_unlock(&imem->mutex);
   249                  return iobj->map;
   250          }
   251  
   252          /* Attempt to get a direct CPU mapping of the object. */
   253          if ((vmm = nvkm_bar_bar2_vmm(imem->subdev.device))) {
   254                  if (!iobj->map && iobj->imem->iomap.size)
   255                          nv50_instobj_kmap(iobj, vmm);
   256                  map = iobj->map;
   257          }
   258  
   259          if (!refcount_inc_not_zero(&iobj->maps)) {
   260                  /* Exclude object from eviction while it's being 
accessed. */
   261                  if (likely(iobj->lru.next))
   262                          list_del_init(&iobj->lru);
   263  
   264                  if (map)
   265                          iobj->base.memory.ptrs = &nv50_instobj_fast;
   266                  else
   267                          iobj->base.memory.ptrs = &nv50_instobj_slow;
   268                  /* barrier to ensure the ptrs are written before 
refcount is set */
   269                  smp_wmb();
   270                  refcount_set(&iobj->maps, 1);
   271          }
   272  
   273          mutex_unlock(&imem->mutex);
   274          return map;
   275  }
   276  
   277  static void
   278  nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vmm *vmm)
   279  {
   280          struct nv50_instobj *iobj = nv50_instobj(memory);
   281          struct nvkm_instmem *imem = &iobj->imem->base;
   282  
   283          /* Exclude bootstrapped objects (ie. the page tables for the
   284           * instmem BAR itself) from eviction.
   285           */
   286          mutex_lock(&imem->mutex);
   287          if (likely(iobj->lru.next)) {
   288                  list_del_init(&iobj->lru);
   289                  iobj->lru.next = NULL;
   290          }
   291  
   292          /*
   293           * boot is only called on BAR2, if we can't remap the complete
   294           * BAR it's unlikely things are functioning well.
   295           */
   296          if (check_io_mapping(iobj->imem))
   297                  nv50_instobj_kmap(iobj, vmm);
   298          nvkm_instmem_boot(imem);
   299          mutex_unlock(&imem->mutex);
   300  }
   301  
   302  static u64
   303  nv50_instobj_size(struct nvkm_memory *memory)
   304  {
   305          return nvkm_memory_size(nv50_instobj(memory)->ram);
   306  }
   307  
   308  static u64
   309  nv50_instobj_addr(struct nvkm_memory *memory)
   310  {
   311          return nvkm_memory_addr(nv50_instobj(memory)->ram);
   312  }
   313  
   314  static u64
   315  nv50_instobj_bar2(struct nvkm_memory *memory)
   316  {
   317          struct nv50_instobj *iobj = nv50_instobj(memory);
   318          u64 addr = ~0ULL;
   319          if (nv50_instobj_acquire(&iobj->base.memory)) {
   320                  iobj->lru.next = NULL; /* Exclude from eviction. */
   321                  addr = iobj->bar->addr;
   322          }
   323          nv50_instobj_release(&iobj->base.memory);
   324          return addr;
   325  }
   326  
   327  static enum nvkm_memory_target
   328  nv50_instobj_target(struct nvkm_memory *memory)
   329  {
   330          return nvkm_memory_target(nv50_instobj(memory)->ram);
   331  }
   332  
   333  static void *
   334  nv50_instobj_dtor(struct nvkm_memory *memory)
   335  {
   336          struct nv50_instobj *iobj = nv50_instobj(memory);
   337          struct nvkm_instmem *imem = &iobj->imem->base;
   338          struct nvkm_vma *bar;
   339          void *map;
   340  
   341          mutex_lock(&imem->mutex);
   342          if (likely(iobj->lru.next))
   343                  list_del(&iobj->lru);
   344          map = iobj->map;
   345          bar = iobj->bar;
   346          mutex_unlock(&imem->mutex);
   347  
   348          if (map) {
   349                  struct nvkm_vmm *vmm = 
nvkm_bar_bar2_vmm(imem->subdev.device);
 > 350                  io_mapping_unmap(map);
   351                  if (likely(vmm)) /* Can be NULL during BAR destructor. 
*/
   352                          nvkm_vmm_put(vmm, &bar);
   353          }
   354  
   355          nvkm_memory_unref(&iobj->ram);
   356          nvkm_instobj_dtor(imem, &iobj->base);
   357          return iobj;
   358  }
   359  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

Reply via email to