All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Larumbe <adrian.larumbe@collabora.com>
To: Boris Brezillon <boris.brezillon@collabora.com>
Cc: Steven Price <steven.price@arm.com>,
	Liviu Dudau <liviu.dudau@arm.com>,
	 Chris Diamand <chris.diamand@arm.com>,
	Akash Goel <akash.goel@arm.com>,
	 Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	 Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>,
	 Simona Vetter <simona@ffwll.ch>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 03/18] drm/panthor: Make panthor_device::pm::state non-atomic
Date: Thu, 10 Sep 2026 02:13:43 +0100	[thread overview]
Message-ID: <aqGEW6o3aelM_tX8@sobremesa> (raw)
In-Reply-To: <20260826-panthor-unplug-fixes-v4-3-982cc8f4234b@collabora.com>

On 26.08.2026 16:56, Boris Brezillon wrote:
> Now that the reset logic has been reworked to use disable/enable_work(),
> there's no need for panthor_device::pm::state to be an atomic. It can
> simply be accessed under the same lock we use to touch MMIO mappings.
> 
> While at it, rename the lock to make it clear it protects more than just
> the MMIO logic, and transition locked sections to scoped_guard().
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/gpu/drm/panthor/panthor_device.c | 97 +++++++++++++++++---------------
>  drivers/gpu/drm/panthor/panthor_device.h | 16 ++++--
>  2 files changed, 63 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
> index 2974f4bc0bb1..133e3895cd0a 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.c
> +++ b/drivers/gpu/drm/panthor/panthor_device.c
> @@ -147,8 +147,10 @@ static void panthor_device_reset_work(struct work_struct *work)
>  	/* If the device is entering suspend, we don't reset. A slow reset will
>  	 * be forced at resume time instead.
>  	 */
> -	if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE)
> -		return;
> +	scoped_guard(mutex, &ptdev->pm.lock) {
> +		if (ptdev->pm.state != PANTHOR_DEVICE_PM_STATE_ACTIVE)
> +			return;
> +	}
>  
>  	if (!drm_dev_enter(&ptdev->base, &cookie))
>  		return;
> @@ -204,7 +206,7 @@ int panthor_device_init(struct panthor_device *ptdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = drmm_mutex_init(&ptdev->base, &ptdev->pm.mmio_lock);
> +	ret = drmm_mutex_init(&ptdev->base, &ptdev->pm.lock);
>  	if (ret)
>  		return ret;
>  
> @@ -213,7 +215,7 @@ int panthor_device_init(struct panthor_device *ptdev)
>  	INIT_LIST_HEAD(&ptdev->gems.node);
>  #endif
>  
> -	atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED);
> +	ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_SUSPENDED;
>  	p = alloc_page(GFP_KERNEL | __GFP_ZERO);
>  	if (!p)
>  		return -ENOMEM;
> @@ -432,40 +434,39 @@ static vm_fault_t panthor_mmio_vm_fault(struct vm_fault *vmf)
>  {
>  	struct vm_area_struct *vma = vmf->vma;
>  	struct panthor_device *ptdev = vma->vm_private_data;
> -	u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
> -	unsigned long pfn;
> -	pgprot_t pgprot;
>  	vm_fault_t ret;
> -	bool active;
>  	int cookie;
>  
>  	if (!drm_dev_enter(&ptdev->base, &cookie))
>  		return VM_FAULT_SIGBUS;
>  
> -	mutex_lock(&ptdev->pm.mmio_lock);
> -	active = atomic_read(&ptdev->pm.state) == PANTHOR_DEVICE_PM_STATE_ACTIVE;
> +	scoped_guard(mutex, &ptdev->pm.lock) {
> +		bool active = ptdev->pm.state == PANTHOR_DEVICE_PM_STATE_ACTIVE;
> +		u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
> +		unsigned long pfn;
> +		pgprot_t pgprot;
>  
> -	switch (offset) {
> -	case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
> +		switch (offset) {
> +		case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
> +			if (active)
> +				pfn = __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID);
> +			else
> +				pfn = page_to_pfn(ptdev->pm.dummy_latest_flush);
> +			break;
> +
> +		default:
> +			ret = VM_FAULT_SIGBUS;
> +			goto out_dev_exit;
> +		}
> +
> +		pgprot = vma->vm_page_prot;
>  		if (active)
> -			pfn = __phys_to_pfn(ptdev->phys_addr + CSF_GPU_LATEST_FLUSH_ID);
> -		else
> -			pfn = page_to_pfn(ptdev->pm.dummy_latest_flush);
> -		break;
> +			pgprot = pgprot_noncached(pgprot);
>  
> -	default:
> -		ret = VM_FAULT_SIGBUS;
> -		goto out_unlock;
> +		ret = vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot);
>  	}
>  
> -	pgprot = vma->vm_page_prot;
> -	if (active)
> -		pgprot = pgprot_noncached(pgprot);
> -
> -	ret = vmf_insert_pfn_prot(vma, vmf->address, pfn, pgprot);
> -
> -out_unlock:
> -	mutex_unlock(&ptdev->pm.mmio_lock);
> +out_dev_exit:
>  	drm_dev_exit(cookie);
>  	return ret;
>  }
> @@ -526,10 +527,13 @@ int panthor_device_resume(struct device *dev)
>  	struct panthor_device *ptdev = dev_get_drvdata(dev);
>  	int ret, cookie;
>  
> -	if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_SUSPENDED)
> -		return -EINVAL;
> +	scoped_guard(mutex, &ptdev->pm.lock) {
> +		if (ptdev->pm.state != PANTHOR_DEVICE_PM_STATE_SUSPENDED)
> +			return -EINVAL;
> +
> +		ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_RESUMING;
> +	}
>  
> -	atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_RESUMING);
>  
>  	ret = clk_prepare_enable(ptdev->clks.core);
>  	if (ret)
> @@ -574,11 +578,11 @@ 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);
> +	mutex_lock(&ptdev->pm.lock);

Maybe you could replace it with scoped_guard(mutex, &ptdev->pm.lock) {}
like you've done in other parts of the commit.

Other than that:

Reviewed-by: Adrián Larumbe <adrian.larumbe@collabora.com>

>  	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);
> +	ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_ACTIVE;
> +	mutex_unlock(&ptdev->pm.lock);
>  
>  	/* Now that everything is resumed, we can re-enable the reset work. */
>  	enable_resets(ptdev);
> @@ -595,7 +599,9 @@ int panthor_device_resume(struct device *dev)
>  	clk_disable_unprepare(ptdev->clks.core);
>  
>  err_set_suspended:
> -	atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED);
> +	scoped_guard(mutex, &ptdev->pm.lock)
> +		ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_SUSPENDED;
> +
>  	atomic_set(&ptdev->pm.recovery_needed, 1);
>  	return ret;
>  }
> @@ -605,21 +611,21 @@ int panthor_device_suspend(struct device *dev)
>  	struct panthor_device *ptdev = dev_get_drvdata(dev);
>  	int cookie;
>  
> -	if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE)
> -		return -EINVAL;
> -
>  	/* Clear all IOMEM mappings pointing to this device before we
>  	 * shutdown the power-domain and clocks. Failing to do that results
>  	 * in external aborts when the process accesses the iomem region.
>  	 * We change the state and call unmap_mapping_range() with the
> -	 * mmio_lock held to make sure the vm_fault handler won't set up
> +	 * 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.lock) {
> +		if (ptdev->pm.state != PANTHOR_DEVICE_PM_STATE_ACTIVE)
> +			return -EINVAL;
> +
> +		ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_SUSPENDING;
> +		unmap_mapping_range(ptdev->base.anon_inode->i_mapping,
> +				    DRM_PANTHOR_USER_MMIO_OFFSET, 0, 1);
> +	}
>  
>  	/* Make sure we're not interrupted by resets after that point
>  	 * until the GPU is resumed.
> @@ -644,6 +650,9 @@ int panthor_device_suspend(struct device *dev)
>  	clk_disable_unprepare(ptdev->clks.coregroup);
>  	clk_disable_unprepare(ptdev->clks.stacks);
>  	clk_disable_unprepare(ptdev->clks.core);
> -	atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED);
> +
> +	scoped_guard(mutex, &ptdev->pm.lock)
> +		ptdev->pm.state = PANTHOR_DEVICE_PM_STATE_SUSPENDED;
> +
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
> index f55baa21b25e..217eec811bdb 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.h
> +++ b/drivers/gpu/drm/panthor/panthor_device.h
> @@ -298,18 +298,22 @@ struct panthor_device {
>  
>  	/** @pm: Power management related data. */
>  	struct {
> -		/** @state: Power state. */
> -		atomic_t state;
> +		/**
> +		 * @state: Power state.
> +		 *
> +		 * Must be accessed with the panthor_device::pm::lock held.
> +		 */
> +		enum panthor_device_pm_state state;
>  
>  		/**
> -		 * @mmio_lock: Lock protecting MMIO userspace CPU mappings.
> +		 * @lock: Lock protecting PM related fields.
>  		 *
>  		 * This is needed to ensure we map the dummy IO pages when
>  		 * the device is being suspended, and the real IO pages when
> -		 * the device is being resumed. We can't just do with the
> -		 * state atomicity to deal with this race.
> +		 * the device is being resumed. We can't just do with an
> +		 * atomic state to deal with this race.
>  		 */
> -		struct mutex mmio_lock;
> +		struct mutex lock;
>  
>  		/**
>  		 * @dummy_latest_flush: Dummy LATEST_FLUSH page.
> 
> -- 
> 2.55.0


Adrian Larumbe

  parent reply	other threads:[~2026-09-10  1:13 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 14:55 [PATCH v4 00/18] drm/panthor: Fix the unplug logic Boris Brezillon
2026-08-26 14:56 ` [PATCH v4 01/18] drm/panthor: Disable reset work before unplug Boris Brezillon
2026-08-27 13:00   ` Liviu Dudau
2026-09-10  1:12   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 02/18] drm/panthor: Revisit the reset logic to avoid reset request loss Boris Brezillon
2026-08-27 15:04   ` Liviu Dudau
2026-09-10  1:13   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 03/18] drm/panthor: Make panthor_device::pm::state non-atomic Boris Brezillon
2026-08-27 15:12   ` Liviu Dudau
2026-09-10  1:13   ` Adrian Larumbe [this message]
2026-08-26 14:56 ` [PATCH v4 04/18] drm/panthor: Flush the cleanup_wq in the unplug path Boris Brezillon
2026-08-27 15:14   ` Liviu Dudau
2026-09-10  1:14   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 05/18] drm/panthor: Make the page table cache and cleanup workqueue device-local Boris Brezillon
2026-08-27 15:20   ` Liviu Dudau
2026-09-10  1:14   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 06/18] drm/panthor: Drop unused vm argument passed to panthor_vm_prepare_sync_only_op_ctx() Boris Brezillon
2026-08-27 15:21   ` Liviu Dudau
2026-09-10  1:15   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 07/18] drm/panthor: Move the debugfs initialization to panthor_device.c Boris Brezillon
2026-09-10  1:18   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 08/18] drm/panthor: Split panthor_vm Boris Brezillon
2026-09-11  3:37   ` Adrian Larumbe
2026-09-11  9:48     ` Boris Brezillon
2026-09-11 22:55   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 09/18] drm/panthor: Add fine-grained restrictions on VMs Boris Brezillon
2026-09-11  3:38   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 10/18] drm/panthor: Check AS state before disabling Boris Brezillon
2026-09-11  3:38   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 11/18] drm/panthor: Don't pre-allocate VMAs or page tables when preparing a full VM unmap Boris Brezillon
2026-09-11  3:38   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 12/18] drm/panthor: Let l2_power_off return errors and force users to check it Boris Brezillon
2026-09-11  3:39   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 13/18] drm/panthor: Complain if the SOFT_RESET fails Boris Brezillon
2026-09-11  3:40   ` Adrian Larumbe
2026-09-11  9:54     ` Boris Brezillon
2026-08-26 14:56 ` [PATCH v4 14/18] drm/panthor: Make the VM cleanup path more robust against UAF Boris Brezillon
2026-09-11 19:15   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 15/18] drm/panthor: Track user owned VMs Boris Brezillon
2026-09-11 19:17   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 16/18] drm/panthor: Track user owned groups Boris Brezillon
2026-09-11 19:17   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 17/18] drm/panthor: Fix the unplug logic Boris Brezillon
2026-09-11 22:44   ` Adrian Larumbe
2026-08-26 14:56 ` [PATCH v4 18/18] drm/panthor: Add debugfs knobs to simulate reset failures Boris Brezillon
2026-09-11 19:18   ` Adrian Larumbe
2026-09-12 19:27   ` Adrian Larumbe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aqGEW6o3aelM_tX8@sobremesa \
    --to=adrian.larumbe@collabora.com \
    --cc=airlied@gmail.com \
    --cc=akash.goel@arm.com \
    --cc=boris.brezillon@collabora.com \
    --cc=chris.diamand@arm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liviu.dudau@arm.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=steven.price@arm.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.