From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E065A4DA534; Wed, 13 May 2026 16:59:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691549; cv=none; b=Rx3uORZ1RmSrbP3+FPt4dZMf2fdc41SMPu7Yp9HIcZOwxVMIQ9466JzWxe+1jAiF+8rFMOMmzA4Hn+EDQz2oYUShYIpd2p/Hr0XnOm1cFcprzrU7nZv86DfHt0MtQTVzP7kI+CxE0hjdvQmSKA1OouI8/wvCOAKZUmFsbjoyKC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691549; c=relaxed/simple; bh=mj6cGNEngX35OEMfxpLboiGY0oC4djWIef0TyNiINr8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k+KYBwbbIxLBAt/uabbTvy+uaGxVEBSlXvFmW92HZaGzunEj/4lsLiBFXb7pbmICIXbxY8J7GoSrgpMOQ7htyhIaGYOVLWtITwivt0uT/rxWnQ85n2JsqT5aoxU2DLnagw+kZBzmAhp/YHtDq2sCVxWCOUWyeVMy0Cv26Zl54sI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=ksxnEmGK; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="ksxnEmGK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691540; bh=mj6cGNEngX35OEMfxpLboiGY0oC4djWIef0TyNiINr8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ksxnEmGKqX4NCHJF1voUybm0Vc14sNDqDPPhlSpVrQ3wxkBnLU27F2yO2GZzT5Cs1 q+N4pCl5E6PCyoaz5m8NG6nf0njInyTUZS9gIZI5BtJgi438JRFpcbURdhzV3v61Ly JPVhikMQv50NRieuLk9vHrSRU4tXtGsvGw42b62eIoHsTYUvpLD4PcUfd8Nxt+SN1B lIDPrvd4IHqVUbhJJ72N7kTlbTTuzYHzibLl0CFDxU2ohmjewYmV8dGnGOXM/T3q9y mI9rv2lBlLhMtZ7G5HLO8Qb67YHOuvQvVbAojYcttJ4R7Uz2PtP9sYQYM+BmtjBCxf QdgW9i11MpHUQ== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id 21BE317E1537; Wed, 13 May 2026 18:59:00 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:49 +0200 Subject: [PATCH 1/6] drm/panthor: Driver-wide xxx_[un]lock -> [scoped_]guard replacement Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-1-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=68146; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=mj6cGNEngX35OEMfxpLboiGY0oC4djWIef0TyNiINr8=; b=nyQ8LEsFprPcl+eX+49u9HLqvTk2tArpNxIE/R33wAJI2ruo967xpUQ5T8O12NZy4KC3QkkOO kbiDMo740LXC6wZj5D3rTPmgWJPSzeHwLmfXOIYDfbji0YqY21lbMf2 X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Right now panthor is mixed bag of manual locks and guards. Let's make that more consitent and thus encourage new submissions to go for guards. Some places require a bit of code motion to avoid an excessive amount of indentation levels, but no functional change is intended. Some of this could also be simplified if we had guards for drm_dev_{enter,exit}/dma_resv_lock(), and/or if we could use the runtime pm guards (we need a custom guard to accommodate our panthor_device_resume_and_get() wrapper). This transition covers all spinlocks, mutexes and rwsemaphores declared in panthor. Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_devfreq.c | 29 +- drivers/gpu/drm/panthor/panthor_device.c | 86 +++--- drivers/gpu/drm/panthor/panthor_gem.c | 27 +- drivers/gpu/drm/panthor/panthor_gpu.c | 40 +-- drivers/gpu/drm/panthor/panthor_heap.c | 139 ++++----- drivers/gpu/drm/panthor/panthor_mmu.c | 467 ++++++++++++++------------= ---- drivers/gpu/drm/panthor/panthor_pwr.c | 8 +- drivers/gpu/drm/panthor/panthor_sched.c | 247 ++++++++-------- 8 files changed, 484 insertions(+), 559 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_devfreq.c b/drivers/gpu/drm/pa= nthor/panthor_devfreq.c index 2249b41ca4af..2322e35493bc 100644 --- a/drivers/gpu/drm/panthor/panthor_devfreq.c +++ b/drivers/gpu/drm/panthor/panthor_devfreq.c @@ -88,22 +88,19 @@ static int panthor_devfreq_get_dev_status(struct device= *dev, { struct panthor_device *ptdev =3D dev_get_drvdata(dev); struct panthor_devfreq *pdevfreq =3D ptdev->devfreq; - unsigned long irqflags; =20 status->current_frequency =3D clk_get_rate(ptdev->clks.core); =20 - spin_lock_irqsave(&pdevfreq->lock, irqflags); + scoped_guard(spinlock_irqsave, &pdevfreq->lock) { + panthor_devfreq_update_utilization(pdevfreq); =20 - panthor_devfreq_update_utilization(pdevfreq); + status->total_time =3D ktime_to_ns(ktime_add(pdevfreq->busy_time, + pdevfreq->idle_time)); =20 - status->total_time =3D ktime_to_ns(ktime_add(pdevfreq->busy_time, - pdevfreq->idle_time)); + status->busy_time =3D ktime_to_ns(pdevfreq->busy_time); =20 - status->busy_time =3D ktime_to_ns(pdevfreq->busy_time); - - panthor_devfreq_reset(pdevfreq); - - spin_unlock_irqrestore(&pdevfreq->lock, irqflags); + panthor_devfreq_reset(pdevfreq); + } =20 drm_dbg(&ptdev->base, "busy %lu total %lu %lu %% freq %lu MHz\n", status->busy_time, status->total_time, @@ -288,33 +285,25 @@ void panthor_devfreq_suspend(struct panthor_device *p= tdev) void panthor_devfreq_record_busy(struct panthor_device *ptdev) { struct panthor_devfreq *pdevfreq =3D ptdev->devfreq; - unsigned long irqflags; =20 if (!pdevfreq->devfreq) return; =20 - spin_lock_irqsave(&pdevfreq->lock, irqflags); - + guard(spinlock_irqsave)(&pdevfreq->lock); panthor_devfreq_update_utilization(pdevfreq); pdevfreq->last_busy_state =3D true; - - spin_unlock_irqrestore(&pdevfreq->lock, irqflags); } =20 void panthor_devfreq_record_idle(struct panthor_device *ptdev) { struct panthor_devfreq *pdevfreq =3D ptdev->devfreq; - unsigned long irqflags; =20 if (!pdevfreq->devfreq) return; =20 - spin_lock_irqsave(&pdevfreq->lock, irqflags); - + guard(spinlock_irqsave)(&pdevfreq->lock); panthor_devfreq_update_utilization(pdevfreq); pdevfreq->last_busy_state =3D false; - - spin_unlock_irqrestore(&pdevfreq->lock, irqflags); } =20 unsigned long panthor_devfreq_get_freq(struct panthor_device *ptdev) diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/pan= thor/panthor_device.c index bd417d6ae8c0..cb9cd8d0448b 100644 --- a/drivers/gpu/drm/panthor/panthor_device.c +++ b/drivers/gpu/drm/panthor/panthor_device.c @@ -63,34 +63,32 @@ static int panthor_init_power(struct device *dev) =20 void panthor_device_unplug(struct panthor_device *ptdev) { + bool was_already_unplugged; + /* This function can be called from two different path: the reset work * and the platform device remove callback. drm_dev_unplug() doesn't * deal with concurrent callers, so we have to protect drm_dev_unplug() * calls with our own lock, and bail out if the device is already * unplugged. */ - mutex_lock(&ptdev->unplug.lock); - if (drm_dev_is_unplugged(&ptdev->base)) { - /* Someone beat us, release the lock and wait for the unplug - * operation to be reported as done. - **/ - mutex_unlock(&ptdev->unplug.lock); + scoped_guard(mutex, &ptdev->unplug.lock) { + was_already_unplugged =3D drm_dev_is_unplugged(&ptdev->base); + if (!was_already_unplugged) { + drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); + + /* Call drm_dev_unplug() so any access to HW blocks happening after + * that point get rejected. + */ + drm_dev_unplug(&ptdev->base); + } + } + + if (was_already_unplugged) { + /* Someone beat us, wait for the unplug operation to be reported as done= . */ wait_for_completion(&ptdev->unplug.done); return; } =20 - drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); - - /* Call drm_dev_unplug() so any access to HW blocks happening after - * that point get rejected. - */ - drm_dev_unplug(&ptdev->base); - - /* We do the rest of the unplug with the unplug lock released, - * future callers will wait on ptdev->unplug.done anyway. - */ - mutex_unlock(&ptdev->unplug.lock); - /* Now, try to cleanly shutdown the GPU before the device resources * get reclaimed. */ @@ -403,30 +401,29 @@ static vm_fault_t panthor_mmio_vm_fault(struct vm_fau= lt *vmf) if (!drm_dev_enter(&ptdev->base, &cookie)) return VM_FAULT_SIGBUS; =20 - mutex_lock(&ptdev->pm.mmio_lock); - active =3D atomic_read(&ptdev->pm.state) =3D=3D PANTHOR_DEVICE_PM_STATE_A= CTIVE; + scoped_guard(mutex, &ptdev->pm.mmio_lock) { + active =3D atomic_read(&ptdev->pm.state) =3D=3D PANTHOR_DEVICE_PM_STATE_= ACTIVE; =20 - switch (offset) { - case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: - if (active) - pfn =3D __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID); - else - pfn =3D page_to_pfn(ptdev->pm.dummy_latest_flush); - break; + switch (offset) { + case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: + if (active) + pfn =3D __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID); + else + pfn =3D page_to_pfn(ptdev->pm.dummy_latest_flush); =20 - default: - ret =3D VM_FAULT_SIGBUS; - goto out_unlock; + pgprot =3D vma->vm_page_prot; + if (active) + pgprot =3D pgprot_noncached(pgprot); + + ret =3D vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot); + break; + + default: + ret =3D VM_FAULT_SIGBUS; + break; + } } =20 - pgprot =3D vma->vm_page_prot; - if (active) - pgprot =3D pgprot_noncached(pgprot); - - ret =3D vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot); - -out_unlock: - mutex_unlock(&ptdev->pm.mmio_lock); drm_dev_exit(cookie); return ret; } @@ -537,11 +534,10 @@ int panthor_device_resume(struct device *dev) * are removed and the real iomem mapping will be restored on next * access. */ - mutex_lock(&ptdev->pm.mmio_lock); + guard(mutex)(&ptdev->pm.mmio_lock); unmap_mapping_range(ptdev->base.anon_inode->i_mapping, DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_ACTIVE); - mutex_unlock(&ptdev->pm.mmio_lock); return 0; =20 err_suspend_devfreq: @@ -575,11 +571,11 @@ int panthor_device_suspend(struct device *dev) * mmio_lock held to make sure the vm_fault handler won't set up * invalid mappings. */ - mutex_lock(&ptdev->pm.mmio_lock); - atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDING); - unmap_mapping_range(ptdev->base.anon_inode->i_mapping, - DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); - mutex_unlock(&ptdev->pm.mmio_lock); + scoped_guard(mutex, &ptdev->pm.mmio_lock) { + atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDING); + unmap_mapping_range(ptdev->base.anon_inode->i_mapping, + DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); + } =20 if (panthor_device_is_initialized(ptdev) && drm_dev_enter(&ptdev->base, &cookie)) { diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/pantho= r/panthor_gem.c index 13295d7a593d..a6fddc380e7d 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -56,9 +56,8 @@ static void panthor_gem_debugfs_bo_add(struct panthor_gem= _object *bo) bo->debugfs.creator.tgid =3D current->tgid; get_task_comm(bo->debugfs.creator.process_name, current->group_leader); =20 - mutex_lock(&ptdev->gems.lock); + guard(mutex)(&ptdev->gems.lock); list_add_tail(&bo->debugfs.node, &ptdev->gems.node); - mutex_unlock(&ptdev->gems.lock); } =20 static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) @@ -69,9 +68,8 @@ static void panthor_gem_debugfs_bo_rm(struct panthor_gem_= object *bo) if (list_empty(&bo->debugfs.node)) return; =20 - mutex_lock(&ptdev->gems.lock); + guard(mutex)(&ptdev->gems.lock); list_del_init(&bo->debugfs.node); - mutex_unlock(&ptdev->gems.lock); } =20 static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object = *bo, u32 usage_flags) @@ -269,9 +267,8 @@ static int panthor_gem_backing_pin_locked(struct pantho= r_gem_object *bo) ret =3D panthor_gem_backing_get_pages_locked(bo); if (!ret) { refcount_set(&bo->backing.pin_count, 1); - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); } =20 return ret; @@ -286,9 +283,8 @@ static void panthor_gem_backing_unpin_locked(struct pan= thor_gem_object *bo) /* We don't release anything when pin_count drops to zero. * Pages stay there until an explicit cleanup is requested. */ - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); } } =20 @@ -766,9 +762,8 @@ static int panthor_gem_mmap(struct drm_gem_object *obj,= struct vm_area_struct *v dma_resv_lock(obj->resv, NULL); if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { refcount_set(&bo->cmap.mmap_count, 1); - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); } dma_resv_unlock(obj->resv); } @@ -853,9 +848,8 @@ static vm_fault_t blocking_page_setup(struct vm_fault *= vmf, unsigned int order, } else { struct page *page =3D bo->backing.pages[page_offset]; =20 - mutex_lock(&bo->base.gpuva.lock); - panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); + scoped_guard(mutex, &bo->base.gpuva.lock) + panthor_gem_update_reclaim_state_locked(bo, NULL); =20 if (mmap_lock_held) ret =3D insert_page(vmf, order, page); @@ -940,9 +934,8 @@ static void panthor_gem_vm_close(struct vm_area_struct = *vma) =20 dma_resv_lock(bo->base.resv, NULL); if (refcount_dec_and_test(&bo->cmap.mmap_count)) { - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); } dma_resv_unlock(bo->base.resv); =20 @@ -1419,7 +1412,8 @@ static bool panthor_gem_try_evict_no_resv_wait(struct= drm_gem_object *obj, * If we fail to lock that's fine, we back off and will get * back to it later. */ - if (!mutex_trylock(&bo->base.gpuva.lock)) + ACQUIRE(mutex_try, gpuva_guard)(&bo->base.gpuva.lock); + if (ACQUIRE_ERR(mutex_try, &gpuva_guard)) return false; =20 drm_gem_for_each_gpuvm_bo(vm_bo, obj) { @@ -1468,7 +1462,6 @@ static bool panthor_gem_try_evict_no_resv_wait(struct= drm_gem_object *obj, break; } } - mutex_unlock(&bo->base.gpuva.lock); =20 return ret =3D=3D 0; } diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/pantho= r/panthor_gpu.c index 04c8f23baf3f..3113024c6f48 100644 --- a/drivers/gpu/drm/panthor/panthor_gpu.c +++ b/drivers/gpu/drm/panthor/panthor_gpu.c @@ -130,17 +130,14 @@ static irqreturn_t panthor_gpu_irq_raw_handler(int ir= q, void *data) */ void panthor_gpu_unplug(struct panthor_device *ptdev) { - unsigned long flags; - /* Make sure the IRQ handler is not running after that point. */ if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) panthor_irq_suspend(&ptdev->gpu->irq); =20 /* Wake-up all waiters. */ - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); + guard(spinlock_irqsave)(&ptdev->gpu->reqs_lock); ptdev->gpu->pending_reqs =3D 0; wake_up_all(&ptdev->gpu->reqs_acked); - spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); } =20 /** @@ -336,34 +333,29 @@ int panthor_gpu_flush_caches(struct panthor_device *p= tdev, u32 l2, u32 lsc, u32 other) { struct panthor_gpu *gpu =3D ptdev->gpu; - unsigned long flags; int ret =3D 0; =20 /* Serialize cache flush operations. */ guard(mutex)(&ptdev->gpu->cache_flush_lock); =20 - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); - if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) { + scoped_guard(spinlock_irqsave, &ptdev->gpu->reqs_lock) { + /* Fail if a cache maintenance operation is already in progress. */ + if (ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) + return -EIO; + ptdev->gpu->pending_reqs |=3D GPU_IRQ_CLEAN_CACHES_COMPLETED; gpu_write(gpu->iomem, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other)); - } else { - ret =3D -EIO; } - spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); - - if (ret) - return ret; =20 if (!wait_event_timeout(ptdev->gpu->reqs_acked, !(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED), msecs_to_jiffies(100))) { - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); + guard(spinlock_irqsave)(&ptdev->gpu->reqs_lock); if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) !=3D 0 && !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPL= ETED)) ret =3D -ETIMEDOUT; else ptdev->gpu->pending_reqs &=3D ~GPU_IRQ_CLEAN_CACHES_COMPLETED; - spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); } =20 if (ret) { @@ -384,27 +376,25 @@ int panthor_gpu_soft_reset(struct panthor_device *ptd= ev) { struct panthor_gpu *gpu =3D ptdev->gpu; bool timedout =3D false; - unsigned long flags; =20 - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); - if (!drm_WARN_ON(&ptdev->base, - ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED)) { - ptdev->gpu->pending_reqs |=3D GPU_IRQ_RESET_COMPLETED; - gpu_write(gpu->irq.iomem, INT_CLEAR, GPU_IRQ_RESET_COMPLETED); - gpu_write(gpu->iomem, GPU_CMD, GPU_SOFT_RESET); + scoped_guard(spinlock_irqsave, &ptdev->gpu->reqs_lock) { + if (!drm_WARN_ON(&ptdev->base, + ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED)) { + ptdev->gpu->pending_reqs |=3D GPU_IRQ_RESET_COMPLETED; + gpu_write(gpu->irq.iomem, INT_CLEAR, GPU_IRQ_RESET_COMPLETED); + gpu_write(gpu->iomem, GPU_CMD, GPU_SOFT_RESET); + } } - spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); =20 if (!wait_event_timeout(ptdev->gpu->reqs_acked, !(ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED), msecs_to_jiffies(100))) { - spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); + guard(spinlock_irqsave)(&ptdev->gpu->reqs_lock); if ((ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED) !=3D 0 && !(gpu_read(gpu->irq.iomem, INT_RAWSTAT) & GPU_IRQ_RESET_COMPLETED)) timedout =3D true; else ptdev->gpu->pending_reqs &=3D ~GPU_IRQ_RESET_COMPLETED; - spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags); } =20 if (timedout) { diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panth= or/panthor_heap.c index 99311abdf1e9..13c6433e75aa 100644 --- a/drivers/gpu/drm/panthor/panthor_heap.c +++ b/drivers/gpu/drm/panthor/panthor_heap.c @@ -126,10 +126,10 @@ static void panthor_free_heap_chunk(struct panthor_he= ap_pool *pool, struct panthor_heap *heap, struct panthor_heap_chunk *chunk) { - mutex_lock(&heap->lock); - list_del(&chunk->node); - heap->chunk_count--; - mutex_unlock(&heap->lock); + scoped_guard(mutex, &heap->lock) { + list_del(&chunk->node); + heap->chunk_count--; + } =20 atomic_sub(heap->chunk_size, &pool->size); =20 @@ -181,10 +181,10 @@ static int panthor_alloc_heap_chunk(struct panthor_he= ap_pool *pool, =20 panthor_kernel_bo_vunmap(chunk->bo); =20 - mutex_lock(&heap->lock); - list_add(&chunk->node, &heap->chunks); - heap->chunk_count++; - mutex_unlock(&heap->lock); + scoped_guard(mutex, &heap->lock) { + list_add(&chunk->node, &heap->chunks); + heap->chunk_count++; + } =20 atomic_add(heap->chunk_size, &pool->size); =20 @@ -246,13 +246,9 @@ panthor_heap_destroy_locked(struct panthor_heap_pool *= pool, u32 handle) */ int panthor_heap_destroy(struct panthor_heap_pool *pool, u32 handle) { - int ret; + guard(rwsem_write)(&pool->lock); =20 - down_write(&pool->lock); - ret =3D panthor_heap_destroy_locked(pool, handle); - up_write(&pool->lock); - - return ret; + return panthor_heap_destroy_locked(pool, handle); } =20 /** @@ -295,9 +291,8 @@ int panthor_heap_create(struct panthor_heap_pool *pool, chunk_size < SZ_128K || chunk_size > SZ_8M) return -EINVAL; =20 - down_read(&pool->lock); - vm =3D panthor_vm_get(pool->vm); - up_read(&pool->lock); + scoped_guard(rwsem_read, &pool->lock) + vm =3D panthor_vm_get(pool->vm); =20 /* The pool has been destroyed, we can't create a new heap. */ if (!vm) @@ -324,22 +319,22 @@ int panthor_heap_create(struct panthor_heap_pool *poo= l, node); *first_chunk_gpu_va =3D panthor_kernel_bo_gpuva(first_chunk->bo); =20 - down_write(&pool->lock); - /* The pool has been destroyed, we can't create a new heap. */ - if (!pool->vm) { - ret =3D -EINVAL; - } else { - ret =3D xa_alloc(&pool->xa, &id, heap, - XA_LIMIT(0, MAX_HEAPS_PER_POOL - 1), GFP_KERNEL); - if (!ret) { - void *gpu_ctx =3D panthor_get_heap_ctx(pool, id); + scoped_guard(rwsem_write, &pool->lock) { + /* The pool has been destroyed, we can't create a new heap. */ + if (!pool->vm) { + ret =3D -EINVAL; + } else { + ret =3D xa_alloc(&pool->xa, &id, heap, + XA_LIMIT(0, MAX_HEAPS_PER_POOL - 1), GFP_KERNEL); + if (!ret) { + void *gpu_ctx =3D panthor_get_heap_ctx(pool, id); =20 - memset(gpu_ctx, 0, panthor_heap_ctx_stride(pool->ptdev)); - *heap_ctx_gpu_va =3D panthor_kernel_bo_gpuva(pool->gpu_contexts) + - panthor_get_heap_ctx_offset(pool, id); + memset(gpu_ctx, 0, panthor_heap_ctx_stride(pool->ptdev)); + *heap_ctx_gpu_va =3D panthor_kernel_bo_gpuva(pool->gpu_contexts) + + panthor_get_heap_ctx_offset(pool, id); + } } } - up_write(&pool->lock); =20 if (ret) goto err_free_heap; @@ -375,43 +370,35 @@ int panthor_heap_return_chunk(struct panthor_heap_poo= l *pool, u32 heap_id =3D (u32)offset / panthor_heap_ctx_stride(pool->ptdev); struct panthor_heap_chunk *chunk, *tmp, *removed =3D NULL; struct panthor_heap *heap; - int ret; =20 if (offset > U32_MAX || heap_id >=3D MAX_HEAPS_PER_POOL) return -EINVAL; =20 - down_read(&pool->lock); + guard(rwsem_read)(&pool->lock); heap =3D xa_load(&pool->xa, heap_id); - if (!heap) { - ret =3D -EINVAL; - goto out_unlock; - } + if (!heap) + return -EINVAL; =20 chunk_gpu_va &=3D GENMASK_ULL(63, 12); =20 - mutex_lock(&heap->lock); - list_for_each_entry_safe(chunk, tmp, &heap->chunks, node) { - if (panthor_kernel_bo_gpuva(chunk->bo) =3D=3D chunk_gpu_va) { - removed =3D chunk; - list_del(&chunk->node); - heap->chunk_count--; - atomic_sub(heap->chunk_size, &pool->size); - break; + scoped_guard(mutex, &heap->lock) { + list_for_each_entry_safe(chunk, tmp, &heap->chunks, node) { + if (panthor_kernel_bo_gpuva(chunk->bo) =3D=3D chunk_gpu_va) { + removed =3D chunk; + list_del(&chunk->node); + heap->chunk_count--; + atomic_sub(heap->chunk_size, &pool->size); + break; + } } } - mutex_unlock(&heap->lock); =20 - if (removed) { - panthor_kernel_bo_destroy(chunk->bo); - kfree(chunk); - ret =3D 0; - } else { - ret =3D -EINVAL; - } + if (!removed) + return -EINVAL; =20 -out_unlock: - up_read(&pool->lock); - return ret; + panthor_kernel_bo_destroy(chunk->bo); + kfree(chunk); + return 0; } =20 /** @@ -444,12 +431,10 @@ int panthor_heap_grow(struct panthor_heap_pool *pool, if (offset > U32_MAX || heap_id >=3D MAX_HEAPS_PER_POOL) return -EINVAL; =20 - down_read(&pool->lock); + guard(rwsem_read)(&pool->lock); heap =3D xa_load(&pool->xa, heap_id); - if (!heap) { - ret =3D -EINVAL; - goto out_unlock; - } + if (!heap) + return -EINVAL; =20 /* If we reached the target in-flight render passes, or if we * reached the maximum number of chunks, let the FW figure another way to @@ -457,10 +442,8 @@ int panthor_heap_grow(struct panthor_heap_pool *pool, * handler provided by the userspace driver, if any). */ if (renderpasses_in_flight > heap->target_in_flight || - heap->chunk_count >=3D heap->max_chunks) { - ret =3D -ENOMEM; - goto out_unlock; - } + heap->chunk_count >=3D heap->max_chunks) + return -ENOMEM; =20 /* FIXME: panthor_alloc_heap_chunk() triggers a kernel BO creation, * which goes through the blocking allocation path. Ultimately, we @@ -475,18 +458,14 @@ int panthor_heap_grow(struct panthor_heap_pool *pool, */ ret =3D panthor_alloc_heap_chunk(pool, heap, false); if (ret) - goto out_unlock; + return ret; =20 chunk =3D list_first_entry(&heap->chunks, struct panthor_heap_chunk, node); *new_chunk_gpu_va =3D (panthor_kernel_bo_gpuva(chunk->bo) & GENMASK_ULL(6= 3, 12)) | (heap->chunk_size >> 12); - ret =3D 0; - -out_unlock: - up_read(&pool->lock); - return ret; + return 0; } =20 static void panthor_heap_pool_release(struct kref *refcount) @@ -600,19 +579,19 @@ void panthor_heap_pool_destroy(struct panthor_heap_po= ol *pool) if (!pool) return; =20 - down_write(&pool->lock); - xa_for_each(&pool->xa, i, heap) - drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i)); + scoped_guard(rwsem_write, &pool->lock) { + xa_for_each(&pool->xa, i, heap) + drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i)); =20 - if (!IS_ERR_OR_NULL(pool->gpu_contexts)) { - atomic_sub(pool->gpu_contexts->obj->size, &pool->size); - panthor_kernel_bo_destroy(pool->gpu_contexts); + if (!IS_ERR_OR_NULL(pool->gpu_contexts)) { + atomic_sub(pool->gpu_contexts->obj->size, &pool->size); + panthor_kernel_bo_destroy(pool->gpu_contexts); + } + + /* Reflects the fact the pool has been destroyed. */ + pool->vm =3D NULL; } =20 - /* Reflects the fact the pool has been destroyed. */ - pool->vm =3D NULL; - up_write(&pool->lock); - panthor_heap_pool_put(pool); } =20 diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index 2955b8baa2e2..157eef286cb9 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -683,47 +683,20 @@ static void panthor_vm_release_as_locked(struct panth= or_vm *vm) vm->as.id =3D -1; } =20 -/** - * panthor_vm_active() - Flag a VM as active - * @vm: VM to flag as active. - * - * Assigns an address space to a VM so it can be used by the GPU/MCU. - * - * Return: 0 on success, a negative error code otherwise. - */ -int panthor_vm_active(struct panthor_vm *vm) +static int panthor_vm_active_locked(struct panthor_vm *vm) { struct panthor_device *ptdev =3D vm->ptdev; u32 va_bits =3D GPU_MMU_FEATURES_VA_BITS(ptdev->gpu_info.mmu_features); struct io_pgtable_cfg *cfg =3D &io_pgtable_ops_to_pgtable(vm->pgtbl_ops)-= >cfg; - int ret =3D 0, as, cookie; u64 transtab, transcfg; u32 fault_mask; + int ret, as; =20 - if (!drm_dev_enter(&ptdev->base, &cookie)) - return -ENODEV; + lockdep_assert_held(&vm->op_lock); + lockdep_assert_held(&ptdev->mmu->as.slots_lock); =20 if (refcount_inc_not_zero(&vm->as.active_cnt)) - goto out_dev_exit; - - /* As soon as active is called, we place the VM at the end of the VM LRU. - * If something fails after that, the only downside is that this VM that - * never became active in the first place will be reclaimed last, but - * that's an acceptable trade-off. - */ - mutex_lock(&ptdev->reclaim.lock); - if (vm->reclaim.lru.count) - list_move_tail(&vm->reclaim.lru_node, &ptdev->reclaim.vms); - mutex_unlock(&ptdev->reclaim.lock); - - /* Make sure we don't race with lock/unlock_region() calls - * happening around VM bind operations. - */ - mutex_lock(&vm->op_lock); - mutex_lock(&ptdev->mmu->as.slots_lock); - - if (refcount_inc_not_zero(&vm->as.active_cnt)) - goto out_unlock; + return 0; =20 as =3D vm->as.id; if (as >=3D 0) { @@ -750,17 +723,15 @@ int panthor_vm_active(struct panthor_vm *vm) lru_vm =3D list_first_entry_or_null(&ptdev->mmu->as.lru_list, struct panthor_vm, as.lru_node); - if (drm_WARN_ON(&ptdev->base, !lru_vm)) { - ret =3D -EBUSY; - goto out_unlock; - } + if (drm_WARN_ON(&ptdev->base, !lru_vm)) + return -EBUSY; =20 drm_WARN_ON(&ptdev->base, refcount_read(&lru_vm->as.active_cnt)); as =3D lru_vm->as.id; =20 ret =3D panthor_mmu_as_disable(ptdev, as, true); if (ret) - goto out_unlock; + return ret; =20 panthor_vm_release_as_locked(lru_vm); } @@ -796,16 +767,52 @@ int panthor_vm_active(struct panthor_vm *vm) */ drm_WARN_ON(&vm->ptdev->base, vm->locked_region.size > 0); ret =3D panthor_mmu_as_enable(vm->ptdev, vm->as.id, transtab, transcfg, v= m->memattr); + if (ret) + return ret; =20 out_make_active: - if (!ret) { - refcount_set(&vm->as.active_cnt, 1); - list_del_init(&vm->as.lru_node); + refcount_set(&vm->as.active_cnt, 1); + list_del_init(&vm->as.lru_node); + + return 0; +} + +/** + * panthor_vm_active() - Flag a VM as active + * @vm: VM to flag as active. + * + * Assigns an address space to a VM so it can be used by the GPU/MCU. + * + * Return: 0 on success, a negative error code otherwise. + */ +int panthor_vm_active(struct panthor_vm *vm) +{ + struct panthor_device *ptdev =3D vm->ptdev; + int ret =3D 0, cookie; + + if (!drm_dev_enter(&ptdev->base, &cookie)) + return -ENODEV; + + if (refcount_inc_not_zero(&vm->as.active_cnt)) + goto out_dev_exit; + + /* As soon as active is called, we place the VM at the end of the VM LRU. + * If something fails after that, the only downside is that this VM that + * never became active in the first place will be reclaimed last, but + * that's an acceptable trade-off. + */ + scoped_guard(mutex, &ptdev->reclaim.lock) { + if (vm->reclaim.lru.count) + list_move_tail(&vm->reclaim.lru_node, &ptdev->reclaim.vms); } =20 -out_unlock: - mutex_unlock(&ptdev->mmu->as.slots_lock); - mutex_unlock(&vm->op_lock); + /* Make sure we don't race with lock/unlock_region() calls + * happening around VM bind operations. + */ + scoped_guard(mutex, &vm->op_lock) { + guard(mutex)(&ptdev->mmu->as.slots_lock); + ret =3D panthor_vm_active_locked(vm); + } =20 out_dev_exit: drm_dev_exit(cookie); @@ -829,14 +836,17 @@ void panthor_vm_idle(struct panthor_vm *vm) { struct panthor_device *ptdev =3D vm->ptdev; =20 - if (!refcount_dec_and_mutex_lock(&vm->as.active_cnt, &ptdev->mmu->as.slot= s_lock)) + if (refcount_dec_not_one(&vm->as.active_cnt)) + return; + + guard(mutex)(&ptdev->mmu->as.slots_lock); + if (!refcount_dec_and_test(&vm->as.active_cnt)) return; =20 if (!drm_WARN_ON(&ptdev->base, vm->as.id =3D=3D -1 || !list_empty(&vm->as= .lru_node))) list_add_tail(&vm->as.lru_node, &ptdev->mmu->as.lru_list); =20 refcount_set(&vm->as.active_cnt, 0); - mutex_unlock(&ptdev->mmu->as.slots_lock); } =20 u32 panthor_vm_page_size(struct panthor_vm *vm) @@ -898,12 +908,11 @@ static void panthor_vm_declare_unusable(struct pantho= r_vm *vm) return; =20 vm->unusable =3D true; - mutex_lock(&ptdev->mmu->as.slots_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); if (vm->as.id >=3D 0 && drm_dev_enter(&ptdev->base, &cookie)) { panthor_mmu_as_disable(ptdev, vm->as.id, false); drm_dev_exit(cookie); } - mutex_unlock(&ptdev->mmu->as.slots_lock); } =20 static void panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 si= ze) @@ -1070,7 +1079,6 @@ panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u6= 4 size, struct drm_mm_node *va_node) { ssize_t vm_pgsz =3D panthor_vm_page_size(vm); - int ret; =20 if (!size || !IS_ALIGNED(size, vm_pgsz)) return -EINVAL; @@ -1078,21 +1086,18 @@ panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, = u64 size, if (va !=3D PANTHOR_VM_KERNEL_AUTO_VA && !IS_ALIGNED(va, vm_pgsz)) return -EINVAL; =20 - mutex_lock(&vm->mm_lock); + guard(mutex)(&vm->mm_lock); if (va !=3D PANTHOR_VM_KERNEL_AUTO_VA) { va_node->start =3D va; va_node->size =3D size; - ret =3D drm_mm_reserve_node(&vm->mm, va_node); - } else { - ret =3D drm_mm_insert_node_in_range(&vm->mm, va_node, size, - size >=3D SZ_2M ? SZ_2M : SZ_4K, - 0, vm->kernel_auto_va.start, - vm->kernel_auto_va.end, - DRM_MM_INSERT_BEST); + return drm_mm_reserve_node(&vm->mm, va_node); } - mutex_unlock(&vm->mm_lock); =20 - return ret; + return drm_mm_insert_node_in_range(&vm->mm, va_node, size, + size >=3D SZ_2M ? SZ_2M : SZ_4K, + 0, vm->kernel_auto_va.start, + vm->kernel_auto_va.end, + DRM_MM_INSERT_BEST); } =20 /** @@ -1102,9 +1107,8 @@ panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u6= 4 size, */ void panthor_vm_free_va(struct panthor_vm *vm, struct drm_mm_node *va_node) { - mutex_lock(&vm->mm_lock); + guard(mutex)(&vm->mm_lock); drm_mm_remove_node(va_node); - mutex_unlock(&vm->mm_lock); } =20 static void panthor_vm_bo_free(struct drm_gpuvm_bo *vm_bo) @@ -1115,9 +1119,8 @@ static void panthor_vm_bo_free(struct drm_gpuvm_bo *v= m_bo) * be taken in the dma signalling path, so call it now. */ dma_resv_lock(bo->base.resv, NULL); - mutex_lock(&bo->base.gpuva.lock); - panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); + scoped_guard(mutex, &bo->base.gpuva.lock) + panthor_gem_update_reclaim_state_locked(bo, NULL); dma_resv_unlock(bo->base.resv); =20 kfree(vm_bo); @@ -1346,9 +1349,8 @@ static int panthor_vm_prepare_map_op_ctx(struct panth= or_vm_op_ctx *op_ctx, =20 /* And finally update the BO state. */ dma_resv_lock(bo->base.resv, NULL); - mutex_lock(&bo->base.gpuva.lock); - panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); + scoped_guard(mutex, &bo->base.gpuva.lock) + panthor_gem_update_reclaim_state_locked(bo, NULL); dma_resv_unlock(bo->base.resv); =20 return 0; @@ -1437,7 +1439,7 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 v= a, u64 *bo_offset) struct panthor_vma *vma; =20 /* Take the VM lock to prevent concurrent map/unmap operations. */ - mutex_lock(&vm->op_lock); + guard(mutex)(&vm->op_lock); gpuva =3D drm_gpuva_find_first(&vm->base, va, 1); vma =3D gpuva ? container_of(gpuva, struct panthor_vma, base) : NULL; if (vma && vma->base.gem.obj) { @@ -1445,7 +1447,6 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 v= a, u64 *bo_offset) bo =3D to_panthor_bo(vma->base.gem.obj); *bo_offset =3D vma->base.gem.offset + (va - vma->base.va.addr); } - mutex_unlock(&vm->op_lock); =20 return bo; } @@ -1571,10 +1572,10 @@ static void panthor_vm_destroy(struct panthor_vm *v= m) if (refcount_read(&vm->as.active_cnt) > 0) panthor_sched_prepare_for_vm_destruction(vm->ptdev); =20 - mutex_lock(&vm->heaps.lock); - panthor_heap_pool_destroy(vm->heaps.pool); - vm->heaps.pool =3D NULL; - mutex_unlock(&vm->heaps.lock); + scoped_guard(mutex, &vm->heaps.lock) { + panthor_heap_pool_destroy(vm->heaps.pool); + vm->heaps.pool =3D NULL; + } =20 drm_WARN_ON(&vm->ptdev->base, panthor_vm_unmap_range(vm, vm->base.mm_start, vm->base.mm_range)); @@ -1702,7 +1703,6 @@ static const char *access_type_name(struct panthor_de= vice *ptdev, static int panthor_vm_lock_region(struct panthor_vm *vm, u64 start, u64 si= ze) { struct panthor_device *ptdev =3D vm->ptdev; - int ret =3D 0; =20 /* sm_step_remap() can call panthor_vm_lock_region() to account for * the wider unmap needed when doing a partial huge page unamp. We @@ -1731,30 +1731,30 @@ static int panthor_vm_lock_region(struct panthor_vm= *vm, u64 start, u64 size) size =3D end - start; } =20 - mutex_lock(&ptdev->mmu->as.slots_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); if (vm->as.id >=3D 0 && size) { + int ret; + /* Lock the region that needs to be updated */ gpu_write64(ptdev->mmu->iomem, AS_LOCKADDR(vm->as.id), pack_region_range(ptdev, &start, &size)); =20 /* If the lock succeeded, update the locked_region info. */ ret =3D as_send_cmd_and_wait(ptdev, vm->as.id, AS_COMMAND_LOCK); + if (ret) + return ret; } =20 - if (!ret) { - vm->locked_region.start =3D start; - vm->locked_region.size =3D size; - } - mutex_unlock(&ptdev->mmu->as.slots_lock); - - return ret; + vm->locked_region.start =3D start; + vm->locked_region.size =3D size; + return 0; } =20 static void panthor_vm_unlock_region(struct panthor_vm *vm) { struct panthor_device *ptdev =3D vm->ptdev; =20 - mutex_lock(&ptdev->mmu->as.slots_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); if (vm->as.id >=3D 0) { int ret; =20 @@ -1778,7 +1778,6 @@ static void panthor_vm_unlock_region(struct panthor_v= m *vm) } vm->locked_region.start =3D 0; vm->locked_region.size =3D 0; - mutex_unlock(&ptdev->mmu->as.slots_lock); } =20 static void panthor_mmu_irq_handler(struct panthor_irq *pirq, u32 status) @@ -1805,7 +1804,7 @@ static void panthor_mmu_irq_handler(struct panthor_ir= q *pirq, u32 status) access_type =3D (fault_status >> 8) & 0x3; source_id =3D (fault_status >> 16); =20 - mutex_lock(&ptdev->mmu->as.slots_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); =20 ptdev->mmu->as.faulty_mask |=3D mask; =20 @@ -1836,8 +1835,6 @@ static void panthor_mmu_irq_handler(struct panthor_ir= q *pirq, u32 status) =20 /* Disable the MMU to kill jobs on this AS. */ panthor_mmu_as_disable(ptdev, as, false); - mutex_unlock(&ptdev->mmu->as.slots_lock); - status &=3D ~mask; has_unhandled_faults =3D true; } @@ -1863,17 +1860,17 @@ static irqreturn_t panthor_mmu_irq_threaded_handler= (int irq, void *data) */ void panthor_mmu_suspend(struct panthor_device *ptdev) { - mutex_lock(&ptdev->mmu->as.slots_lock); - for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { - struct panthor_vm *vm =3D ptdev->mmu->as.slots[i].vm; + scoped_guard(mutex, &ptdev->mmu->as.slots_lock) { + for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { + struct panthor_vm *vm =3D ptdev->mmu->as.slots[i].vm; =20 - if (vm) { - drm_WARN_ON(&ptdev->base, - panthor_mmu_as_disable(ptdev, i, false)); - panthor_vm_release_as_locked(vm); + if (vm) { + drm_WARN_ON(&ptdev->base, + panthor_mmu_as_disable(ptdev, i, false)); + panthor_vm_release_as_locked(vm); + } } } - mutex_unlock(&ptdev->mmu->as.slots_lock); =20 panthor_irq_suspend(&ptdev->mmu->irq); } @@ -1889,10 +1886,10 @@ void panthor_mmu_suspend(struct panthor_device *ptd= ev) */ void panthor_mmu_resume(struct panthor_device *ptdev) { - mutex_lock(&ptdev->mmu->as.slots_lock); - ptdev->mmu->as.alloc_mask =3D 0; - ptdev->mmu->as.faulty_mask =3D 0; - mutex_unlock(&ptdev->mmu->as.slots_lock); + scoped_guard(mutex, &ptdev->mmu->as.slots_lock) { + ptdev->mmu->as.alloc_mask =3D 0; + ptdev->mmu->as.faulty_mask =3D 0; + } =20 panthor_irq_resume(&ptdev->mmu->irq); } @@ -1913,11 +1910,11 @@ void panthor_mmu_pre_reset(struct panthor_device *p= tdev) =20 panthor_irq_suspend(&ptdev->mmu->irq); =20 - mutex_lock(&ptdev->mmu->vm.lock); - ptdev->mmu->vm.reset_in_progress =3D true; - list_for_each_entry(vm, &ptdev->mmu->vm.list, node) - panthor_vm_stop(vm); - mutex_unlock(&ptdev->mmu->vm.lock); + scoped_guard(mutex, &ptdev->mmu->vm.lock) { + ptdev->mmu->vm.reset_in_progress =3D true; + list_for_each_entry(vm, &ptdev->mmu->vm.list, node) + panthor_vm_stop(vm); + } } =20 /** @@ -1931,32 +1928,29 @@ void panthor_mmu_post_reset(struct panthor_device *= ptdev) { struct panthor_vm *vm; =20 - mutex_lock(&ptdev->mmu->as.slots_lock); + scoped_guard(mutex, &ptdev->mmu->as.slots_lock) { + /* Now that the reset is effective, we can assume that none of the + * AS slots are setup, and clear the faulty flags too. + */ + ptdev->mmu->as.alloc_mask =3D 0; + ptdev->mmu->as.faulty_mask =3D 0; =20 - /* Now that the reset is effective, we can assume that none of the - * AS slots are setup, and clear the faulty flags too. - */ - ptdev->mmu->as.alloc_mask =3D 0; - ptdev->mmu->as.faulty_mask =3D 0; + for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { + struct panthor_vm *vm =3D ptdev->mmu->as.slots[i].vm; =20 - for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { - struct panthor_vm *vm =3D ptdev->mmu->as.slots[i].vm; - - if (vm) - panthor_vm_release_as_locked(vm); + if (vm) + panthor_vm_release_as_locked(vm); + } } =20 - mutex_unlock(&ptdev->mmu->as.slots_lock); - panthor_irq_resume(&ptdev->mmu->irq); =20 /* Restart the VM_BIND queues. */ - mutex_lock(&ptdev->mmu->vm.lock); + guard(mutex)(&ptdev->mmu->vm.lock); list_for_each_entry(vm, &ptdev->mmu->vm.list, node) { panthor_vm_start(vm); } ptdev->mmu->vm.reset_in_progress =3D false; - mutex_unlock(&ptdev->mmu->vm.lock); } =20 static void panthor_vm_free(struct drm_gpuvm *gpuvm) @@ -1964,46 +1958,45 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) struct panthor_vm *vm =3D container_of(gpuvm, struct panthor_vm, base); struct panthor_device *ptdev =3D vm->ptdev; =20 - mutex_lock(&ptdev->reclaim.lock); - list_del_init(&vm->reclaim.lru_node); - mutex_unlock(&ptdev->reclaim.lock); + scoped_guard(mutex, &ptdev->reclaim.lock) + list_del_init(&vm->reclaim.lru_node); =20 - mutex_lock(&vm->heaps.lock); - if (drm_WARN_ON(&ptdev->base, vm->heaps.pool)) - panthor_heap_pool_destroy(vm->heaps.pool); - mutex_unlock(&vm->heaps.lock); + scoped_guard(mutex, &vm->heaps.lock) { + if (drm_WARN_ON(&ptdev->base, vm->heaps.pool)) + panthor_heap_pool_destroy(vm->heaps.pool); + } mutex_destroy(&vm->heaps.lock); =20 - mutex_lock(&ptdev->mmu->vm.lock); - list_del(&vm->node); - /* Restore the scheduler state so we can call drm_sched_entity_destroy() - * and drm_sched_fini(). If get there, that means we have no job left - * and no new jobs can be queued, so we can start the scheduler without - * risking interfering with the reset. - */ - if (ptdev->mmu->vm.reset_in_progress) - panthor_vm_start(vm); - mutex_unlock(&ptdev->mmu->vm.lock); + scoped_guard(mutex, &ptdev->mmu->vm.lock) { + list_del(&vm->node); + + /* Restore the scheduler state so we can call drm_sched_entity_destroy() + * and drm_sched_fini(). If get there, that means we have no job left + * and no new jobs can be queued, so we can start the scheduler without + * risking interfering with the reset. + */ + if (ptdev->mmu->vm.reset_in_progress) + panthor_vm_start(vm); + } =20 drm_sched_entity_destroy(&vm->entity); drm_sched_fini(&vm->sched); =20 - mutex_lock(&vm->op_lock); - mutex_lock(&ptdev->mmu->as.slots_lock); - if (vm->as.id >=3D 0) { - int cookie; + scoped_guard(mutex, &vm->op_lock) { + guard(mutex)(&ptdev->mmu->as.slots_lock); + if (vm->as.id >=3D 0) { + int cookie; =20 - if (drm_dev_enter(&ptdev->base, &cookie)) { - panthor_mmu_as_disable(ptdev, vm->as.id, false); - drm_dev_exit(cookie); + if (drm_dev_enter(&ptdev->base, &cookie)) { + panthor_mmu_as_disable(ptdev, vm->as.id, false); + drm_dev_exit(cookie); + } + + ptdev->mmu->as.slots[vm->as.id].vm =3D NULL; + clear_bit(vm->as.id, &ptdev->mmu->as.alloc_mask); + list_del(&vm->as.lru_node); } - - ptdev->mmu->as.slots[vm->as.id].vm =3D NULL; - clear_bit(vm->as.id, &ptdev->mmu->as.alloc_mask); - list_del(&vm->as.lru_node); } - mutex_unlock(&ptdev->mmu->as.slots_lock); - mutex_unlock(&vm->op_lock); =20 free_io_pgtable_ops(vm->pgtbl_ops); =20 @@ -2052,7 +2045,7 @@ struct panthor_heap_pool *panthor_vm_get_heap_pool(st= ruct panthor_vm *vm, bool c { struct panthor_heap_pool *pool; =20 - mutex_lock(&vm->heaps.lock); + guard(mutex)(&vm->heaps.lock); if (!vm->heaps.pool && create) { if (vm->destroyed) pool =3D ERR_PTR(-EINVAL); @@ -2066,7 +2059,6 @@ struct panthor_heap_pool *panthor_vm_get_heap_pool(st= ruct panthor_vm *vm, bool c if (!pool) pool =3D ERR_PTR(-ENOENT); } - mutex_unlock(&vm->heaps.lock); =20 return pool; } @@ -2146,9 +2138,8 @@ static void panthor_vma_link(struct panthor_vm *vm, { struct panthor_gem_object *bo =3D to_panthor_bo(vma->base.gem.obj); =20 - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); drm_gpuva_link(&vma->base, vm_bo); - mutex_unlock(&bo->base.gpuva.lock); } =20 static void panthor_vma_unlink(struct panthor_vma *vma) @@ -2362,11 +2353,10 @@ void panthor_vm_update_bo_reclaim_lru_locked(struct= panthor_gem_object *bo) drm_WARN_ON(&ptdev->base, vm); vm =3D container_of(vm_bo->vm, struct panthor_vm, base); =20 - mutex_lock(&ptdev->reclaim.lock); + guard(mutex)(&ptdev->reclaim.lock); drm_gem_lru_move_tail_locked(&vm->reclaim.lru, &bo->base); if (list_empty(&vm->reclaim.lru_node)) list_move(&vm->reclaim.lru_node, &ptdev->reclaim.vms); - mutex_unlock(&ptdev->reclaim.lock); } } =20 @@ -2379,7 +2369,8 @@ int panthor_vm_evict_bo_mappings_locked(struct pantho= r_gem_object *bo) struct panthor_vm *vm =3D container_of(vm_bo->vm, struct panthor_vm, bas= e); struct drm_gpuva *va; =20 - if (!mutex_trylock(&vm->op_lock)) + ACQUIRE(mutex_try, op_guard)(&vm->op_lock); + if (ACQUIRE_ERR(mutex_try, &op_guard)) return -EDEADLK; =20 /* It can be that the vm_bo was already evicted but a new @@ -2417,8 +2408,6 @@ int panthor_vm_evict_bo_mappings_locked(struct pantho= r_gem_object *bo) vma->evicted =3D true; } =20 - mutex_unlock(&vm->op_lock); - if (ret) break; } @@ -2434,7 +2423,7 @@ static struct panthor_vma *select_evicted_vma(struct = drm_gpuvm_bo *vm_bo, struct drm_gpuva *va; =20 /* Take op_lock to protect against va insertion/removal. */ - mutex_lock(&vm->op_lock); + guard(mutex)(&vm->op_lock); drm_gpuvm_bo_for_each_va(va, vm_bo) { struct panthor_vma *vma =3D container_of(va, struct panthor_vma, base); =20 @@ -2445,7 +2434,6 @@ static struct panthor_vma *select_evicted_vma(struct = drm_gpuvm_bo *vm_bo, break; } } - mutex_unlock(&vm->op_lock); =20 return first_evicted_vma; } @@ -2469,45 +2457,44 @@ static int remap_evicted_vma(struct drm_gpuvm_bo *v= m_bo, * to release it so we can allocate PTs, because this very same lock * is taken in a DMA-signalling path. */ - mutex_lock(&vm->op_lock); - drm_gpuvm_bo_for_each_va(va, vm_bo) { - struct panthor_vma *vma =3D container_of(va, struct panthor_vma, base); + scoped_guard(mutex, &vm->op_lock) { + drm_gpuvm_bo_for_each_va(va, vm_bo) { + struct panthor_vma *vma =3D container_of(va, struct panthor_vma, base); =20 - if (vma !=3D evicted_vma) - continue; + if (vma !=3D evicted_vma) + continue; =20 - /* Because we had to release the lock between the evicted_vma selection - * and its repopulation, we can't rely solely on pointer equality (the - * VMA might have been freed and a new one allocated at the same address= ). - * If the evicted bit is still set, we're sure it's our VMA, because - * population/eviction is serialized with the BO resv lock. - */ - if (vma->evicted) - found =3D true; + /* Because we had to release the lock between the evicted_vma selection + * and its repopulation, we can't rely solely on pointer equality (the + * VMA might have been freed and a new one allocated at the same addres= s). + * If the evicted bit is still set, we're sure it's our VMA, because + * population/eviction is serialized with the BO resv lock. + */ + if (vma->evicted) + found =3D true; =20 - break; - } - - if (found) { - vm->op_ctx =3D op_ctx; - ret =3D panthor_vm_lock_region(vm, evicted_vma->base.va.addr, - evicted_vma->base.va.range); - if (!ret) { - ret =3D panthor_vm_map_pages(vm, evicted_vma->base.va.addr, - flags_to_prot(evicted_vma->flags), - bo->dmap.sgt, - evicted_vma->base.gem.offset, - evicted_vma->base.va.range); - if (!ret) - evicted_vma->evicted =3D false; - - panthor_vm_unlock_region(vm); + break; } =20 - vm->op_ctx =3D NULL; - } + if (found) { + vm->op_ctx =3D op_ctx; + ret =3D panthor_vm_lock_region(vm, evicted_vma->base.va.addr, + evicted_vma->base.va.range); + if (!ret) { + ret =3D panthor_vm_map_pages(vm, evicted_vma->base.va.addr, + flags_to_prot(evicted_vma->flags), + bo->dmap.sgt, + evicted_vma->base.gem.offset, + evicted_vma->base.va.range); + if (!ret) + evicted_vma->evicted =3D false; =20 - mutex_unlock(&vm->op_lock); + panthor_vm_unlock_region(vm); + } + + vm->op_ctx =3D NULL; + } + } =20 out_cleanup: panthor_vm_cleanup_op_ctx(op_ctx, vm); @@ -2550,9 +2537,8 @@ static int panthor_vm_bo_validate(struct drm_gpuvm_bo= *vm_bo, return ret; =20 drm_gpuvm_bo_evict(vm_bo, false); - mutex_lock(&bo->base.gpuva.lock); + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - mutex_unlock(&bo->base.gpuva.lock); return 0; } =20 @@ -2594,7 +2580,7 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pant= hor_vm_op_ctx *op, if (op_type =3D=3D DRM_PANTHOR_VM_BIND_OP_TYPE_SYNC_ONLY) return 0; =20 - mutex_lock(&vm->op_lock); + guard(mutex)(&vm->op_lock); vm->op_ctx =3D op; =20 ret =3D panthor_vm_lock_region(vm, op->va.addr, op->va.range); @@ -2635,8 +2621,6 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pant= hor_vm_op_ctx *op, panthor_vm_declare_unusable(vm); =20 vm->op_ctx =3D NULL; - mutex_unlock(&vm->op_lock); - return ret; } =20 @@ -2812,13 +2796,13 @@ panthor_vm_create(struct panthor_device *ptdev, boo= l for_mcu, mair =3D io_pgtable_ops_to_pgtable(vm->pgtbl_ops)->cfg.arm_lpae_s1_cfg.ma= ir; vm->memattr =3D mair_to_memattr(mair, ptdev->coherent); =20 - mutex_lock(&ptdev->mmu->vm.lock); - list_add_tail(&vm->node, &ptdev->mmu->vm.list); + scoped_guard(mutex, &ptdev->mmu->vm.lock) { + list_add_tail(&vm->node, &ptdev->mmu->vm.list); =20 - /* If a reset is in progress, stop the scheduler. */ - if (ptdev->mmu->vm.reset_in_progress) - panthor_vm_stop(vm); - mutex_unlock(&ptdev->mmu->vm.lock); + /* If a reset is in progress, stop the scheduler. */ + if (ptdev->mmu->vm.reset_in_progress) + panthor_vm_stop(vm); + } =20 /* We intentionally leave the reserved range to zero, because we want ker= nel VMAs * to be handled the same way user VMAs are. @@ -3142,48 +3126,44 @@ panthor_mmu_reclaim_priv_bos(struct panthor_device = *ptdev, LIST_HEAD(remaining_vms); LIST_HEAD(vms); =20 - mutex_lock(&ptdev->reclaim.lock); - list_splice_init(&ptdev->reclaim.vms, &vms); + scoped_guard(mutex, &ptdev->reclaim.lock) + list_splice_init(&ptdev->reclaim.vms, &vms); =20 while (freed < nr_to_scan) { struct panthor_vm *vm; =20 - vm =3D list_first_entry_or_null(&vms, typeof(*vm), - reclaim.lru_node); - if (!vm) - break; - - if (!kref_get_unless_zero(&vm->base.kref)) { - list_del_init(&vm->reclaim.lru_node); - continue; + scoped_guard(mutex, &ptdev->reclaim.lock) { + vm =3D list_first_entry_or_null(&vms, typeof(*vm), + reclaim.lru_node); + if (vm && !kref_get_unless_zero(&vm->base.kref)) { + list_del_init(&vm->reclaim.lru_node); + vm =3D NULL; + } } =20 - mutex_unlock(&ptdev->reclaim.lock); + if (!vm) + break; =20 freed +=3D drm_gem_lru_scan(&vm->reclaim.lru, nr_to_scan - freed, remaining, shrink, NULL); =20 - mutex_lock(&ptdev->reclaim.lock); - - /* If the VM is still in the temporary list, remove it so we - * can proceed with the next VM. - */ - if (vm =3D=3D list_first_entry_or_null(&vms, typeof(*vm), reclaim.lru_no= de)) { - list_del_init(&vm->reclaim.lru_node); - - /* Keep the VM around if there are still things to - * reclaim, so we can preserve the LRU order when - * re-inserting in ptdev->reclaim.vms at the end. + scoped_guard(mutex, &ptdev->reclaim.lock) { + /* If the VM is still in the temporary list, remove it so we + * can proceed with the next VM. */ - if (vm->reclaim.lru.count > 0) - list_add_tail(&vm->reclaim.lru_node, &remaining_vms); + if (vm =3D=3D list_first_entry_or_null(&vms, typeof(*vm), reclaim.lru_n= ode)) { + list_del_init(&vm->reclaim.lru_node); + + /* Keep the VM around if there are still things to + * reclaim, so we can preserve the LRU order when + * re-inserting in ptdev->reclaim.vms at the end. + */ + if (vm->reclaim.lru.count > 0) + list_add_tail(&vm->reclaim.lru_node, &remaining_vms); + } } =20 - mutex_unlock(&ptdev->reclaim.lock); - panthor_vm_put(vm); - - mutex_lock(&ptdev->reclaim.lock); } =20 /* Re-insert VMs with remaining data to reclaim at the beginning of @@ -3192,9 +3172,10 @@ panthor_mmu_reclaim_priv_bos(struct panthor_device *= ptdev, * temporary [remaining_]vms list, meaning anything we re-insert here * preserves the LRU order. */ - list_splice_tail(&vms, &remaining_vms); - list_splice(&remaining_vms, &ptdev->reclaim.vms); - mutex_unlock(&ptdev->reclaim.lock); + scoped_guard(mutex, &ptdev->reclaim.lock) { + list_splice_tail(&vms, &remaining_vms); + list_splice(&remaining_vms, &ptdev->reclaim.vms); + } =20 return freed; } @@ -3211,7 +3192,7 @@ void panthor_mmu_unplug(struct panthor_device *ptdev) if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) panthor_irq_suspend(&ptdev->mmu->irq); =20 - mutex_lock(&ptdev->mmu->as.slots_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { struct panthor_vm *vm =3D ptdev->mmu->as.slots[i].vm; =20 @@ -3221,7 +3202,6 @@ void panthor_mmu_unplug(struct panthor_device *ptdev) panthor_vm_release_as_locked(vm); } } - mutex_unlock(&ptdev->mmu->as.slots_lock); } =20 static void panthor_mmu_release_wq(struct drm_device *ddev, void *res) @@ -3290,13 +3270,9 @@ int panthor_mmu_init(struct panthor_device *ptdev) #ifdef CONFIG_DEBUG_FS static int show_vm_gpuvas(struct panthor_vm *vm, struct seq_file *m) { - int ret; + guard(mutex)(&vm->op_lock); =20 - mutex_lock(&vm->op_lock); - ret =3D drm_debugfs_gpuva_info(m, &vm->base); - mutex_unlock(&vm->op_lock); - - return ret; + return drm_debugfs_gpuva_info(m, &vm->base); } =20 static int show_each_vm(struct seq_file *m, void *arg) @@ -3308,17 +3284,16 @@ static int show_each_vm(struct seq_file *m, void *a= rg) struct panthor_vm *vm; int ret =3D 0; =20 - mutex_lock(&ptdev->mmu->vm.lock); + guard(mutex)(&ptdev->mmu->vm.lock); list_for_each_entry(vm, &ptdev->mmu->vm.list, node) { ret =3D show(vm, m); if (ret < 0) - break; + return ret; =20 seq_puts(m, "\n"); } - mutex_unlock(&ptdev->mmu->vm.lock); =20 - return ret; + return 0; } =20 static struct drm_info_list panthor_mmu_debugfs_list[] =3D { diff --git a/drivers/gpu/drm/panthor/panthor_pwr.c b/drivers/gpu/drm/pantho= r/panthor_pwr.c index 1efb7f3482ba..340d3260bd55 100644 --- a/drivers/gpu/drm/panthor/panthor_pwr.c +++ b/drivers/gpu/drm/panthor/panthor_pwr.c @@ -61,7 +61,7 @@ static void panthor_pwr_irq_handler(struct panthor_irq *p= irq, u32 status) struct panthor_device *ptdev =3D pirq->ptdev; struct panthor_pwr *pwr =3D ptdev->pwr; =20 - spin_lock(&ptdev->pwr->reqs_lock); + guard(spinlock_irqsave)(&ptdev->pwr->reqs_lock); gpu_write(pwr->irq.iomem, INT_CLEAR, status); =20 if (unlikely(status & PWR_IRQ_COMMAND_NOT_ALLOWED)) @@ -74,7 +74,6 @@ static void panthor_pwr_irq_handler(struct panthor_irq *p= irq, u32 status) ptdev->pwr->pending_reqs &=3D ~status; wake_up_all(&ptdev->pwr->reqs_acked); } - spin_unlock(&ptdev->pwr->reqs_lock); } =20 static irqreturn_t panthor_pwr_irq_threaded_handler(int irq, void *data) @@ -452,8 +451,6 @@ static int panthor_pwr_domain_force_off(struct panthor_= device *ptdev, u32 domain =20 void panthor_pwr_unplug(struct panthor_device *ptdev) { - unsigned long flags; - if (!ptdev->pwr) return; =20 @@ -461,10 +458,9 @@ void panthor_pwr_unplug(struct panthor_device *ptdev) panthor_irq_suspend(&ptdev->pwr->irq); =20 /* Wake-up all waiters. */ - spin_lock_irqsave(&ptdev->pwr->reqs_lock, flags); + guard(spinlock_irqsave)(&ptdev->pwr->reqs_lock); ptdev->pwr->pending_reqs =3D 0; wake_up_all(&ptdev->pwr->reqs_acked); - spin_unlock_irqrestore(&ptdev->pwr->reqs_lock, flags); } =20 int panthor_pwr_init(struct panthor_device *ptdev) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index a9124bcc7de6..d8cadd393fbe 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -1492,21 +1492,21 @@ static int group_process_tiler_oom(struct panthor_g= roup *group, u32 cs_id) u32 vt_start, vt_end, frag_end; int ret, csg_id; =20 - mutex_lock(&sched->lock); - csg_id =3D group->csg_id; - if (csg_id >=3D 0) { - struct panthor_fw_cs_iface *cs_iface; + scoped_guard(mutex, &sched->lock) { + csg_id =3D group->csg_id; + if (csg_id >=3D 0) { + struct panthor_fw_cs_iface *cs_iface; =20 - cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); - heaps =3D panthor_vm_get_heap_pool(group->vm, false); - heap_address =3D cs_iface->output->heap_address; - vt_start =3D cs_iface->output->heap_vt_start; - vt_end =3D cs_iface->output->heap_vt_end; - frag_end =3D cs_iface->output->heap_frag_end; - renderpasses_in_flight =3D vt_start - frag_end; - pending_frag_count =3D vt_end - frag_end; + cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); + heaps =3D panthor_vm_get_heap_pool(group->vm, false); + heap_address =3D cs_iface->output->heap_address; + vt_start =3D cs_iface->output->heap_vt_start; + vt_end =3D cs_iface->output->heap_vt_end; + frag_end =3D cs_iface->output->heap_frag_end; + renderpasses_in_flight =3D vt_start - frag_end; + pending_frag_count =3D vt_end - frag_end; + } } - mutex_unlock(&sched->lock); =20 /* The group got scheduled out, we stop here. We will get a new tiler OOM= event * when it's scheduled again. @@ -1537,22 +1537,22 @@ static int group_process_tiler_oom(struct panthor_g= roup *group, u32 cs_id) goto out_put_heap_pool; } =20 - mutex_lock(&sched->lock); - csg_id =3D group->csg_id; - if (csg_id >=3D 0) { - struct panthor_fw_csg_iface *csg_iface; - struct panthor_fw_cs_iface *cs_iface; + scoped_guard(mutex, &sched->lock) { + csg_id =3D group->csg_id; + if (csg_id >=3D 0) { + struct panthor_fw_csg_iface *csg_iface; + struct panthor_fw_cs_iface *cs_iface; =20 - csg_iface =3D panthor_fw_get_csg_iface(ptdev, csg_id); - cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); + csg_iface =3D panthor_fw_get_csg_iface(ptdev, csg_id); + cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); =20 - cs_iface->input->heap_start =3D new_chunk_va; - cs_iface->input->heap_end =3D new_chunk_va; - panthor_fw_update_reqs(cs_iface, req, cs_iface->output->ack, CS_TILER_OO= M); - panthor_fw_toggle_reqs(csg_iface, doorbell_req, doorbell_ack, BIT(cs_id)= ); - panthor_fw_ring_csg_doorbells(ptdev, BIT(csg_id)); + cs_iface->input->heap_start =3D new_chunk_va; + cs_iface->input->heap_end =3D new_chunk_va; + panthor_fw_update_reqs(cs_iface, req, cs_iface->output->ack, CS_TILER_O= OM); + panthor_fw_toggle_reqs(csg_iface, doorbell_req, doorbell_ack, BIT(cs_id= )); + panthor_fw_ring_csg_doorbells(ptdev, BIT(csg_id)); + } } - mutex_unlock(&sched->lock); =20 /* We allocated a chunck, but couldn't link it to the heap * context because the group was scheduled out while we were @@ -2505,24 +2505,15 @@ tick_ctx_update_resched_target(struct panthor_sched= uler *sched, return U64_MAX; } =20 -static void tick_work(struct work_struct *work) +static void tick(struct panthor_scheduler *sched) { - struct panthor_scheduler *sched =3D container_of(work, struct panthor_sch= eduler, - tick_work.work); struct panthor_device *ptdev =3D sched->ptdev; struct panthor_sched_tick_ctx ctx; u64 resched_target =3D sched->resched_target; u64 remaining_jiffies =3D 0, resched_delay; u64 now =3D get_jiffies_64(); - int prio, ret, cookie; bool full_tick; - - if (!drm_dev_enter(&ptdev->base, &cookie)) - return; - - ret =3D panthor_device_resume_and_get(ptdev); - if (drm_WARN_ON(&ptdev->base, ret)) - goto out_dev_exit; + int prio; =20 /* If the tick is stopped, calculate when the next tick would be */ if (resched_target =3D=3D U64_MAX) @@ -2533,9 +2524,9 @@ static void tick_work(struct work_struct *work) =20 full_tick =3D remaining_jiffies =3D=3D 0; =20 - mutex_lock(&sched->lock); + guard(mutex)(&sched->lock); if (panthor_device_reset_is_pending(sched->ptdev)) - goto out_unlock; + return; =20 tick_ctx_init(sched, &ctx); if (ctx.csg_upd_failed_mask) @@ -2626,9 +2617,23 @@ static void tick_work(struct work_struct *work) =20 out_cleanup_ctx: tick_ctx_cleanup(sched, &ctx); +} =20 -out_unlock: - mutex_unlock(&sched->lock); +static void tick_work(struct work_struct *work) +{ + struct panthor_scheduler *sched =3D container_of(work, struct panthor_sch= eduler, + tick_work.work); + struct panthor_device *ptdev =3D sched->ptdev; + int ret, cookie; + + if (!drm_dev_enter(&ptdev->base, &cookie)) + return; + + ret =3D panthor_device_resume_and_get(ptdev); + if (drm_WARN_ON(&ptdev->base, ret)) + goto out_dev_exit; + + tick(sched); pm_runtime_mark_last_busy(ptdev->base.dev); pm_runtime_put_autosuspend(ptdev->base.dev); =20 @@ -2673,7 +2678,7 @@ static void sync_upd_work(struct work_struct *work) struct panthor_group *group, *tmp; bool immediate_tick =3D false; =20 - mutex_lock(&sched->lock); + guard(mutex)(&sched->lock); list_for_each_entry_safe(group, tmp, &sched->groups.waiting, wait_node) { u32 tested_queues =3D group->blocked_queues; u32 unblocked_queues =3D 0; @@ -2704,7 +2709,6 @@ static void sync_upd_work(struct work_struct *work) if (!group->blocked_queues) list_del_init(&group->wait_node); } - mutex_unlock(&sched->lock); =20 if (immediate_tick) sched_queue_delayed_work(sched, tick, 0); @@ -2877,7 +2881,7 @@ void panthor_sched_suspend(struct panthor_device *ptd= ev) u32 suspended_slots; u32 i; =20 - mutex_lock(&sched->lock); + guard(mutex)(&sched->lock); csgs_upd_ctx_init(&upd_ctx); for (i =3D 0; i < sched->csg_slot_count; i++) { struct panthor_csg_slot *csg_slot =3D &sched->csg_slots[i]; @@ -2998,7 +3002,6 @@ void panthor_sched_suspend(struct panthor_device *ptd= ev) } group_put(group); } - mutex_unlock(&sched->lock); } =20 void panthor_sched_pre_reset(struct panthor_device *ptdev) @@ -3007,7 +3010,7 @@ void panthor_sched_pre_reset(struct panthor_device *p= tdev) struct panthor_group *group, *group_tmp; u32 i; =20 - mutex_lock(&sched->reset.lock); + guard(mutex)(&sched->reset.lock); atomic_set(&sched->reset.in_progress, true); =20 /* Cancel all scheduler works. Once this is done, these works can't be @@ -3030,8 +3033,6 @@ void panthor_sched_pre_reset(struct panthor_device *p= tdev) list_for_each_entry_safe(group, group_tmp, &sched->groups.idle[i], run_n= ode) panthor_group_stop(group); } - - mutex_unlock(&sched->reset.lock); } =20 void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_fai= led) @@ -3039,7 +3040,7 @@ void panthor_sched_post_reset(struct panthor_device *= ptdev, bool reset_failed) struct panthor_scheduler *sched =3D ptdev->scheduler; struct panthor_group *group, *group_tmp; =20 - mutex_lock(&sched->reset.lock); + guard(mutex)(&sched->reset.lock); =20 list_for_each_entry_safe(group, group_tmp, &sched->reset.stopped_groups, = run_node) { /* Consider all previously running group as terminated if the @@ -3055,7 +3056,6 @@ void panthor_sched_post_reset(struct panthor_device *= ptdev, bool reset_failed) * kick the scheduler. */ atomic_set(&sched->reset.in_progress, false); - mutex_unlock(&sched->reset.lock); =20 /* No need to queue a tick and update syncs if the reset failed. */ if (!reset_failed) { @@ -3265,36 +3265,19 @@ static u32 calc_job_credits(u32 profile_mask) } =20 static struct dma_fence * -queue_run_job(struct drm_sched_job *sched_job) +queue_run_job_locked(struct panthor_job *job) { - struct panthor_job *job =3D container_of(sched_job, struct panthor_job, b= ase); struct panthor_group *group =3D job->group; struct panthor_queue *queue =3D group->queues[job->queue_idx]; struct panthor_device *ptdev =3D group->ptdev; struct panthor_scheduler *sched =3D ptdev->scheduler; struct panthor_job_ringbuf_instrs instrs; struct panthor_job_cs_params cs_params; - struct dma_fence *done_fence; - int ret; =20 - /* Stream size is zero, nothing to do except making sure all previously - * submitted jobs are done before we signal the - * drm_sched_job::s_fence::finished fence. - */ - if (!job->call_info.size) { - job->done_fence =3D dma_fence_get(queue->fence_ctx.last_fence); - return dma_fence_get(job->done_fence); - } + lockdep_assert_held(&sched->lock); =20 - ret =3D panthor_device_resume_and_get(ptdev); - if (drm_WARN_ON(&ptdev->base, ret)) - return ERR_PTR(ret); - - mutex_lock(&sched->lock); - if (!group_can_run(group)) { - done_fence =3D ERR_PTR(-ECANCELED); - goto out_unlock; - } + if (!group_can_run(group)) + return ERR_PTR(-ECANCELED); =20 dma_fence_init(job->done_fence, &panthor_queue_fence_ops, @@ -3355,10 +3338,37 @@ queue_run_job(struct drm_sched_job *sched_job) dma_fence_put(queue->fence_ctx.last_fence); queue->fence_ctx.last_fence =3D dma_fence_get(job->done_fence); =20 - done_fence =3D dma_fence_get(job->done_fence); + return dma_fence_get(job->done_fence); +} + +static struct dma_fence * +queue_run_job(struct drm_sched_job *sched_job) +{ + struct panthor_job *job =3D container_of(sched_job, struct panthor_job, b= ase); + struct panthor_group *group =3D job->group; + struct panthor_queue *queue =3D group->queues[job->queue_idx]; + struct panthor_device *ptdev =3D group->ptdev; + struct panthor_scheduler *sched =3D ptdev->scheduler; + struct dma_fence *done_fence; + int ret; + + /* Stream size is zero, nothing to do except making sure all previously + * submitted jobs are done before we signal the + * drm_sched_job::s_fence::finished fence. + */ + if (!job->call_info.size) { + job->done_fence =3D dma_fence_get(queue->fence_ctx.last_fence); + return dma_fence_get(job->done_fence); + } + + ret =3D panthor_device_resume_and_get(ptdev); + if (drm_WARN_ON(&ptdev->base, ret)) + return ERR_PTR(ret); + + scoped_guard(mutex, &sched->lock) { + done_fence =3D queue_run_job_locked(job); + } =20 -out_unlock: - mutex_unlock(&sched->lock); pm_runtime_mark_last_busy(ptdev->base.dev); pm_runtime_put_autosuspend(ptdev->base.dev); =20 @@ -3381,20 +3391,20 @@ queue_timedout_job(struct drm_sched_job *sched_job) =20 queue_stop(queue, job); =20 - mutex_lock(&sched->lock); - group->timedout =3D true; - if (group->csg_id >=3D 0) { - sched_queue_delayed_work(ptdev->scheduler, tick, 0); - } else { - /* Remove from the run queues, so the scheduler can't - * pick the group on the next tick. - */ - list_del_init(&group->run_node); - list_del_init(&group->wait_node); + scoped_guard(mutex, &sched->lock) { + group->timedout =3D true; + if (group->csg_id >=3D 0) { + sched_queue_delayed_work(ptdev->scheduler, tick, 0); + } else { + /* Remove from the run queues, so the scheduler can't + * pick the group on the next tick. + */ + list_del_init(&group->run_node); + list_del_init(&group->wait_node); =20 - group_queue_work(group, term); + group_queue_work(group, term); + } } - mutex_unlock(&sched->lock); =20 queue_start(queue); return DRM_GPU_SCHED_STAT_RESET; @@ -3713,16 +3723,15 @@ int panthor_group_create(struct panthor_file *pfile, =20 group->idle_queues =3D GENMASK(group->queue_count - 1, 0); =20 - mutex_lock(&sched->reset.lock); - if (atomic_read(&sched->reset.in_progress)) { - panthor_group_stop(group); - } else { - mutex_lock(&sched->lock); - list_add_tail(&group->run_node, - &sched->groups.idle[group->priority]); - mutex_unlock(&sched->lock); + scoped_guard(mutex, &sched->reset.lock) { + if (atomic_read(&sched->reset.in_progress)) { + panthor_group_stop(group); + } else { + guard(mutex)(&sched->lock); + list_add_tail(&group->run_node, + &sched->groups.idle[group->priority]); + } } - mutex_unlock(&sched->reset.lock); =20 add_group_kbo_sizes(group->ptdev, group); spin_lock_init(&group->fdinfo.lock); @@ -3755,21 +3764,20 @@ int panthor_group_destroy(struct panthor_file *pfil= e, u32 group_handle) if (!group) return -EINVAL; =20 - mutex_lock(&sched->reset.lock); - mutex_lock(&sched->lock); - group->destroyed =3D true; - if (group->csg_id >=3D 0) { - sched_queue_delayed_work(sched, tick, 0); - } else if (!atomic_read(&sched->reset.in_progress)) { - /* Remove from the run queues, so the scheduler can't - * pick the group on the next tick. - */ - list_del_init(&group->run_node); - list_del_init(&group->wait_node); - group_queue_work(group, term); + scoped_guard(mutex, &sched->reset.lock) { + guard(mutex)(&sched->lock); + group->destroyed =3D true; + if (group->csg_id >=3D 0) { + sched_queue_delayed_work(sched, tick, 0); + } else if (!atomic_read(&sched->reset.in_progress)) { + /* Remove from the run queues, so the scheduler can't + * pick the group on the next tick. + */ + list_del_init(&group->run_node); + list_del_init(&group->wait_node); + group_queue_work(group, term); + } } - mutex_unlock(&sched->lock); - mutex_unlock(&sched->reset.lock); =20 group_put(group); return 0; @@ -3804,16 +3812,16 @@ int panthor_group_get_state(struct panthor_file *pf= ile, =20 memset(get_state, 0, sizeof(*get_state)); =20 - mutex_lock(&sched->lock); - if (group->timedout) - get_state->state |=3D DRM_PANTHOR_GROUP_STATE_TIMEDOUT; - if (group->fatal_queues) { - get_state->state |=3D DRM_PANTHOR_GROUP_STATE_FATAL_FAULT; - get_state->fatal_queues =3D group->fatal_queues; + scoped_guard(mutex, &sched->lock) { + if (group->timedout) + get_state->state |=3D DRM_PANTHOR_GROUP_STATE_TIMEDOUT; + if (group->fatal_queues) { + get_state->state |=3D DRM_PANTHOR_GROUP_STATE_FATAL_FAULT; + get_state->fatal_queues =3D group->fatal_queues; + } + if (group->innocent) + get_state->state |=3D DRM_PANTHOR_GROUP_STATE_INNOCENT; } - if (group->innocent) - get_state->state |=3D DRM_PANTHOR_GROUP_STATE_INNOCENT; - mutex_unlock(&sched->lock); =20 group_put(group); return 0; @@ -4023,12 +4031,11 @@ void panthor_sched_unplug(struct panthor_device *pt= dev) disable_delayed_work_sync(&sched->tick_work); disable_work_sync(&sched->sync_upd_work); =20 - mutex_lock(&sched->lock); + guard(mutex)(&sched->lock); if (sched->pm.has_ref) { pm_runtime_put(ptdev->base.dev); sched->pm.has_ref =3D false; } - mutex_unlock(&sched->lock); } =20 static void panthor_sched_fini(struct drm_device *ddev, void *res) --=20 2.54.0 From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CA864DA545; Wed, 13 May 2026 16:59:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691545; cv=none; b=QnCE3gmVoxJSVSRcSiAcTPUa9AP51SW2MGLAAEMiTcqpoZGpJ2UIZ42MDvLaIZ4VvfTEE8jZkBSYfE0bmpTIqmPTYLjcgXWAE1nVxKGRDsYctxFFkgTTZpeEY12ehvbsZco4buDO/ney6wfgeSt+eyTlIYx9zAe6D7Rd4u43S40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691545; c=relaxed/simple; bh=0OQwKbihhL4l6Gg92F+5W95NMeySKGXxSegqXoUTufA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AM7SoMXGR8MZlVqSQMCwERLJt5S9g9VUdt/Mqupkx1j4KImPMRTW31xvscIsykOrWjob+yLRyoPS+XVNJ1Ph46w4wRvvc7Xp9g63nq6u/CBqlSdfGRj/sgxZJgdcg95pQ1GGUNw0hIgvTJXJcWk3IHl3+Eps2qvXFRdgB4CzaUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Dxb+IAhb; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Dxb+IAhb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691541; bh=0OQwKbihhL4l6Gg92F+5W95NMeySKGXxSegqXoUTufA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Dxb+IAhbRGLXHKb4n8nGIjtrDyltHEIvjekTkPRW86Z2GKA6RUaJE3QQw2AwE/sQi 3uZO7efstdUfSccotCcO0DfZ90V6iOZydjg+LtYNWSNqtMIUrxf1dw1WYBshQZq5Px 8WJUNaVyBBOQhbKl5RUF+zXbARJddyhSD2QaPvwG+LeKuPrHm8HKnWwKrknPI0GWUq cHFZG71xu8OM6aS/XvEcoUPjthwj7mYtsDYI2ekYrJ9TR8/9cYUony3b/gV1f5/FAw sj5RRjH/6c3nYQb9JEw4D5+FLYZqOs0TqRecReGVNvVpc6fO6KAoAJhoWjRxZtyPKs UcEh0Iz3Vx6iA== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id D5E4A17E156E; Wed, 13 May 2026 18:59:00 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:50 +0200 Subject: [PATCH 2/6] dma-resv: Define guards for context-less dma_resv locks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-2-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=1220; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=0OQwKbihhL4l6Gg92F+5W95NMeySKGXxSegqXoUTufA=; b=xilM6lR+4IMUjFkcXTn/tPBSzFs1xaXCDrF+j1zMUf4DsDX6g+1XB2TSR14o+EYGkRBtR2yLZ sjpVbTeL/v2DMevUfB8qax4xB2AJGbFboAA/mLo/VyBwtQssRUIMkDe X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= When used without a context, dma_resv are no different from regular locks. Define guards so we can use the guard-syntactic sugars for explicit/implicit scoped locks. Signed-off-by: Boris Brezillon Reviewed-by: Chia-I Wu Reviewed-by: Christian K=C3=B6nig Reviewed-by: Steven Price --- include/linux/dma-resv.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h index c5ab6fd9ebe8..e559b1811ca3 100644 --- a/include/linux/dma-resv.h +++ b/include/linux/dma-resv.h @@ -40,6 +40,7 @@ #define _LINUX_RESERVATION_H =20 #include +#include #include #include #include @@ -484,4 +485,8 @@ void dma_resv_set_deadline(struct dma_resv *obj, enum d= ma_resv_usage usage, bool dma_resv_test_signaled(struct dma_resv *obj, enum dma_resv_usage usag= e); void dma_resv_describe(struct dma_resv *obj, struct seq_file *seq); =20 +DEFINE_GUARD(dma_resv, struct dma_resv *, dma_resv_lock(_T, NULL), dma_res= v_unlock(_T)); +DEFINE_GUARD_COND(dma_resv, _intr, dma_resv_lock_interruptible(_T, NULL), = !_RET); +DEFINE_GUARD_COND(dma_resv, _try, dma_resv_trylock(_T)); + #endif /* _LINUX_RESERVATION_H */ --=20 2.54.0 From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CEA3C4C0419; Wed, 13 May 2026 16:59:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691546; cv=none; b=QQlqzc7D11eKq7FtgA2gtIOixdm8sLq+TtJS2rcyaCfv8tkrALmXNfEu73ljoEZvJsmjQil4lKwArGgtupVOYOM58bSyfxFy+vCvGuE74a2HM7BBTDwEbfkJhj3+VLgDScTiCLmto44ZnFTf6R6qGGfbtKByNMjNeCyDceDjTpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691546; c=relaxed/simple; bh=AAqKJoPOOkLMripnuQaHw9xbx35RrEUMeTSdxMx4p6s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B77jKLGCt8n+KRntvz8bAwXYj9Q2q0cYGKxFWa7GcyebYFxaq83VVx4VdLxHRyi8h5DedlQE5KC4ogeBb/k7tLqJ+zzXZQiB2/YkVDQvbAJCmk3f76kv3DfQVVuwhe2yVijr1sMU19qZvVMXCak4M4YDnIu2VeL6S2mv+tsOI5Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=iz7J+lbh; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="iz7J+lbh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691542; bh=AAqKJoPOOkLMripnuQaHw9xbx35RrEUMeTSdxMx4p6s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=iz7J+lbh0ukvjOToMFhD5Zp8Se4seX2ihx25f/7zzFUb0I7hTL8179T8uCclw+FSw 1MRunWebsti7/QI1M/oKi7k3n2cTIo/Mb1LtRxiV4099JPsz8qbhZdDKsYSoFqDtb7 B9hN248Y6p+ePLN9GNKED/cXdduVAQb0q485ypZmmKxANrbTGBD+4eqCZqGY2YfkrJ z12Go3GpLzOD3CKfNRrw5ud+cAnuQtUyDNaqNblSrYjK6NyUdkKn4ADkxANeNdT6ro CAszu8lPyEaUkjJW2sFw01FhuRYrqlWH83unEuhlFyH8Q9mKVU6axEOViIayI0oDAB A685TKVXB1fTQ== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id 86F8B17E1584; Wed, 13 May 2026 18:59:01 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:51 +0200 Subject: [PATCH 3/6] drm: Define a conditional guard for drm_dev_{enter,exit}() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-3-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=1053; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=AAqKJoPOOkLMripnuQaHw9xbx35RrEUMeTSdxMx4p6s=; b=FYRu54IWmcIrt4VqItE/N6hDpklTqfnMHVMRaefA+rhpji77Nnesrd2OBc/n1HO3aQJVUjjtc z7TIGQgNP8uDMCgjQngOurcrLUVY/qExit+MP4PzEpPLSs8Pva8lVXu X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Define a conditional drm_dev_access guard to automate the drm_dev_{enter,exit}() sequence. Signed-off-by: Boris Brezillon --- include/drm/drm_drv.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 42fc085f986d..79d1958f93e4 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -490,6 +490,15 @@ void drm_dev_unplug(struct drm_device *dev); int drm_dev_wedged_event(struct drm_device *dev, unsigned long method, struct drm_wedge_task_info *info); =20 +/* + * Only the conditional drm_dev_access guard is valid. The drm_dev one is + * here so we can extend it with a conditional variant. + */ +DEFINE_LOCK_GUARD_1(drm_dev, struct drm_device, + { WARN_ON("Use cond guards"); _T->idx =3D -1; }, + drm_dev_exit(_T->idx), int idx); +DEFINE_LOCK_GUARD_1_COND(drm_dev, _access, drm_dev_enter(_T->lock, &_T->id= x)); + /** * drm_dev_is_unplugged - is a DRM device unplugged * @dev: DRM device --=20 2.54.0 From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDE954D990C; Wed, 13 May 2026 16:59:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691547; cv=none; b=FHPXm5gsY+hMIXAetN/hVyqEY0UjI0tZa4VY3DM6M23648SGIdsbh0tqSxxkf8aHBSXG/C8RdO+Qr6J2EiDo8lugPJJ9cJAsDBsjMTWBHt+yarIhtl56nToQtpV/X8gdvr0PJE7NpcLssFxTYWDescwJas5PDgb0CLsXtPZ/LoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691547; c=relaxed/simple; bh=EJJ23B90TRdK54+z/YbNMzCTJKQm4n/q+/3aupZ8f0I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BZSlu5Q3SWboku2SeByal9ox9vcLyPJyQV9lULqZbmAZXY8VwuqtZRGNEN5Ov5gBtJMqngPX16eHRhq7nDqdLXqyiOVPdRxZfR7OE3cHR6dCtRWDUxFptjW+vHY+WHOWAvLIvMSdm7WrBQofIg4G2CzyCHcRyBdLnxFUeG8yAiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=DrAS9pHG; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="DrAS9pHG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691542; bh=EJJ23B90TRdK54+z/YbNMzCTJKQm4n/q+/3aupZ8f0I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=DrAS9pHGJD4f2D7ukaPu+A1IQfK1Tmf1k987qVc1/qhi342IIcDduEZSkWDd/AvKB Z89nXb0d8An2t0HEPUaLzJ1aF7Fh/4jwhi3l0rxO5LEmPEdPSfKlZRHl3I7mZZgcEz sM55Oyt/G0QaBmA19f9+OTS/luSMT/bO9HF1dZAXkdQznpikjjvBvQmD05IYdbfaOV D5EwikP+TeQ33MCFX7heaUetVL6Mp6dDJ0nryvvt8B++xZCoxkEOg3Pngv61DalU/E OktWfQNlEg8yfvKns4d1CydELglnTyMi+G/uUYeMl2EqqeDNinhfDllr7a3ZTq+bfW G5Ki7sTfxl9FQ== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id 33EDF17E15D6; Wed, 13 May 2026 18:59:02 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:52 +0200 Subject: [PATCH 4/6] drm/panthor: Use guards for resv locking Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-4-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=8300; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=EJJ23B90TRdK54+z/YbNMzCTJKQm4n/q+/3aupZ8f0I=; b=MjAH65QDppFUt8iLXK6Pl2Zzl8rYttDheFLSv5H17jH5+LrQcGulXVS5YF9iEEyKNbwRyMpT6 0s/nyLlC0JPDAGp+cQ1F4btNTwRZsXBqV8JNW+8X9Oq0QnFIkUMoLd5 X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Now that we have guards for resv locks, we can use them to simplify the core. The only manual lock/unlock remaining are the ones in panthor_gem_try_evict_no_resv_wait(), because the lock/unlock are in different for_each() loop scopes. Signed-off-by: Boris Brezillon Reviewed-by: Chia-I Wu --- drivers/gpu/drm/panthor/panthor_gem.c | 77 ++++++++++++-------------------= ---- drivers/gpu/drm/panthor/panthor_mmu.c | 16 ++++---- 2 files changed, 32 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/pantho= r/panthor_gem.c index a6fddc380e7d..94facdc8cfe1 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -339,13 +339,9 @@ panthor_gem_dev_map_get_sgt_locked(struct panthor_gem_= object *bo) struct sg_table * panthor_gem_get_dev_sgt(struct panthor_gem_object *bo) { - struct sg_table *sgt; + guard(dma_resv)(bo->base.resv); =20 - dma_resv_lock(bo->base.resv, NULL); - sgt =3D panthor_gem_dev_map_get_sgt_locked(bo); - dma_resv_unlock(bo->base.resv); - - return sgt; + return panthor_gem_dev_map_get_sgt_locked(bo); } =20 static void @@ -497,7 +493,7 @@ panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_= buf, struct panthor_gem_object *bo =3D to_panthor_bo(obj); struct dma_buf_attachment *attach; =20 - dma_resv_lock(obj->resv, NULL); + guard(dma_resv)(obj->resv); if (bo->dmap.sgt) dma_sync_sgtable_for_cpu(drm_dev_dma_dev(dev), bo->dmap.sgt, dir); =20 @@ -510,7 +506,6 @@ panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_= buf, if (sgt) dma_sync_sgtable_for_cpu(attach->dev, sgt, dir); } - dma_resv_unlock(obj->resv); =20 return 0; } @@ -524,7 +519,7 @@ panthor_gem_prime_end_cpu_access(struct dma_buf *dma_bu= f, struct panthor_gem_object *bo =3D to_panthor_bo(obj); struct dma_buf_attachment *attach; =20 - dma_resv_lock(obj->resv, NULL); + guard(dma_resv)(obj->resv); list_for_each_entry(attach, &dma_buf->attachments, node) { struct sg_table *sgt =3D attach->priv; =20 @@ -538,7 +533,6 @@ panthor_gem_prime_end_cpu_access(struct dma_buf *dma_bu= f, if (bo->dmap.sgt) dma_sync_sgtable_for_device(drm_dev_dma_dev(dev), bo->dmap.sgt, dir); =20 - dma_resv_unlock(obj->resv); return 0; } =20 @@ -625,19 +619,15 @@ static void panthor_gem_unpin_locked(struct drm_gem_o= bject *obj) =20 int panthor_gem_pin(struct panthor_gem_object *bo) { - int ret =3D 0; - if (drm_gem_is_imported(&bo->base)) return 0; =20 if (refcount_inc_not_zero(&bo->backing.pin_count)) return 0; =20 - dma_resv_lock(bo->base.resv, NULL); - ret =3D panthor_gem_backing_pin_locked(bo); - dma_resv_unlock(bo->base.resv); + guard(dma_resv)(bo->base.resv); =20 - return ret; + return panthor_gem_backing_pin_locked(bo); } =20 void panthor_gem_unpin(struct panthor_gem_object *bo) @@ -648,9 +638,8 @@ void panthor_gem_unpin(struct panthor_gem_object *bo) if (refcount_dec_not_one(&bo->backing.pin_count)) return; =20 - dma_resv_lock(bo->base.resv, NULL); + guard(dma_resv)(bo->base.resv); panthor_gem_backing_unpin_locked(bo); - dma_resv_unlock(bo->base.resv); } =20 int panthor_gem_swapin_locked(struct panthor_gem_object *bo) @@ -759,13 +748,12 @@ static int panthor_gem_mmap(struct drm_gem_object *ob= j, struct vm_area_struct *v return -EINVAL; =20 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { - dma_resv_lock(obj->resv, NULL); + guard(dma_resv)(obj->resv); if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { refcount_set(&bo->cmap.mmap_count, 1); guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); } - dma_resv_unlock(obj->resv); } =20 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); @@ -814,18 +802,12 @@ static vm_fault_t nonblocking_page_setup(struct vm_fa= ult *vmf, { struct vm_area_struct *vma =3D vmf->vma; struct panthor_gem_object *bo =3D to_panthor_bo(vma->vm_private_data); - vm_fault_t ret; =20 - if (!dma_resv_trylock(bo->base.resv)) + ACQUIRE(dma_resv_try, resv_guard)(bo->base.resv); + if (ACQUIRE_ERR(dma_resv_try, &resv_guard) || !bo->backing.pages) return VM_FAULT_RETRY; =20 - if (bo->backing.pages) - ret =3D insert_page(vmf, order, bo->backing.pages[page_offset]); - else - ret =3D VM_FAULT_RETRY; - - dma_resv_unlock(bo->base.resv); - return ret; + return insert_page(vmf, order, bo->backing.pages[page_offset]); } =20 static vm_fault_t blocking_page_setup(struct vm_fault *vmf, unsigned int o= rder, @@ -835,8 +817,8 @@ static vm_fault_t blocking_page_setup(struct vm_fault *= vmf, unsigned int order, vm_fault_t ret; int err; =20 - err =3D dma_resv_lock_interruptible(bo->base.resv, NULL); - if (err) + ACQUIRE(dma_resv_intr, resv_guard)(bo->base.resv); + if (ACQUIRE_ERR(dma_resv_intr, &resv_guard)) return mmap_lock_held ? VM_FAULT_NOPAGE : VM_FAULT_RETRY; =20 err =3D panthor_gem_backing_get_pages_locked(bo); @@ -857,8 +839,6 @@ static vm_fault_t blocking_page_setup(struct vm_fault *= vmf, unsigned int order, ret =3D VM_FAULT_RETRY; } =20 - dma_resv_unlock(bo->base.resv); - return ret; } =20 @@ -932,12 +912,12 @@ static void panthor_gem_vm_close(struct vm_area_struc= t *vma) if (refcount_dec_not_one(&bo->cmap.mmap_count)) goto out; =20 - dma_resv_lock(bo->base.resv, NULL); - if (refcount_dec_and_test(&bo->cmap.mmap_count)) { - guard(mutex)(&bo->base.gpuva.lock); - panthor_gem_update_reclaim_state_locked(bo, NULL); + scoped_guard(dma_resv, bo->base.resv) { + if (refcount_dec_and_test(&bo->cmap.mmap_count)) { + guard(mutex)(&bo->base.gpuva.lock); + panthor_gem_update_reclaim_state_locked(bo, NULL); + } } - dma_resv_unlock(bo->base.resv); =20 out: drm_gem_object_put(&bo->base); @@ -1161,21 +1141,18 @@ panthor_gem_sync(struct drm_gem_object *obj, u32 ty= pe, if (size =3D=3D 0) return 0; =20 - ret =3D dma_resv_lock_interruptible(bo->base.resv, NULL); + ACQUIRE(dma_resv_intr, resv_guard)(bo->base.resv); + ret =3D ACQUIRE_ERR(dma_resv_intr, &resv_guard); if (ret) return ret; =20 /* If there's no pages, there's no point pulling those back, bail out ear= ly. */ - if (!bo->backing.pages) { - ret =3D 0; - goto out_unlock; - } + if (!bo->backing.pages) + return 0; =20 sgt =3D panthor_gem_dev_map_get_sgt_locked(bo); - if (IS_ERR(sgt)) { - ret =3D PTR_ERR(sgt); - goto out_unlock; - } + if (IS_ERR(sgt)) + return PTR_ERR(sgt); =20 for_each_sgtable_dma_sg(sgt, sgl, count) { if (size =3D=3D 0) @@ -1219,11 +1196,7 @@ panthor_gem_sync(struct drm_gem_object *obj, u32 typ= e, dma_sync_single_for_cpu(dma_dev, paddr, len, DMA_FROM_DEVICE); } =20 - ret =3D 0; - -out_unlock: - dma_resv_unlock(bo->base.resv); - return ret; + return 0; } =20 /** diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index 157eef286cb9..ab9a77e6a145 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -1118,10 +1118,10 @@ static void panthor_vm_bo_free(struct drm_gpuvm_bo = *vm_bo) /* We couldn't call this when we unlinked, because the resv lock can't * be taken in the dma signalling path, so call it now. */ - dma_resv_lock(bo->base.resv, NULL); - scoped_guard(mutex, &bo->base.gpuva.lock) + scoped_guard(dma_resv, bo->base.resv) { + guard(mutex)(&bo->base.gpuva.lock); panthor_gem_update_reclaim_state_locked(bo, NULL); - dma_resv_unlock(bo->base.resv); + } =20 kfree(vm_bo); } @@ -1342,16 +1342,14 @@ static int panthor_vm_prepare_map_op_ctx(struct pan= thor_vm_op_ctx *op_ctx, =20 /* Insert BO into the extobj list last, when we know nothing can fail. */ if (bo->base.resv !=3D panthor_vm_resv(vm)) { - dma_resv_lock(panthor_vm_resv(vm), NULL); + guard(dma_resv)(panthor_vm_resv(vm)); drm_gpuvm_bo_extobj_add(op_ctx->map.vm_bo); - dma_resv_unlock(panthor_vm_resv(vm)); } =20 /* And finally update the BO state. */ - dma_resv_lock(bo->base.resv, NULL); - scoped_guard(mutex, &bo->base.gpuva.lock) - panthor_gem_update_reclaim_state_locked(bo, NULL); - dma_resv_unlock(bo->base.resv); + guard(dma_resv)(bo->base.resv); + guard(mutex)(&bo->base.gpuva.lock); + panthor_gem_update_reclaim_state_locked(bo, NULL); =20 return 0; =20 --=20 2.54.0 From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E00D4DB557; Wed, 13 May 2026 16:59:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691550; cv=none; b=Ku8Juhvkn2OOOnEhR6mMdm5bHAIEBSQUshy4gfPob/rhCAtLznridMxLs+yXEJIlmJ1+WxdTC523KtNtBv4dUXrSANOI2SZnbUOe++xazk0M93Am2W5j9/vnGnh9TBZyuZjhB5KVaUeI6BlV4w1OvwSNxP/+pHlnLnhtQ95OeXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691550; c=relaxed/simple; bh=Lvz1a1n/wWJFbYaXmSb0nQujNWIYvHlSpP6TrVQhgHU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eHDTmGRXz6JRQAq5fSuQiTYTys60UEgLorLEwO3oDJHgXCVCTPcn6L4trNT0nWf/tNjzNP7AjLpT1UUDmsgnLobGNMv7FVgEXHnTkZgN+wOJgPej6KPEBnEbK6rP8NE7cCraLoWXnX22Jx01uTaNCQoFoztXhL7QMNebhytoHIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=GEH+1cg1; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="GEH+1cg1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691543; bh=Lvz1a1n/wWJFbYaXmSb0nQujNWIYvHlSpP6TrVQhgHU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GEH+1cg1lXYeDuYFMBEqHswXo8BWKzphI3QhubCrctdvY1MozD3PMvo08qlH9H7Ys lgEOx3qam60zaa855cyGzUOYyYgUhLFP2R3JHQn1bppE7337IWwfnrxN2FiZAgSGYx XnPYREovuE8x5NvQjD6uUDlJF2M+QF/WKEKOlViul6R+p0rO990NVrr82bGujriTz7 INTNMspRfP9LGyVL3EqwijB40HrjEULovRUJTD2dLUcVrmuTiYlH3tkqQRL2l8bRiQ 7CagwmKYCFpLc1g12CMTRgGfVxSAbYlu0uNB3tVfAeV/z/7HIr2IeopzI6FCemeLV/ /Qe3a00QEvBcg== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id D437F17E38BA; Wed, 13 May 2026 18:59:02 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:53 +0200 Subject: [PATCH 5/6] drm/panthor: Use the drm_dev_access guard Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-5-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=15018; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=Lvz1a1n/wWJFbYaXmSb0nQujNWIYvHlSpP6TrVQhgHU=; b=Ndg8PtyNHjA3lsDCp73Ufmw7Rpjzf6eDxJAvTN4qw6WggCsEi793DwK7BXL31M7Xs/A4a5i6D LrCIjamsiSkB5qsDnwPsmyua1de6mdZx5Nm3KAPXoBhPLfmYRJq/WzW X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= It simplifies the code in a few places, allowing direct returns instead of gotos. It also helps identifying the sections under the dev_access guard when scoped_cond_guard() is used. Signed-off-by: Boris Brezillon Reviewed-by: Chia-I Wu --- drivers/gpu/drm/panthor/panthor_device.c | 127 ++++++++++++++-------------= ---- drivers/gpu/drm/panthor/panthor_drv.c | 58 ++++++-------- drivers/gpu/drm/panthor/panthor_mmu.c | 29 +++---- drivers/gpu/drm/panthor/panthor_sched.c | 10 +-- 4 files changed, 95 insertions(+), 129 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/pan= thor/panthor_device.c index cb9cd8d0448b..988a9a34f753 100644 --- a/drivers/gpu/drm/panthor/panthor_device.c +++ b/drivers/gpu/drm/panthor/panthor_device.c @@ -123,7 +123,7 @@ static void panthor_device_reset_cleanup(struct drm_dev= ice *ddev, void *data) static void panthor_device_reset_work(struct work_struct *work) { struct panthor_device *ptdev =3D container_of(work, struct panthor_device= , reset.work); - int ret =3D 0, cookie; + int ret =3D 0; =20 /* If the device is entering suspend, we don't reset. A slow reset will * be forced at resume time instead. @@ -131,19 +131,17 @@ static void panthor_device_reset_work(struct work_str= uct *work) if (atomic_read(&ptdev->pm.state) !=3D PANTHOR_DEVICE_PM_STATE_ACTIVE) return; =20 - if (!drm_dev_enter(&ptdev->base, &cookie)) - return; - - panthor_sched_pre_reset(ptdev); - panthor_fw_pre_reset(ptdev, true); - panthor_mmu_pre_reset(ptdev); - panthor_hw_soft_reset(ptdev); - panthor_hw_l2_power_on(ptdev); - panthor_mmu_post_reset(ptdev); - ret =3D panthor_fw_post_reset(ptdev); - atomic_set(&ptdev->reset.pending, 0); - panthor_sched_post_reset(ptdev, ret !=3D 0); - drm_dev_exit(cookie); + scoped_cond_guard(drm_dev_access, return, &ptdev->base) { + panthor_sched_pre_reset(ptdev); + panthor_fw_pre_reset(ptdev, true); + panthor_mmu_pre_reset(ptdev); + panthor_hw_soft_reset(ptdev); + panthor_hw_l2_power_on(ptdev); + panthor_mmu_post_reset(ptdev); + ret =3D panthor_fw_post_reset(ptdev); + atomic_set(&ptdev->reset.pending, 0); + panthor_sched_post_reset(ptdev, ret !=3D 0); + } =20 if (ret) { panthor_device_unplug(ptdev); @@ -394,38 +392,31 @@ static vm_fault_t panthor_mmio_vm_fault(struct vm_fau= lt *vmf) u64 offset =3D (u64)vma->vm_pgoff << PAGE_SHIFT; unsigned long pfn; pgprot_t pgprot; - vm_fault_t ret; bool active; - int cookie; =20 - if (!drm_dev_enter(&ptdev->base, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(&ptdev->base); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return VM_FAULT_SIGBUS; =20 - scoped_guard(mutex, &ptdev->pm.mmio_lock) { - active =3D atomic_read(&ptdev->pm.state) =3D=3D PANTHOR_DEVICE_PM_STATE_= ACTIVE; + guard(mutex)(&ptdev->pm.mmio_lock); + active =3D atomic_read(&ptdev->pm.state) =3D=3D PANTHOR_DEVICE_PM_STATE_A= CTIVE; =20 - switch (offset) { - case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: - if (active) - pfn =3D __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID); - else - pfn =3D page_to_pfn(ptdev->pm.dummy_latest_flush); + switch (offset) { + case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: + if (active) + pfn =3D __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID); + else + pfn =3D page_to_pfn(ptdev->pm.dummy_latest_flush); =20 - pgprot =3D vma->vm_page_prot; - if (active) - pgprot =3D pgprot_noncached(pgprot); + pgprot =3D vma->vm_page_prot; + if (active) + pgprot =3D pgprot_noncached(pgprot); =20 - ret =3D vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot); - break; + return vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot); =20 - default: - ret =3D VM_FAULT_SIGBUS; - break; - } + default: + return VM_FAULT_SIGBUS; } - - drm_dev_exit(cookie); - return ret; } =20 static const struct vm_operations_struct panthor_mmio_vm_ops =3D { @@ -482,7 +473,7 @@ static int panthor_device_resume_hw_components(struct p= anthor_device *ptdev) int panthor_device_resume(struct device *dev) { struct panthor_device *ptdev =3D dev_get_drvdata(dev); - int ret, cookie; + int ret; =20 if (atomic_read(&ptdev->pm.state) !=3D PANTHOR_DEVICE_PM_STATE_SUSPENDED) return -EINVAL; @@ -503,28 +494,27 @@ int panthor_device_resume(struct device *dev) =20 panthor_devfreq_resume(ptdev); =20 - if (panthor_device_is_initialized(ptdev) && - drm_dev_enter(&ptdev->base, &cookie)) { - /* If there was a reset pending at the time we suspended the - * device, we force a slow reset. - */ - if (atomic_read(&ptdev->reset.pending)) { - ptdev->reset.fast =3D false; - atomic_set(&ptdev->reset.pending, 0); - } + if (panthor_device_is_initialized(ptdev)) { + scoped_cond_guard(drm_dev_access, ret =3D 0, &ptdev->base) { + /* If there was a reset pending at the time we suspended the + * device, we force a slow reset. + */ + if (atomic_read(&ptdev->reset.pending)) { + ptdev->reset.fast =3D false; + atomic_set(&ptdev->reset.pending, 0); + } =20 - ret =3D panthor_device_resume_hw_components(ptdev); - if (ret && ptdev->reset.fast) { - drm_err(&ptdev->base, "Fast reset failed, trying a slow reset"); - ptdev->reset.fast =3D false; ret =3D panthor_device_resume_hw_components(ptdev); + if (ret && ptdev->reset.fast) { + drm_err(&ptdev->base, "Fast reset failed, trying a slow reset"); + ptdev->reset.fast =3D false; + ret =3D panthor_device_resume_hw_components(ptdev); + } + + if (!ret) + panthor_sched_resume(ptdev); } =20 - if (!ret) - panthor_sched_resume(ptdev); - - drm_dev_exit(cookie); - if (ret) goto err_suspend_devfreq; } @@ -559,7 +549,6 @@ int panthor_device_resume(struct device *dev) int panthor_device_suspend(struct device *dev) { struct panthor_device *ptdev =3D dev_get_drvdata(dev); - int cookie; =20 if (atomic_read(&ptdev->pm.state) !=3D PANTHOR_DEVICE_PM_STATE_ACTIVE) return -EINVAL; @@ -577,19 +566,19 @@ int panthor_device_suspend(struct device *dev) DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1); } =20 - if (panthor_device_is_initialized(ptdev) && - drm_dev_enter(&ptdev->base, &cookie)) { - cancel_work_sync(&ptdev->reset.work); + if (panthor_device_is_initialized(ptdev)) { + scoped_guard(drm_dev_access, &ptdev->base) { + cancel_work_sync(&ptdev->reset.work); =20 - /* We prepare everything as if we were resetting the GPU. - * The end of the reset will happen in the resume path though. - */ - panthor_sched_suspend(ptdev); - panthor_fw_suspend(ptdev); - panthor_mmu_suspend(ptdev); - panthor_gpu_suspend(ptdev); - panthor_pwr_suspend(ptdev); - drm_dev_exit(cookie); + /* We prepare everything as if we were resetting the GPU. + * The end of the reset will happen in the resume path though. + */ + panthor_sched_suspend(ptdev); + panthor_fw_suspend(ptdev); + panthor_mmu_suspend(ptdev); + panthor_gpu_suspend(ptdev); + panthor_pwr_suspend(ptdev); + } } =20 panthor_devfreq_suspend(ptdev); diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/pantho= r/panthor_drv.c index e8dc4096c1d2..789ddc0ff7ef 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -997,9 +997,10 @@ static int panthor_ioctl_vm_create(struct drm_device *= ddev, void *data, struct panthor_device *ptdev =3D container_of(ddev, struct panthor_device= , base); struct panthor_file *pfile =3D file->driver_priv; struct drm_panthor_vm_create *args =3D data; - int cookie, ret; + int ret; =20 - if (!drm_dev_enter(ddev, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(ddev); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 ret =3D panthor_vm_pool_create_vm(ptdev, pfile->vms, args); @@ -1008,7 +1009,6 @@ static int panthor_ioctl_vm_create(struct drm_device = *ddev, void *data, ret =3D 0; } =20 - drm_dev_exit(cookie); return ret; } =20 @@ -1033,38 +1033,30 @@ static int panthor_ioctl_bo_create(struct drm_devic= e *ddev, void *data, struct panthor_file *pfile =3D file->driver_priv; struct drm_panthor_bo_create *args =3D data; struct panthor_vm *vm =3D NULL; - int cookie, ret; + int ret; =20 - if (!drm_dev_enter(ddev, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(ddev); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 if (!args->size || args->pad || - (args->flags & ~PANTHOR_BO_FLAGS)) { - ret =3D -EINVAL; - goto out_dev_exit; - } + (args->flags & ~PANTHOR_BO_FLAGS)) + return -EINVAL; =20 if ((args->flags & DRM_PANTHOR_BO_NO_MMAP) && - (args->flags & DRM_PANTHOR_BO_WB_MMAP)) { - ret =3D -EINVAL; - goto out_dev_exit; - } + (args->flags & DRM_PANTHOR_BO_WB_MMAP)) + return -EINVAL; =20 if (args->exclusive_vm_id) { vm =3D panthor_vm_pool_get_vm(pfile->vms, args->exclusive_vm_id); - if (!vm) { - ret =3D -EINVAL; - goto out_dev_exit; - } + if (!vm) + return -EINVAL; } =20 ret =3D panthor_gem_create_with_handle(file, ddev, vm, &args->size, args->flags, &args->handle); =20 panthor_vm_put(vm); - -out_dev_exit: - drm_dev_exit(cookie); return ret; } =20 @@ -1107,17 +1099,18 @@ static int panthor_ioctl_group_submit(struct drm_de= vice *ddev, void *data, struct drm_panthor_group_submit *args =3D data; struct drm_panthor_queue_submit *jobs_args; struct panthor_submit_ctx ctx; - int ret =3D 0, cookie; + int ret =3D 0; =20 if (args->pad) return -EINVAL; =20 - if (!drm_dev_enter(ddev, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(ddev); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 ret =3D PANTHOR_UOBJ_GET_ARRAY(jobs_args, &args->queue_submits); if (ret) - goto out_dev_exit; + return ret; =20 ret =3D panthor_submit_ctx_init(&ctx, file, args->queue_submits.count); if (ret) @@ -1201,8 +1194,6 @@ static int panthor_ioctl_group_submit(struct drm_devi= ce *ddev, void *data, out_free_jobs_args: kvfree(jobs_args); =20 -out_dev_exit: - drm_dev_exit(cookie); return ret; } =20 @@ -1438,18 +1429,15 @@ static int panthor_ioctl_vm_bind(struct drm_device = *ddev, void *data, struct drm_file *file) { struct drm_panthor_vm_bind *args =3D data; - int cookie, ret; =20 - if (!drm_dev_enter(ddev, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(ddev); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 if (args->flags & DRM_PANTHOR_VM_BIND_ASYNC) - ret =3D panthor_ioctl_vm_bind_async(ddev, args, file); - else - ret =3D panthor_ioctl_vm_bind_sync(ddev, args, file); + return panthor_ioctl_vm_bind_async(ddev, args, file); =20 - drm_dev_exit(cookie); - return ret; + return panthor_ioctl_vm_bind_sync(ddev, args, file); } =20 static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data, @@ -1671,9 +1659,10 @@ static int panthor_mmap(struct file *filp, struct vm= _area_struct *vma) struct panthor_device *ptdev =3D pfile->ptdev; u64 offset =3D (u64)vma->vm_pgoff << PAGE_SHIFT; u64 user_mmio_offset; - int ret, cookie; + int ret; =20 - if (!drm_dev_enter(file->minor->dev, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(file->minor->dev); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 /* Adjust the user MMIO offset to match the offset used kernel side. @@ -1691,7 +1680,6 @@ static int panthor_mmap(struct file *filp, struct vm_= area_struct *vma) ret =3D drm_gem_mmap(filp, vma); } =20 - drm_dev_exit(cookie); return ret; } =20 diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index ab9a77e6a145..ff3beb9147e8 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -788,13 +788,13 @@ static int panthor_vm_active_locked(struct panthor_vm= *vm) int panthor_vm_active(struct panthor_vm *vm) { struct panthor_device *ptdev =3D vm->ptdev; - int ret =3D 0, cookie; =20 - if (!drm_dev_enter(&ptdev->base, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(&ptdev->base); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return -ENODEV; =20 if (refcount_inc_not_zero(&vm->as.active_cnt)) - goto out_dev_exit; + return 0; =20 /* As soon as active is called, we place the VM at the end of the VM LRU. * If something fails after that, the only downside is that this VM that @@ -809,14 +809,10 @@ int panthor_vm_active(struct panthor_vm *vm) /* Make sure we don't race with lock/unlock_region() calls * happening around VM bind operations. */ - scoped_guard(mutex, &vm->op_lock) { - guard(mutex)(&ptdev->mmu->as.slots_lock); - ret =3D panthor_vm_active_locked(vm); - } + guard(mutex)(&vm->op_lock); + guard(mutex)(&ptdev->mmu->as.slots_lock); =20 -out_dev_exit: - drm_dev_exit(cookie); - return ret; + return panthor_vm_active_locked(vm); } =20 /** @@ -902,16 +898,15 @@ static size_t get_pgsize(u64 addr, size_t size, size_= t *count) static void panthor_vm_declare_unusable(struct panthor_vm *vm) { struct panthor_device *ptdev =3D vm->ptdev; - int cookie; =20 if (vm->unusable) return; =20 vm->unusable =3D true; guard(mutex)(&ptdev->mmu->as.slots_lock); - if (vm->as.id >=3D 0 && drm_dev_enter(&ptdev->base, &cookie)) { - panthor_mmu_as_disable(ptdev, vm->as.id, false); - drm_dev_exit(cookie); + if (vm->as.id >=3D 0) { + scoped_guard(drm_dev_access, &ptdev->base) + panthor_mmu_as_disable(ptdev, vm->as.id, false); } } =20 @@ -1983,12 +1978,8 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) scoped_guard(mutex, &vm->op_lock) { guard(mutex)(&ptdev->mmu->as.slots_lock); if (vm->as.id >=3D 0) { - int cookie; - - if (drm_dev_enter(&ptdev->base, &cookie)) { + scoped_guard(drm_dev_access, &ptdev->base) panthor_mmu_as_disable(ptdev, vm->as.id, false); - drm_dev_exit(cookie); - } =20 ptdev->mmu->as.slots[vm->as.id].vm =3D NULL; clear_bit(vm->as.id, &ptdev->mmu->as.alloc_mask); diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index d8cadd393fbe..9aa9941d2309 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -2624,21 +2624,19 @@ static void tick_work(struct work_struct *work) struct panthor_scheduler *sched =3D container_of(work, struct panthor_sch= eduler, tick_work.work); struct panthor_device *ptdev =3D sched->ptdev; - int ret, cookie; + int ret; =20 - if (!drm_dev_enter(&ptdev->base, &cookie)) + ACQUIRE(drm_dev_access, dev_guard)(&ptdev->base); + if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return; =20 ret =3D panthor_device_resume_and_get(ptdev); if (drm_WARN_ON(&ptdev->base, ret)) - goto out_dev_exit; + return; =20 tick(sched); pm_runtime_mark_last_busy(ptdev->base.dev); pm_runtime_put_autosuspend(ptdev->base.dev); - -out_dev_exit: - drm_dev_exit(cookie); } =20 static int panthor_queue_eval_syncwait(struct panthor_group *group, u8 que= ue_idx) --=20 2.54.0 From nobody Fri Jun 12 17:17:14 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E1214DB561; Wed, 13 May 2026 16:59:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691551; cv=none; b=b/9jBm8xHyiJ8IDaoy5QT+iy7e+lsF0+P1qOzSvbARUsP0+fPLErnfNsw13+wZ8QZyx+NWBhjLQv0FKaI5FEXqSRgfwU6IDWYBPqQBDQPr706/oK18fc33fW8Kz5P8nZFD02V2kx0blHVE6gPvpk0pcdy2Jgz/aJipf2cRgw6Es= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778691551; c=relaxed/simple; bh=5JKcUdxXHvhQCI1LQwFg7UllUAKuTCGb8JFxelc+z4Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r9ie+SInteNzDyvtU/++OpBEIfvh43POjuXaM7JIdtzXhiWq/y/ifUEL4V35I62/A9/pyfxtwF+k79Em/1k4xdspiMwHHr5yH40QhfpRgX+LLnE1CkQcVg6/xPDl31uhxwkX0A/Xlqf/2MPNgzETrb+zU8pO6M+Ou5t7WQ5SMBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=F13wnAN7; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="F13wnAN7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1778691544; bh=5JKcUdxXHvhQCI1LQwFg7UllUAKuTCGb8JFxelc+z4Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=F13wnAN72bQ34z/ls0txawzH+G/Wb1Djs5EMfFi96/xIi2XYvKgjKVjqVs7zRkJZR Xl7gPyTiTxPZGEizMPugx6u55UuG+WJYh6bruOivIVD3nZ6IxELerzqOEzhgUohHFM 7HoZiAFmx5ZGsJf2gaWVAuztoqRBm5SN2vLHjKIszAtK2K5u1zfprTuOeCT3oGr63a MTAYgspn5KCCTqfHgB/Z2EHaq6rW6Kn92cn+7F0MmwA6+zwVymQOyAkxASWpRb9rm1 74k+ngppkOIwj44+XXi0ifUWYoh1ij13sxaVOPh/iYxs2fJcXEZ1fTTtroF1Zj4YiL Ivj90abjzz8Vw== Received: from [192.168.1.38] (unknown [100.64.0.11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bbrezillon) by bali.collaboradmins.com (Postfix) with ESMTPSA id 8631317E38C6; Wed, 13 May 2026 18:59:03 +0200 (CEST) From: Boris Brezillon Date: Wed, 13 May 2026 18:58:54 +0200 Subject: [PATCH 6/6] drm/panthor: Add a new guard for our custom resume_and_get() PM helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260513-panthor-guard-refactor-v1-6-f2d8c15a97ce@collabora.com> References: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> In-Reply-To: <20260513-panthor-guard-refactor-v1-0-f2d8c15a97ce@collabora.com> To: Steven Price , Liviu Dudau Cc: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778691539; l=4385; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=5JKcUdxXHvhQCI1LQwFg7UllUAKuTCGb8JFxelc+z4Y=; b=/j4GD7bj6f01mPZjfZbWJzs8fGUcCv15qaDHQz1LMWFkC6+dttkTiBgbsj9qf1GPiwcmVgTz9 Xsw0wzKTQlNCxJmFMZSmwdxR1WYZ9+kVEd4XWlnUgAspldj2fY9BP+W X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Overload the already existing pm_runtime_active_auto_try_enabled guard with our custom guard that force the state to suspened (and thus clear the runtime_error) in case the resume fails. Once done, we can replace the existing places where manual panthor_device_resume_and_get()+pm_runtime_put_autosuspend() were done by guards. Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_device.h | 10 +++++++--- drivers/gpu/drm/panthor/panthor_drv.c | 4 ++-- drivers/gpu/drm/panthor/panthor_sched.c | 11 ++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/pan= thor/panthor_device.h index 1aaf06df875b..51527d2e2f77 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -407,9 +407,10 @@ int panthor_device_mmap_io(struct panthor_device *ptde= v, int panthor_device_resume(struct device *dev); int panthor_device_suspend(struct device *dev); =20 -static inline int panthor_device_resume_and_get(struct panthor_device *ptd= ev) +static inline int panthor_device_resume_and_get(struct device *dev) { - int ret =3D pm_runtime_resume_and_get(ptdev->base.dev); + struct panthor_device *ptdev =3D dev_get_drvdata(dev); + int ret =3D pm_runtime_resume_and_get(dev); =20 /* If the resume failed, we need to clear the runtime_error, which * can done by forcing the RPM state to suspended. If multiple @@ -424,11 +425,14 @@ static inline int panthor_device_resume_and_get(struc= t panthor_device *ptdev) * something we can live with. */ if (ret && atomic_cmpxchg(&ptdev->pm.recovery_needed, 1, 0) =3D=3D 1) - pm_runtime_set_suspended(ptdev->base.dev); + pm_runtime_set_suspended(dev); =20 return ret; } =20 +DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled_or_suspend, + panthor_device_resume_and_get(_T), _RET =3D=3D 0) + enum drm_panthor_exception_type { DRM_PANTHOR_EXCEPTION_OK =3D 0x00, DRM_PANTHOR_EXCEPTION_TERMINATED =3D 0x04, diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/pantho= r/panthor_drv.c index 789ddc0ff7ef..f2d60ff00896 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -824,7 +824,8 @@ static int panthor_query_timestamp_info(struct panthor_= device *ptdev, (flags & DRM_PANTHOR_TIMESTAMP_DURATION) || (timestamp_types >=3D 2); =20 - ret =3D panthor_device_resume_and_get(ptdev); + ACQUIRE(pm_runtime_active_auto_try_enabled_or_suspend, pm_guard)(ptdev->b= ase.dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_auto_try_enabled_or_suspend, &pm_gu= ard); if (ret) return ret; =20 @@ -894,7 +895,6 @@ static int panthor_query_timestamp_info(struct panthor_= device *ptdev, arg->cpu_timestamp_nsec =3D 0; } =20 - pm_runtime_put(ptdev->base.dev); return 0; } =20 diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 9aa9941d2309..9afa38e87fc9 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -2630,13 +2630,12 @@ static void tick_work(struct work_struct *work) if (ACQUIRE_ERR(drm_dev_access, &dev_guard)) return; =20 - ret =3D panthor_device_resume_and_get(ptdev); + ACQUIRE(pm_runtime_active_auto_try_enabled_or_suspend, pm_guard)(ptdev->b= ase.dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_auto_try_enabled_or_suspend, &pm_gu= ard); if (drm_WARN_ON(&ptdev->base, ret)) return; =20 tick(sched); - pm_runtime_mark_last_busy(ptdev->base.dev); - pm_runtime_put_autosuspend(ptdev->base.dev); } =20 static int panthor_queue_eval_syncwait(struct panthor_group *group, u8 que= ue_idx) @@ -3359,7 +3358,8 @@ queue_run_job(struct drm_sched_job *sched_job) return dma_fence_get(job->done_fence); } =20 - ret =3D panthor_device_resume_and_get(ptdev); + ACQUIRE(pm_runtime_active_auto_try_enabled_or_suspend, pm_guard)(ptdev->b= ase.dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_auto_try_enabled_or_suspend, &pm_gu= ard); if (drm_WARN_ON(&ptdev->base, ret)) return ERR_PTR(ret); =20 @@ -3367,9 +3367,6 @@ queue_run_job(struct drm_sched_job *sched_job) done_fence =3D queue_run_job_locked(job); } =20 - pm_runtime_mark_last_busy(ptdev->base.dev); - pm_runtime_put_autosuspend(ptdev->base.dev); - return done_fence; } =20 --=20 2.54.0