dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Adrián Larumbe" <adrian.larumbe@collabora.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v7 07/17] drm/panfrost: Stop all jobs before commencing device teardown
Date: Fri, 28 Aug 2026 21:16:02 +0000	[thread overview]
Message-ID: <20260828211603.22B2A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260828-claude-fixes-v7-7-72a13b2c125d@collabora.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [Critical] panfrost_stop_jobs() unintentionally commands the hardware to restart pending jobs during device teardown, leading to GPU execution with freed memory and unmapped page tables.
- [High] Jobs aborted during device teardown are never signaled or properly freed, causing a memory leak and permanently hanging userspace waiters.
- [High] Scheduler timeout handler (work_tdr) is not canceled when schedulers are stopped during teardown, allowing a concurrent TDR to resuscitate the device mid-teardown.

Pre-existing issues:
- [High] Concurrent executions of panfrost_reset() from multiple scheduler timeouts corrupt the scheduler pending list.
- [High] Sleeping functions called from DMA fence signalling path during panfrost_reset.
--

commit bbe9e4a95112d42e26f093db1d29071e85c60996
Author: Adrián Larumbe <adrian.larumbe@collabora.com>
Subject: drm/panfrost: Stop all jobs before commencing device teardown

This patch ensures that no jobs are inflight at the time the driver finishes
its structures and synchronizes IRQs. To achieve this, it halts submissions
from existing scheduler entities and forces the hardware to soft-stop all
running jobs during device teardown.

> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
> index 9549ddb7854a3..9e02fb5f73c82 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> @@ -341,6 +341,8 @@ void panfrost_device_fini(struct panfrost_device *pfdev)
>  	pm_runtime_get_sync(pfdev->base.dev);
>  	pm_runtime_disable(pfdev->base.dev);
>  
> +	panfrost_jm_stop_sched_jobs(pfdev);
> +

[Severity: High]
Does this code leak the job structures and GEM references while permanently
hanging userspace waiters?

This adds a call to soft-stop inflight jobs during device teardown without
providing a mechanism to signal their fences. The interrupt handler skips
signaling the fence for soft-stopped jobs (signal_fence = false), expecting
a reset. Stuck jobs are erased from driver state via memset, but panfrost
does not implement the cancel_job callback in drm_sched_backend_ops.

Since they are abandoned on the scheduler's pending_list without being freed
or having their fences signaled, any teardown of the device while jobs are
in flight will trigger this leak and hang.

>  	panfrost_gem_fini(pfdev);
>  	panfrost_perfcnt_fini(pfdev);

[ ... ]

> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
> index 5016d2d53da26..630298b7ea8a5 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c

[ ... ]

> +void panfrost_jm_stop_sched_jobs(struct panfrost_device *pfdev)
> +{
> +	for (u32 i = 0; i < NUM_JOB_SLOTS; i++)
> +		drm_sched_wqueue_stop(&pfdev->js->queue[i].sched);
> +

[Severity: High]
Does this create a race window where the timeout handler can execute
concurrently mid-teardown?

The stop logic uses drm_sched_wqueue_stop() which pauses submit queues, but
fails to cancel the delayed timeout work (work_tdr). If the timeout expires
before teardown reaches panfrost_jm_fini(), panfrost_job_timedout() executes
concurrently and triggers a GPU reset. The reset sequence unconditionally
invokes drm_sched_start() and re-enables hardware interrupts, forcing the
GPU and schedulers to resume execution while panfrost_device_fini() destroys
underlying memory and structures.

> +	panfrost_stop_jobs(pfdev);
> +}
> +

[Severity: Critical]
Does panfrost_stop_jobs() unintentionally command the hardware to restart
pending jobs during device teardown?

This new teardown function reuses the reset path's soft-stop mechanism
without setting reset.pending. During teardown, the resulting IRQ is handled
by panfrost_jm_handle_irq(). Because this is a teardown and not a GPU reset,
pfdev->reset.pending is 0. 

The handler logic unconditionally sees !atomic_read(&pfdev->reset.pending)
and writes JS_COMMAND_START to launch the next queued job. The GPU hardware
resumes executing jobs while panfrost_device_fini() concurrently frees all
backing structures, leading to GPU execution with freed memory and unmapped
page tables.

> +static void
> +panfrost_reset(struct panfrost_device *pfdev,
> +	       struct drm_sched_job *bad)
> +{
> +	unsigned int i;
> +	bool cookie;
> +
> +	if (!atomic_read(&pfdev->reset.pending))
> +		return;
> +
> +	/* Stop the schedulers.
> +	 *
> +	 * FIXME: We temporarily get out of the dma_fence_signalling section
> +	 * because the cleanup path generate lockdep splats when taking locks
> +	 * to release job resources. We should rework the code to follow this
> +	 * pattern:
> +	 *
> +	 *	try_lock
> +	 *	if (locked)
> +	 *		release
> +	 *	else
> +	 *		schedule_work_to_release_later
> +	 */
> +	for (i = 0; i < NUM_JOB_SLOTS; i++)
> +		drm_sched_stop(&pfdev->js->queue[i].sched, bad);
> +

[Severity: High]
This is a pre-existing issue, but can concurrent executions of
panfrost_reset() from multiple scheduler timeouts corrupt the scheduler
pending list?

Panfrost uses multiple independent DRM schedulers (one per job slot). If
multiple slots timeout simultaneously (e.g. due to a global GPU hang),
multiple work_tdr works fire concurrently. They enter panfrost_job_timedout()
which calls atomic_set(&pfdev->reset.pending, 1) rather than an atomic
exchange.

Both threads bypass the !atomic_read() exclusion check here and concurrently
invoke drm_sched_stop(). Since drm_sched_stop() manipulates
sched->pending_list without internal locks for list_add, the concurrent
modifications corrupt the list.

> +	cookie = dma_fence_begin_signalling();
> +
> +	if (bad)
> +		drm_sched_increase_karma(bad);
> +
> +	panfrost_stop_jobs(pfdev);

[Severity: High]
This isn't a bug introduced by this patch (the code was simply refactored
into a helper), but does this invoke sleeping functions from the DMA fence
signalling path?

dma_fence_begin_signalling() enters a critical section where sleeping is
strictly forbidden. Immediately afterward, panfrost_stop_jobs() is called,
which invokes synchronize_irq() (which can block waiting for IRQ handlers)
and readl_poll_timeout() (which sleeps via usleep_range()).

>  
>  	/* Proceed with reset now. */
>  	panfrost_device_reset(pfdev, false);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260828-claude-fixes-v7-0-72a13b2c125d@collabora.com?part=7

  reply	other threads:[~2026-08-28 21:16 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-28 20:56 [PATCH v7 00/17] Collection of fixes for Panfrost: Perfcnt, RPM, refactorings Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 01/17] drm/panfrost: Move shrinker initialization and unplug one level down Adrián Larumbe
2026-09-01 11:28   ` Boris Brezillon
2026-09-02 15:36     ` Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 02/17] drm/panfrost: Move all DRM device initialisation into device_init() Adrián Larumbe
2026-09-01 11:49   ` Boris Brezillon
2026-09-02 15:38     ` Adrián Larumbe
2026-09-02 15:50       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 03/17] drm/panfrost: Move lock and modparam initialisations into their subsystems Adrián Larumbe
2026-08-28 21:14   ` sashiko-bot
2026-09-01 12:10   ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 04/17] drm/panfrost: Move debugfs initialisation to relevant subsystems Adrián Larumbe
2026-09-01 12:30   ` Boris Brezillon
2026-09-02 15:40     ` Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 05/17] drm/panfrost: Skip NULL checks for clock enable/disabling Adrián Larumbe
2026-09-01 12:31   ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 06/17] drm/panfrost: Consolidate device clock management and reset Adrián Larumbe
2026-09-01 12:38   ` Boris Brezillon
2026-09-02 15:41     ` Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 07/17] drm/panfrost: Stop all jobs before commencing device teardown Adrián Larumbe
2026-08-28 21:16   ` sashiko-bot [this message]
2026-09-01 12:58   ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 08/17] drm/panfrost: Split subsystem init/reset from interrupt enablement Adrián Larumbe
2026-08-28 21:11   ` sashiko-bot
2026-09-01 13:08   ` Boris Brezillon
2026-09-02 15:41     ` Adrián Larumbe
2026-09-02 16:05       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 09/17] drm/panfrost: Fix PM refcnt and autosuspend issues at device probe/remove Adrián Larumbe
2026-08-28 21:09   ` sashiko-bot
2026-09-01 13:18   ` Boris Brezillon
2026-09-02 15:42     ` Adrián Larumbe
2026-09-02 16:14       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 10/17] drm/panfrost: Add warning messages to fatal error conditions Adrián Larumbe
2026-08-28 21:10   ` sashiko-bot
2026-09-01 13:20   ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 11/17] drm/panfrost: Add debugfs knob for manually triggering a GPU reset Adrián Larumbe
2026-08-28 21:12   ` sashiko-bot
2026-09-01 13:27   ` Boris Brezillon
2026-09-02 15:42     ` Adrián Larumbe
2026-09-02 16:23       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 12/17] drm/panfrost: Move perfcnt GPU disable sequence into a helper Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 13/17] drm/panfrost: Skip cache flush/invalidate when enabling perfcnt Adrián Larumbe
2026-09-01 13:32   ` Boris Brezillon
2026-09-02 15:43     ` Adrián Larumbe
2026-09-02 16:29       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 14/17] drm/panfrost: Avoid cache flush after perfcnt sample in fully coherent systems Adrián Larumbe
2026-08-28 21:14   ` sashiko-bot
2026-09-01 13:37   ` Boris Brezillon
2026-09-02 15:44     ` Adrián Larumbe
2026-09-02 16:33       ` Boris Brezillon
2026-09-02 16:34   ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 15/17] drm/panfrost: Introduce a reset lock Adrián Larumbe
2026-08-28 20:56 ` [PATCH v7 16/17] drm/panfrost: Fix races between perfcnt and reset sequence Adrián Larumbe
2026-08-28 21:17   ` sashiko-bot
2026-09-01 14:03   ` Boris Brezillon
2026-09-02 15:45     ` Adrián Larumbe
2026-09-02 16:51       ` Boris Brezillon
2026-08-28 20:56 ` [PATCH v7 17/17] drm/panfrost: Bump driver minor to reflect new DUMP IOCTL req field Adrián 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=20260828211603.22B2A1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=adrian.larumbe@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox