Message ID | 20210602165313.553291-6-robdclark@gmail.com |
---|---|
State | New |
Headers | show |
Series | iommu/arm-smmu: adreno-smmu page fault handling | expand |
Hi Rob, I love your patch! Yet something to improve: [auto build test ERROR on iommu/next] [also build test ERROR on drm-intel/for-linux-next drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master v5.13-rc4 next-20210603] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Rob-Clark/iommu-arm-smmu-adreno-smmu-page-fault-handling/20210603-005246 base: https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next config: arm64-randconfig-r001-20210603 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project d8e0ae9a76a62bdc6117630d59bf9967ac9bb4ea) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/cdbd07b471b955a50c15ea2a86f73c39bea6dfa5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Rob-Clark/iommu-arm-smmu-adreno-smmu-page-fault-handling/20210603-005246 git checkout cdbd07b471b955a50c15ea2a86f73c39bea6dfa5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> drivers/gpu/drm/msm/msm_gpu.c:510:53: error: too many arguments to function call, expected 4, have 5 msm_gpu_crashstate_capture(gpu, submit, comm, cmd, false); ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~ drivers/gpu/drm/msm/msm_gpu.c:432:13: note: 'msm_gpu_crashstate_capture' declared here static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, ^ 1 error generated. vim +510 drivers/gpu/drm/msm/msm_gpu.c 460 461 static void recover_worker(struct kthread_work *work) 462 { 463 struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work); 464 struct drm_device *dev = gpu->dev; 465 struct msm_drm_private *priv = dev->dev_private; 466 struct msm_gem_submit *submit; 467 struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu); 468 char *comm = NULL, *cmd = NULL; 469 int i; 470 471 mutex_lock(&dev->struct_mutex); 472 473 DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name); 474 475 submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); 476 if (submit) { 477 struct task_struct *task; 478 479 /* Increment the fault counts */ 480 gpu->global_faults++; 481 submit->queue->faults++; 482 483 task = get_pid_task(submit->pid, PIDTYPE_PID); 484 if (task) { 485 comm = kstrdup(task->comm, GFP_KERNEL); 486 cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); 487 put_task_struct(task); 488 } 489 490 /* msm_rd_dump_submit() needs bo locked to dump: */ 491 for (i = 0; i < submit->nr_bos; i++) 492 msm_gem_lock(&submit->bos[i].obj->base); 493 494 if (comm && cmd) { 495 DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", 496 gpu->name, comm, cmd); 497 498 msm_rd_dump_submit(priv->hangrd, submit, 499 "offending task: %s (%s)", comm, cmd); 500 } else { 501 msm_rd_dump_submit(priv->hangrd, submit, NULL); 502 } 503 504 for (i = 0; i < submit->nr_bos; i++) 505 msm_gem_unlock(&submit->bos[i].obj->base); 506 } 507 508 /* Record the crash state */ 509 pm_runtime_get_sync(&gpu->pdev->dev); > 510 msm_gpu_crashstate_capture(gpu, submit, comm, cmd, false); 511 pm_runtime_put_sync(&gpu->pdev->dev); 512 513 kfree(cmd); 514 kfree(comm); 515 516 /* 517 * Update all the rings with the latest and greatest fence.. this 518 * needs to happen after msm_rd_dump_submit() to ensure that the 519 * bo's referenced by the offending submit are still around. 520 */ 521 for (i = 0; i < gpu->nr_rings; i++) { 522 struct msm_ringbuffer *ring = gpu->rb[i]; 523 524 uint32_t fence = ring->memptrs->fence; 525 526 /* 527 * For the current (faulting?) ring/submit advance the fence by 528 * one more to clear the faulting submit 529 */ 530 if (ring == cur_ring) 531 fence++; 532 533 update_fences(gpu, ring, fence); 534 } 535 536 if (msm_gpu_active(gpu)) { 537 /* retire completed submits, plus the one that hung: */ 538 retire_submits(gpu); 539 540 pm_runtime_get_sync(&gpu->pdev->dev); 541 gpu->funcs->recover(gpu); 542 pm_runtime_put_sync(&gpu->pdev->dev); 543 544 /* 545 * Replay all remaining submits starting with highest priority 546 * ring 547 */ 548 for (i = 0; i < gpu->nr_rings; i++) { 549 struct msm_ringbuffer *ring = gpu->rb[i]; 550 551 spin_lock(&ring->submit_lock); 552 list_for_each_entry(submit, &ring->submits, node) 553 gpu->funcs->submit(gpu, submit); 554 spin_unlock(&ring->submit_lock); 555 } 556 } 557 558 mutex_unlock(&dev->struct_mutex); 559 560 msm_gpu_retire(gpu); 561 } 562 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index bdc989183c64..d2c31fae64fd 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -434,7 +434,7 @@ static void a2xx_dump(struct msm_gpu *gpu) adreno_dump(gpu); } -static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu) +static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu, bool stalled) { struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 4534633fe7cd..b1a6f87d74ef 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -464,7 +464,7 @@ static void a3xx_dump(struct msm_gpu *gpu) adreno_dump(gpu); } -static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu) +static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu, bool stalled) { struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 82bebb40234d..22780a594d6f 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -549,7 +549,7 @@ static const unsigned int a405_registers[] = { ~0 /* sentinel */ }; -static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu) +static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu, bool stalled) { struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index a0eef5d9b89b..2e7714b1a17f 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1519,7 +1519,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu, msm_gem_kernel_put(dumper.bo, gpu->aspace, true); } -static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) +static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu, bool stalled) { struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state), GFP_KERNEL); @@ -1536,7 +1536,8 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS); /* Get the HLSQ regs with the help of the crashdumper */ - a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); + if (!stalled) + a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); a5xx_set_hwcg(gpu, true); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index ce0610c5256f..e0f06ce4e1a9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -86,7 +86,7 @@ unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu); void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, struct drm_printer *p); -struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu); +struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu, bool stalled); int a6xx_gpu_state_put(struct msm_gpu_state *state); #endif /* __A6XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index c1699b4f9a89..d0af68a76c4f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -833,6 +833,21 @@ static void a6xx_get_registers(struct msm_gpu *gpu, a6xx_state, &a6xx_vbif_reglist, &a6xx_state->registers[index++]); + if (!dumper) { + /* + * We can't use the crashdumper when the SMMU is stalled, + * because the GPU has no memory access until we resume + * translation (but we don't want to do that until after + * we have captured as much useful GPU state as possible). + * So instead collect registers via the CPU: + */ + for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) + a6xx_get_ahb_gpu_registers(gpu, + a6xx_state, &a6xx_reglist[i], + &a6xx_state->registers[index++]); + return; + } + for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) a6xx_get_crashdumper_registers(gpu, a6xx_state, &a6xx_reglist[i], @@ -903,9 +918,9 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu, a6xx_state->nr_indexed_regs = count; } -struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) +struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu, bool stalled) { - struct a6xx_crashdumper dumper = { 0 }; + struct a6xx_crashdumper _dumper = { 0 }, *dumper = NULL; struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state), @@ -928,14 +943,24 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) /* Get the banks of indexed registers */ a6xx_get_indexed_registers(gpu, a6xx_state); - /* Try to initialize the crashdumper */ - if (!a6xx_crashdumper_init(gpu, &dumper)) { - a6xx_get_registers(gpu, a6xx_state, &dumper); - a6xx_get_shaders(gpu, a6xx_state, &dumper); - a6xx_get_clusters(gpu, a6xx_state, &dumper); - a6xx_get_dbgahb_clusters(gpu, a6xx_state, &dumper); + /* + * Try to initialize the crashdumper, if we are not dumping state + * with the SMMU stalled. The crashdumper needs memory access to + * write out GPU state, so we need to skip this when the SMMU is + * stalled in response to an iova fault + */ + if (!stalled && !a6xx_crashdumper_init(gpu, &_dumper)) { + dumper = &_dumper; + } + + a6xx_get_registers(gpu, a6xx_state, dumper); + + if (dumper) { + a6xx_get_shaders(gpu, a6xx_state, dumper); + a6xx_get_clusters(gpu, a6xx_state, dumper); + a6xx_get_dbgahb_clusters(gpu, a6xx_state, dumper); - msm_gem_kernel_put(dumper.bo, gpu->aspace, true); + msm_gem_kernel_put(dumper->bo, gpu->aspace, true); } if (snapshot_debugbus) diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 7a2b53d35e6b..90558e826934 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -77,7 +77,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file) goto free_priv; pm_runtime_get_sync(&gpu->pdev->dev); - show_priv->state = gpu->funcs->gpu_state_get(gpu); + show_priv->state = gpu->funcs->gpu_state_get(gpu, false); pm_runtime_put_sync(&gpu->pdev->dev); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index fa7691cb4614..4d280bf446e6 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -381,7 +381,8 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state, } static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, - struct msm_gem_submit *submit, char *comm, char *cmd) + struct msm_gem_submit *submit, char *comm, char *cmd, + bool stalled) { struct msm_gpu_state *state; @@ -393,7 +394,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, if (gpu->crashstate) return; - state = gpu->funcs->gpu_state_get(gpu); + state = gpu->funcs->gpu_state_get(gpu, stalled); if (IS_ERR_OR_NULL(state)) return; @@ -519,7 +520,7 @@ static void recover_worker(struct kthread_work *work) /* Record the crash state */ pm_runtime_get_sync(&gpu->pdev->dev); - msm_gpu_crashstate_capture(gpu, submit, comm, cmd); + msm_gpu_crashstate_capture(gpu, submit, comm, cmd, false); pm_runtime_put_sync(&gpu->pdev->dev); kfree(cmd); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 7a082a12d98f..c15e5fd675d2 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -60,7 +60,7 @@ struct msm_gpu_funcs { void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); #endif unsigned long (*gpu_busy)(struct msm_gpu *gpu); - struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu); + struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu, bool stalled); int (*gpu_state_put)(struct msm_gpu_state *state); unsigned long (*gpu_get_freq)(struct msm_gpu *gpu); void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp);