From nobody Mon Sep 28 07:19:42 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 EA06A3314AC for ; Tue, 25 Aug 2026 08:01:38 +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=1787644900; cv=none; b=na5uaeIk45MfwtRSeq+mMErVDw0+HCDWdDAzBhGUgg/u0Q+IJ3G6anPfxt3L70+hwfwYoou4SL1Xz1M+mctzHjRF1K6OmkHydx8SKfxhEgs0L0S0d41WB3ms5snsI3tvGbArl/PF+mUk83K5xRX7SJIN2Ut1Qk3ziMMh6rNJb28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644900; c=relaxed/simple; bh=AwbS6+2vfVG/4d48RPtiD/bosa/LCN6GhZ3XG0FQWK8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SV8DBCMHTt4PCNWkF+RvWnxZvpb7XbEt2AFl6MxM2u2yUw9U7ALv9TPONHe1if+DoaNNXHifdWimi0YcVzch2y8msUXetnV67M6FnUZew7WJD7XE1V7fIaHcsBOSrOGIwsVll2TUU/9OEaXktFka2oDfq8EjimPGnICXIcU2iM8= 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=ntPrqBTH; 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="ntPrqBTH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644890; bh=AwbS6+2vfVG/4d48RPtiD/bosa/LCN6GhZ3XG0FQWK8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ntPrqBTHpffIMnHxht7sHbLBZOwl+xmh0bUQg2TR9EIxXDGagaQyp15ojtly7SCK+ NCZ1niS+pO2RuYKjfFAPoCc3LHsqdPdxBmrxiZJh8SvvRmMOuuxL9QXjFNu3oRS7u1 s4BVJ5RVLJUFsyIFBE9Q0kSQjf/DFUSx1uAk1C8XAl6E6FhVtf67tNi1EUuEZsXWVN OEsgY3bspIqC8GtVZ1BGzBJ60gHu19dEWGaKqnl0aLFY9V965iSZQZkckAYuWqZEO1 KNeOZw/xVC3IfIZa7dJ+f45oCdtescbWrTD5Z3ySFZ8FyFcgirmeCDn296vwmMxeH5 G9WzaJylDQ65g== Received: from fedora-32.home (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 4B81517E089D; Tue, 25 Aug 2026 10:01:30 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:22 +0200 Subject: [PATCH v7 1/9] drm/panthor: Make panthor_irq::state a non-atomic field 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: <20260825-panthor-signal-from-irq-v7-1-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=7250; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=AwbS6+2vfVG/4d48RPtiD/bosa/LCN6GhZ3XG0FQWK8=; b=TgIEmQ6J4INnlWcRo+1+ImLkG5ABC3mcDwjA/IuOLTRduQI2GusendNOGamXQrfHSS3BOnndR 4qmkq1E3Z58AVForGtmDdjs+GJAL6hfnh6GZigUCW24epqiCFcBBRpX X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= The only place where panthor_irq::state is accessed without panthor_irq::mask_lock held is in the prologue of _irq_suspend(), which is not really a fast-path. So let's simplify things by assuming panthor_irq::state must always be accessed with the mask_lock held, and add a scoped_guard() in _irq_suspend(). While at it, rename the lock so it's clear it doesn't just protect access to the panthor_irq::mask or the INT_MASK register. Reviewed-by: Steven Price Reviewed-by: Liviu Dudau Reviewed-by: Chia-I Wu Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_device.h | 61 +++++++++++++++-------------= ---- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/pan= thor/panthor_device.h index 0fda64fbe5f2..4e5f7b0fb53f 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -92,17 +92,21 @@ struct panthor_irq { u32 mask; =20 /** - * @mask_lock: protects modifications to _INT_MASK and @mask. + * @lock: protects modifications to _INT_MASK, @mask and @state. * * In paths where _INT_MASK is updated based on a state * transition/check, it's crucial for the state update/check to be * inside the locked section, otherwise it introduces a race window * leading to potential _INT_MASK inconsistencies. */ - spinlock_t mask_lock; + spinlock_t lock; =20 - /** @state: one of &enum panthor_irq_state reflecting the current state. = */ - atomic_t state; + /** + * @state: one of &enum panthor_irq_state reflecting the current state. + * + * Must be accessed with lock held. + */ + enum panthor_irq_state state; }; =20 /** @@ -510,22 +514,15 @@ const char *panthor_exception_name(struct panthor_dev= ice *ptdev, static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *d= ata) \ { \ struct panthor_irq *pirq =3D data; \ - enum panthor_irq_state old_state; \ \ - guard(spinlock_irqsave)(&pirq->mask_lock); \ - old_state =3D atomic_cmpxchg(&pirq->state, \ - PANTHOR_IRQ_STATE_ACTIVE, \ - PANTHOR_IRQ_STATE_PROCESSING); \ - if (old_state !=3D PANTHOR_IRQ_STATE_ACTIVE) \ + guard(spinlock_irqsave)(&pirq->lock); \ + if (pirq->state !=3D PANTHOR_IRQ_STATE_ACTIVE) \ return IRQ_NONE; \ \ - if (!gpu_read(pirq->iomem, INT_STAT)) { \ - atomic_cmpxchg(&pirq->state, \ - PANTHOR_IRQ_STATE_PROCESSING, \ - PANTHOR_IRQ_STATE_ACTIVE); \ + if (!gpu_read(pirq->iomem, INT_STAT)) \ return IRQ_NONE; \ - } \ \ + pirq->state =3D PANTHOR_IRQ_STATE_PROCESSING; \ gpu_write(pirq->iomem, INT_MASK, 0); \ return IRQ_WAKE_THREAD; \ } \ @@ -554,14 +551,11 @@ static irqreturn_t panthor_ ## __name ## _irq_threade= d_handler(int irq, void *da ret =3D IRQ_HANDLED; \ } \ \ - scoped_guard(spinlock_irqsave, &pirq->mask_lock) { \ - enum panthor_irq_state old_state; \ - \ - old_state =3D atomic_cmpxchg(&pirq->state, \ - PANTHOR_IRQ_STATE_PROCESSING, \ - PANTHOR_IRQ_STATE_ACTIVE); \ - if (old_state =3D=3D PANTHOR_IRQ_STATE_PROCESSING) \ + scoped_guard(spinlock_irqsave, &pirq->lock) { \ + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_PROCESSING) { \ + pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; \ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ + } \ } \ \ return ret; \ @@ -569,19 +563,20 @@ static irqreturn_t panthor_ ## __name ## _irq_threade= d_handler(int irq, void *da \ static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *= pirq) \ { \ - scoped_guard(spinlock_irqsave, &pirq->mask_lock) { \ - atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDING); \ + scoped_guard(spinlock_irqsave, &pirq->lock) { \ + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDING; \ gpu_write(pirq->iomem, INT_MASK, 0); \ } \ synchronize_irq(pirq->irq); \ - atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \ + scoped_guard(spinlock_irqsave, &pirq->lock) \ + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; \ } \ \ static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *p= irq) \ { \ - guard(spinlock_irqsave)(&pirq->mask_lock); \ + guard(spinlock_irqsave)(&pirq->lock); \ \ - atomic_set(&pirq->state, PANTHOR_IRQ_STATE_ACTIVE); \ + pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; \ gpu_write(pirq->iomem, INT_CLEAR, pirq->mask); \ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ } \ @@ -594,8 +589,8 @@ static int panthor_request_ ## __name ## _irq(struct pa= nthor_device *ptdev, \ pirq->irq =3D irq; \ pirq->mask =3D 0; \ pirq->iomem =3D iomem; \ - spin_lock_init(&pirq->mask_lock); \ - atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \ + spin_lock_init(&pirq->lock); \ + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; \ gpu_write(pirq->iomem, INT_MASK, 0); \ \ return devm_request_threaded_irq(ptdev->base.dev, irq, \ @@ -607,7 +602,7 @@ static int panthor_request_ ## __name ## _irq(struct pa= nthor_device *ptdev, \ \ static inline void panthor_ ## __name ## _irq_enable_events(struct panthor= _irq *pirq, u32 mask) \ { \ - guard(spinlock_irqsave)(&pirq->mask_lock); \ + guard(spinlock_irqsave)(&pirq->lock); \ pirq->mask |=3D mask; \ \ /* The only situation where we need to write the new mask is if the IRQ i= s active. \ @@ -615,13 +610,13 @@ static inline void panthor_ ## __name ## _irq_enable_= events(struct panthor_irq * * on the PROCESSING -> ACTIVE transition. \ * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. \ */ \ - if (atomic_read(&pirq->state) =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ } \ \ static inline void panthor_ ## __name ## _irq_disable_events(struct pantho= r_irq *pirq, u32 mask)\ { \ - guard(spinlock_irqsave)(&pirq->mask_lock); \ + guard(spinlock_irqsave)(&pirq->lock); \ pirq->mask &=3D ~mask; \ \ /* The only situation where we need to write the new mask is if the IRQ i= s active. \ @@ -629,7 +624,7 @@ static inline void panthor_ ## __name ## _irq_disable_e= vents(struct panthor_irq * on the PROCESSING -> ACTIVE transition. \ * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. \ */ \ - if (atomic_read(&pirq->state) =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ } =20 --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 E2A2F2DB798 for ; Tue, 25 Aug 2026 08:01:38 +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=1787644900; cv=none; b=QkymszN+kEwv6Mn3/Bk8Zz7/H74vgYs6akopgvXHmzs59nxoEhq3dEK/eARSPl9SgMY+3L7iwNq38JktQ4m9g/79gIaKJYPj3ET+8Snn0AJTETMWF1cDdp/OU3wf+3mqCjaHRZsNgLNQy48WH3L7vD0xAARV6FFwGWc+W1l05Yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644900; c=relaxed/simple; bh=3TNOGAvccl1TNM4QLXC4SAQP/XgcNL1NcuiVhIv6acY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dwYiQOeoV819UHDIT4rdwjE/fmXqFQM/79ImBKz4tH/uHVa3x9LlflBk2vMX+Y7iCZJcskcAy3QzpykgOY8/mafzxtY9wKc2aRVxvUnyzhzEtDVEwDrhxOIbEiiKazUlNUKmXfl3bm6B6jwRxxBUmePCmOpcksCHgi1BKEPuT24= 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=jqjEExv1; 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="jqjEExv1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644891; bh=3TNOGAvccl1TNM4QLXC4SAQP/XgcNL1NcuiVhIv6acY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jqjEExv1yRgbzcqmG3c6mTwpDjpjt9+MCqI/N7wrxpN3FX2Ih7geQugjgvYaGADoG /dQ9a/n8S/yf0DxzRW+gHUGvqy5ZCZr9WYSmCLEl2vxN8x8+QRNFBWVeiqcXuDExsU t9W05MufbAv41WhD+frIjfao565B5sIaokWhFmd2gt3WjxgA+/kKezKnT7+l09Fxf0 dI4em34JYfq8dglgqmBpKZTcMJtTkNB4zAKCWug0z+YevvzcnqKHN+6xj08bB/rdbU k4naWUbMyoAJdj+k8JuqeGC1u0lljSk+l2Ge/4hLGy+AW3JS8uYNI5oHkYD0I/TJQZ G3xDKUnOivhAA== Received: from fedora-32.home (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 D388617E0A44; Tue, 25 Aug 2026 10:01:30 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:23 +0200 Subject: [PATCH v7 2/9] drm/panthor: Move the register accessors before the IRQ helpers 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: <20260825-panthor-signal-from-irq-v7-2-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=5742; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=3TNOGAvccl1TNM4QLXC4SAQP/XgcNL1NcuiVhIv6acY=; b=cOqPPUrWWQeam95HTNZ50Oj9j0jB/5K8eMsprxS451xd44L6/vwk2DHZEX+k8hR9FtssNZbAV S82w9X0KawjDK6NrAjla7NWVSr10SPXptxfo7jVAIGHe6RIgwR6oPag X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= We're about to add an IRQ inline helper using gpu_read(). Move things around to avoid forward declarations. No functional changes. Reviewed-by: Steven Price Reviewed-by: Liviu Dudau Reviewed-by: Chia-I Wu Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_device.h | 142 +++++++++++++++------------= ---- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/pan= thor/panthor_device.h index 4e5f7b0fb53f..b102ea77fd1a 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -495,6 +495,77 @@ panthor_exception_is_fault(u32 exception_code) const char *panthor_exception_name(struct panthor_device *ptdev, u32 exception_code); =20 +static inline void gpu_write(void __iomem *iomem, u32 reg, u32 data) +{ + writel(data, iomem + reg); +} + +static inline u32 gpu_read(void __iomem *iomem, u32 reg) +{ + return readl(iomem + reg); +} + +static inline u32 gpu_read_relaxed(void __iomem *iomem, u32 reg) +{ + return readl_relaxed(iomem + reg); +} + +static inline void gpu_write64(void __iomem *iomem, u32 reg, u64 data) +{ + gpu_write(iomem, reg, lower_32_bits(data)); + gpu_write(iomem, reg + 4, upper_32_bits(data)); +} + +static inline u64 gpu_read64(void __iomem *iomem, u32 reg) +{ + return (gpu_read(iomem, reg) | ((u64)gpu_read(iomem, reg + 4) << 32)); +} + +static inline u64 gpu_read64_relaxed(void __iomem *iomem, u32 reg) +{ + return (gpu_read_relaxed(iomem, reg) | + ((u64)gpu_read_relaxed(iomem, reg + 4) << 32)); +} + +static inline u64 gpu_read64_counter(void __iomem *iomem, u32 reg) +{ + u32 lo, hi1, hi2; + do { + hi1 =3D gpu_read(iomem, reg + 4); + lo =3D gpu_read(iomem, reg); + hi2 =3D gpu_read(iomem, reg + 4); + } while (hi1 !=3D hi2); + return lo | ((u64)hi2 << 32); +} + +#define gpu_read_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us)= \ + read_poll_timeout(gpu_read, val, cond, delay_us, timeout_us, false, \ + iomem, reg) + +#define gpu_read_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \ + timeout_us) \ + read_poll_timeout_atomic(gpu_read, val, cond, delay_us, timeout_us, \ + false, iomem, reg) + +#define gpu_read64_poll_timeout(iomem, reg, val, cond, delay_us, timeout_u= s) \ + read_poll_timeout(gpu_read64, val, cond, delay_us, timeout_us, false, \ + iomem, reg) + +#define gpu_read64_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \ + timeout_us) \ + read_poll_timeout_atomic(gpu_read64, val, cond, delay_us, timeout_us, \ + false, iomem, reg) + +#define gpu_read_relaxed_poll_timeout_atomic(iomem, reg, val, cond, delay_= us, \ + timeout_us) \ + read_poll_timeout_atomic(gpu_read_relaxed, val, cond, delay_us, \ + timeout_us, false, iomem, reg) + +#define gpu_read64_relaxed_poll_timeout(iomem, reg, val, cond, delay_us, \ + timeout_us) \ + read_poll_timeout(gpu_read64_relaxed, val, cond, delay_us, timeout_us, \ + false, iomem, reg) + #define INT_RAWSTAT 0x0 #define INT_CLEAR 0x4 #define INT_MASK 0x8 @@ -630,75 +701,4 @@ static inline void panthor_ ## __name ## _irq_disable_= events(struct panthor_irq =20 extern struct workqueue_struct *panthor_cleanup_wq; =20 -static inline void gpu_write(void __iomem *iomem, u32 reg, u32 data) -{ - writel(data, iomem + reg); -} - -static inline u32 gpu_read(void __iomem *iomem, u32 reg) -{ - return readl(iomem + reg); -} - -static inline u32 gpu_read_relaxed(void __iomem *iomem, u32 reg) -{ - return readl_relaxed(iomem + reg); -} - -static inline void gpu_write64(void __iomem *iomem, u32 reg, u64 data) -{ - gpu_write(iomem, reg, lower_32_bits(data)); - gpu_write(iomem, reg + 4, upper_32_bits(data)); -} - -static inline u64 gpu_read64(void __iomem *iomem, u32 reg) -{ - return (gpu_read(iomem, reg) | ((u64)gpu_read(iomem, reg + 4) << 32)); -} - -static inline u64 gpu_read64_relaxed(void __iomem *iomem, u32 reg) -{ - return (gpu_read_relaxed(iomem, reg) | - ((u64)gpu_read_relaxed(iomem, reg + 4) << 32)); -} - -static inline u64 gpu_read64_counter(void __iomem *iomem, u32 reg) -{ - u32 lo, hi1, hi2; - do { - hi1 =3D gpu_read(iomem, reg + 4); - lo =3D gpu_read(iomem, reg); - hi2 =3D gpu_read(iomem, reg + 4); - } while (hi1 !=3D hi2); - return lo | ((u64)hi2 << 32); -} - -#define gpu_read_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us)= \ - read_poll_timeout(gpu_read, val, cond, delay_us, timeout_us, false, \ - iomem, reg) - -#define gpu_read_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \ - timeout_us) \ - read_poll_timeout_atomic(gpu_read, val, cond, delay_us, timeout_us, \ - false, iomem, reg) - -#define gpu_read64_poll_timeout(iomem, reg, val, cond, delay_us, timeout_u= s) \ - read_poll_timeout(gpu_read64, val, cond, delay_us, timeout_us, false, \ - iomem, reg) - -#define gpu_read64_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \ - timeout_us) \ - read_poll_timeout_atomic(gpu_read64, val, cond, delay_us, timeout_us, \ - false, iomem, reg) - -#define gpu_read_relaxed_poll_timeout_atomic(iomem, reg, val, cond, delay_= us, \ - timeout_us) \ - read_poll_timeout_atomic(gpu_read_relaxed, val, cond, delay_us, \ - timeout_us, false, iomem, reg) - -#define gpu_read64_relaxed_poll_timeout(iomem, reg, val, cond, delay_us, \ - timeout_us) \ - read_poll_timeout(gpu_read64_relaxed, val, cond, delay_us, timeout_us, \ - false, iomem, reg) - #endif --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 4A702355819 for ; Tue, 25 Aug 2026 08:01:39 +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=1787644901; cv=none; b=LprNXDQqKzJStpW/TG3F61zSyjAYoE5tUP7bJwA0o6EEyV5mKWOAZzwazjdWBInD60o8LvLZcwaw3z5v1u6E3E/IA9q7yOwphZeLhRiqWE4Ro/4mO4uNbGrtctuGUScFsCZjxUmDUY49a3T7lWRdvNLwYux2oIAILWXlROjrq9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644901; c=relaxed/simple; bh=RRTyLCPeaWnw/IYJOOJcbe9dwK1sl1DE1nHDWR8GSFs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ilPM9XI3nFuIig3ybP5UJwMepN76GSFjyYZ6s1qAgDlgmaG6pRoxU8JE3JjCd6nHYoCXgw80bI9n+2LMSfoputdVhe0+D3XH1QKMUR3D4mxOJlUNsQhCOV7XnQy2+LzdvReDaQD6q7GoP1eXYqV4azpGFly8/BKFoP3M8OYLkLs= 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=WrL7GYld; 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="WrL7GYld" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644891; bh=RRTyLCPeaWnw/IYJOOJcbe9dwK1sl1DE1nHDWR8GSFs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WrL7GYldVIrOMR2PVnveF6iWZqn0AQhcRWIqEDZUZxMwB/eCvbZ1/gqSjyXpsWax9 OwFQLad0PsgKX7NuAKlYB8cir+efC/68p+fSN11/eMZtZD2lrp/28tchKLeDqK/twj QEnhYOw1PJEFsN6U+dwDdE9ZL9lQVfrlkPlcaIZYp7dLzmMwOeDp6cL5+UsQ2pY0Nf cfrWhwYNaHQ0R2qoztcpRZuizBQPJ1NOTPA6eAMLU+JLZX8SwXTmCdIqkd80841VVg q2HN/1vEebvh5FHlT+yPkm1Vk6ZSpSGPD7jF7cDxL4X0kdM5EqkrsYMVsDIKJ69rab FtFUhe39ZUPPw== Received: from fedora-32.home (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 658FA17E0A4C; Tue, 25 Aug 2026 10:01:31 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:24 +0200 Subject: [PATCH v7 3/9] drm/panthor: Replace the panthor_irq macro machinery by inline helpers 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: <20260825-panthor-signal-from-irq-v7-3-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=23928; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=RRTyLCPeaWnw/IYJOOJcbe9dwK1sl1DE1nHDWR8GSFs=; b=EHSBYI8tb97g2fPj7GgTthvs2FrjP5XijPVu0GtHZ/dVZSLbnSjy2e5MvGtw8J45SZeW8fOVe BVVPMbdFnzQCXgLnIqw/6JeeGoMIFlalw6Dibysyd6j5jJ2l8HtTn+h X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Now that panthor_irq contains the iomem region, there's no real need for the macro-based panthor_irq helper generation logic. We can just provide inline helpers that do the same and let the compiler optimize indirect function calls. The only extra annoyance is the fact we have to open-code the panthor_xxx_irq_threaded_handler() implementation, but those are single-line functions, so it's acceptable. While at it, we changed the prototype of the IRQ handlers to take a panthor_irq instead of panthor_device, since that's the thing that's passed around when it comes to panthor_irq, and the panthor_device can be directly extracted from there. Reviewed-by: Steven Price Reviewed-by: Chia-I Wu Reviewed-by: Liviu Dudau Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_device.h | 247 +++++++++++++++------------= ---- drivers/gpu/drm/panthor/panthor_fw.c | 22 ++- drivers/gpu/drm/panthor/panthor_gpu.c | 28 ++-- drivers/gpu/drm/panthor/panthor_mmu.c | 39 ++--- drivers/gpu/drm/panthor/panthor_pwr.c | 24 +-- 5 files changed, 188 insertions(+), 172 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/pan= thor/panthor_device.h index b102ea77fd1a..b55a3f9edd41 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -571,132 +571,127 @@ static inline u64 gpu_read64_counter(void __iomem *= iomem, u32 reg) #define INT_MASK 0x8 #define INT_STAT 0xc =20 -/** - * PANTHOR_IRQ_HANDLER() - Define interrupt handlers and the interrupt - * registration function. - * - * The boiler-plate to gracefully deal with shared interrupts is - * auto-generated. All you have to do is call PANTHOR_IRQ_HANDLER() - * just after the actual handler. The handler prototype is: - * - * void (*handler)(struct panthor_device *, u32 status); - */ -#define PANTHOR_IRQ_HANDLER(__name, __handler) \ -static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *d= ata) \ -{ \ - struct panthor_irq *pirq =3D data; \ - \ - guard(spinlock_irqsave)(&pirq->lock); \ - if (pirq->state !=3D PANTHOR_IRQ_STATE_ACTIVE) \ - return IRQ_NONE; \ - \ - if (!gpu_read(pirq->iomem, INT_STAT)) \ - return IRQ_NONE; \ - \ - pirq->state =3D PANTHOR_IRQ_STATE_PROCESSING; \ - gpu_write(pirq->iomem, INT_MASK, 0); \ - return IRQ_WAKE_THREAD; \ -} \ - \ -static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, vo= id *data) \ -{ \ - struct panthor_irq *pirq =3D data; \ - struct panthor_device *ptdev =3D pirq->ptdev; \ - irqreturn_t ret =3D IRQ_NONE; \ - \ - while (true) { \ - /* It's safe to access pirq->mask without the lock held here. If a new \ - * event gets added to the mask and the corresponding IRQ is pending, \ - * we'll process it right away instead of adding an extra raw -> threade= d \ - * round trip. If an event is removed and the status bit is set, it will= \ - * be ignored, just like it would have been if the mask had been adjuste= d \ - * right before the HW event kicks in. TLDR; it's all expected races we'= re \ - * covered for. \ - */ \ - u32 status =3D gpu_read(pirq->iomem, INT_RAWSTAT) & pirq->mask; \ - \ - if (!status) \ - break; \ - \ - __handler(ptdev, status); \ - ret =3D IRQ_HANDLED; \ - } \ - \ - scoped_guard(spinlock_irqsave, &pirq->lock) { \ - if (pirq->state =3D=3D PANTHOR_IRQ_STATE_PROCESSING) { \ - pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; \ - gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ - } \ - } \ - \ - return ret; \ -} \ - \ -static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *= pirq) \ -{ \ - scoped_guard(spinlock_irqsave, &pirq->lock) { \ - pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDING; \ - gpu_write(pirq->iomem, INT_MASK, 0); \ - } \ - synchronize_irq(pirq->irq); \ - scoped_guard(spinlock_irqsave, &pirq->lock) \ - pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; \ -} \ - \ -static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *p= irq) \ -{ \ - guard(spinlock_irqsave)(&pirq->lock); \ - \ - pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; \ - gpu_write(pirq->iomem, INT_CLEAR, pirq->mask); \ - gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ -} \ - \ -static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev= , \ - struct panthor_irq *pirq, \ - int irq, void __iomem *iomem) \ -{ \ - pirq->ptdev =3D ptdev; \ - pirq->irq =3D irq; \ - pirq->mask =3D 0; \ - pirq->iomem =3D iomem; \ - spin_lock_init(&pirq->lock); \ - pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; \ - gpu_write(pirq->iomem, INT_MASK, 0); \ - \ - return devm_request_threaded_irq(ptdev->base.dev, irq, \ - panthor_ ## __name ## _irq_raw_handler, \ - panthor_ ## __name ## _irq_threaded_handler, \ - IRQF_SHARED, KBUILD_MODNAME "-" # __name, \ - pirq); \ -} \ - \ -static inline void panthor_ ## __name ## _irq_enable_events(struct panthor= _irq *pirq, u32 mask) \ -{ \ - guard(spinlock_irqsave)(&pirq->lock); \ - pirq->mask |=3D mask; \ - \ - /* The only situation where we need to write the new mask is if the IRQ i= s active. \ - * If it's being processed, the mask will be restored for us in _irq_thre= aded_handler() \ - * on the PROCESSING -> ACTIVE transition. \ - * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. \ - */ \ - if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ - gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ -} \ - \ -static inline void panthor_ ## __name ## _irq_disable_events(struct pantho= r_irq *pirq, u32 mask)\ -{ \ - guard(spinlock_irqsave)(&pirq->lock); \ - pirq->mask &=3D ~mask; \ - \ - /* The only situation where we need to write the new mask is if the IRQ i= s active. \ - * If it's being processed, the mask will be restored for us in _irq_thre= aded_handler() \ - * on the PROCESSING -> ACTIVE transition. \ - * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. \ - */ \ - if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) \ - gpu_write(pirq->iomem, INT_MASK, pirq->mask); \ +static inline irqreturn_t panthor_irq_default_raw_handler(int irq, void *d= ata) +{ + struct panthor_irq *pirq =3D data; + + guard(spinlock_irqsave)(&pirq->lock); + if (pirq->state !=3D PANTHOR_IRQ_STATE_ACTIVE) + return IRQ_NONE; + + if (!gpu_read(pirq->iomem, INT_STAT)) + return IRQ_NONE; + + pirq->state =3D PANTHOR_IRQ_STATE_PROCESSING; + gpu_write(pirq->iomem, INT_MASK, 0); + return IRQ_WAKE_THREAD; +} + +static __always_inline irqreturn_t +panthor_irq_default_threaded_handler(void *data, + void (*slow_handler)(struct panthor_irq *, u32)) +{ + struct panthor_irq *pirq =3D data; + irqreturn_t ret =3D IRQ_NONE; + + while (true) { + /* It's safe to access pirq->mask without the lock held here. If a new + * event gets added to the mask and the corresponding IRQ is pending, + * we'll process it right away instead of adding an extra raw -> threaded + * round trip. If an event is removed and the status bit is set, it will + * be ignored, just like it would have been if the mask had been adjusted + * right before the HW event kicks in. TLDR; it's all expected races we'= re + * covered for. + */ + u32 status =3D gpu_read(pirq->iomem, INT_RAWSTAT) & pirq->mask; + + if (!status) + break; + + slow_handler(pirq, status); + ret =3D IRQ_HANDLED; + } + + scoped_guard(spinlock_irqsave, &pirq->lock) { + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_PROCESSING) { + pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; + gpu_write(pirq->iomem, INT_MASK, pirq->mask); + } + } + + return ret; +} + +static inline void panthor_irq_suspend(struct panthor_irq *pirq) +{ + scoped_guard(spinlock_irqsave, &pirq->lock) { + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDING; + gpu_write(pirq->iomem, INT_MASK, 0); + } + synchronize_irq(pirq->irq); + scoped_guard(spinlock_irqsave, &pirq->lock) + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; +} + +static inline void panthor_irq_resume(struct panthor_irq *pirq) +{ + guard(spinlock_irqsave)(&pirq->lock); + pirq->state =3D PANTHOR_IRQ_STATE_ACTIVE; + gpu_write(pirq->iomem, INT_CLEAR, pirq->mask); + gpu_write(pirq->iomem, INT_MASK, pirq->mask); +} + +static inline void panthor_irq_enable_events(struct panthor_irq *pirq, u32= mask) +{ + guard(spinlock_irqsave)(&pirq->lock); + pirq->mask |=3D mask; + + /* The only situation where we need to write the new mask is if the IRQ i= s active. + * If it's being processed, the mask will be restored for us in _irq_thre= aded_handler() + * on the PROCESSING -> ACTIVE transition. + * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. + */ + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) + gpu_write(pirq->iomem, INT_MASK, pirq->mask); +} + +static inline void panthor_irq_disable_events(struct panthor_irq *pirq, u3= 2 mask) +{ + guard(spinlock_irqsave)(&pirq->lock); + pirq->mask &=3D ~mask; + + /* The only situation where we need to write the new mask is if the IRQ i= s active. + * If it's being processed, the mask will be restored for us in _irq_thre= aded_handler() + * on the PROCESSING -> ACTIVE transition. + * If the IRQ is suspended/suspending, the mask is restored at resume tim= e. + */ + if (pirq->state =3D=3D PANTHOR_IRQ_STATE_ACTIVE) + gpu_write(pirq->iomem, INT_MASK, pirq->mask); +} + +static inline int +panthor_irq_request(struct panthor_device *ptdev, struct panthor_irq *pirq, + int irq, void __iomem *iomem, const char *name, + irqreturn_t (*threaded_handler)(int, void *data)) +{ + const char *full_name; + + pirq->ptdev =3D ptdev; + pirq->irq =3D irq; + pirq->mask =3D 0; + pirq->iomem =3D iomem; + spin_lock_init(&pirq->lock); + pirq->state =3D PANTHOR_IRQ_STATE_SUSPENDED; + + full_name =3D devm_kasprintf(ptdev->base.dev, GFP_KERNEL, KBUILD_MODNAME = "-%s", name); + if (!full_name) + return -ENOMEM; + + gpu_write(pirq->iomem, INT_MASK, 0); + return devm_request_threaded_irq(ptdev->base.dev, irq, + panthor_irq_default_raw_handler, + threaded_handler, + IRQF_SHARED, full_name, pirq); } =20 extern struct workqueue_struct *panthor_cleanup_wq; diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor= /panthor_fw.c index fc1a423e48a8..68965175105f 100644 --- a/drivers/gpu/drm/panthor/panthor_fw.c +++ b/drivers/gpu/drm/panthor/panthor_fw.c @@ -1072,8 +1072,9 @@ static void panthor_fw_init_global_iface(struct panth= or_device *ptdev) msecs_to_jiffies(PING_INTERVAL_MS)); } =20 -static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 stat= us) +static void panthor_job_irq_handler(struct panthor_irq *pirq, u32 status) { + struct panthor_device *ptdev =3D pirq->ptdev; u32 duration; u64 start =3D 0; =20 @@ -1099,7 +1100,11 @@ static void panthor_job_irq_handler(struct panthor_d= evice *ptdev, u32 status) trace_gpu_job_irq(ptdev->base.dev, status, duration); } } -PANTHOR_IRQ_HANDLER(job, panthor_job_irq_handler); + +static irqreturn_t panthor_job_irq_threaded_handler(int irq, void *data) +{ + return panthor_irq_default_threaded_handler(data, panthor_job_irq_handler= ); +} =20 static int panthor_fw_start(struct panthor_device *ptdev) { @@ -1107,8 +1112,8 @@ static int panthor_fw_start(struct panthor_device *pt= dev) bool timedout =3D false; =20 ptdev->fw->booted =3D false; - panthor_job_irq_enable_events(&ptdev->fw->irq, ~0); - panthor_job_irq_resume(&ptdev->fw->irq); + panthor_irq_enable_events(&ptdev->fw->irq, ~0); + panthor_irq_resume(&ptdev->fw->irq); gpu_write(fw->iomem, MCU_CONTROL, MCU_CONTROL_AUTO); =20 if (!wait_event_timeout(ptdev->fw->req_waitqueue, @@ -1218,7 +1223,7 @@ void panthor_fw_pre_reset(struct panthor_device *ptde= v, bool on_hang) ptdev->reset.fast =3D true; } =20 - panthor_job_irq_suspend(&ptdev->fw->irq); + panthor_irq_suspend(&ptdev->fw->irq); panthor_fw_stop(ptdev); } =20 @@ -1287,7 +1292,7 @@ void panthor_fw_unplug(struct panthor_device *ptdev) =20 if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) { /* Make sure the IRQ handler cannot be called after that point. */ - panthor_job_irq_suspend(&ptdev->fw->irq); + panthor_irq_suspend(&ptdev->fw->irq); panthor_fw_stop(ptdev); } =20 @@ -1482,8 +1487,9 @@ int panthor_fw_init(struct panthor_device *ptdev) if (irq <=3D 0) return -ENODEV; =20 - ret =3D panthor_request_job_irq(ptdev, &fw->irq, irq, - ptdev->iomem + JOB_INT_BASE); + ret =3D panthor_irq_request(ptdev, &fw->irq, irq, + ptdev->iomem + JOB_INT_BASE, "job", + panthor_job_irq_threaded_handler); if (ret) { drm_err(&ptdev->base, "failed to request job irq"); return ret; diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/pantho= r/panthor_gpu.c index c013d6bf9a59..7f287242285a 100644 --- a/drivers/gpu/drm/panthor/panthor_gpu.c +++ b/drivers/gpu/drm/panthor/panthor_gpu.c @@ -86,8 +86,9 @@ static void panthor_gpu_l2_config_set(struct panthor_devi= ce *ptdev) gpu_write(gpu->iomem, GPU_L2_CONFIG, l2_config); } =20 -static void panthor_gpu_irq_handler(struct panthor_device *ptdev, u32 stat= us) +static void panthor_gpu_irq_handler(struct panthor_irq *pirq, u32 status) { + struct panthor_device *ptdev =3D pirq->ptdev; struct panthor_gpu *gpu =3D ptdev->gpu; =20 gpu_write(gpu->irq.iomem, INT_CLEAR, status); @@ -116,7 +117,11 @@ static void panthor_gpu_irq_handler(struct panthor_dev= ice *ptdev, u32 status) } spin_unlock(&ptdev->gpu->reqs_lock); } -PANTHOR_IRQ_HANDLER(gpu, panthor_gpu_irq_handler); + +static irqreturn_t panthor_gpu_irq_threaded_handler(int irq, void *data) +{ + return panthor_irq_default_threaded_handler(data, panthor_gpu_irq_handler= ); +} =20 /** * panthor_gpu_unplug() - Called when the GPU is unplugged. @@ -128,7 +133,7 @@ void panthor_gpu_unplug(struct panthor_device *ptdev) =20 /* Make sure the IRQ handler is not running after that point. */ if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) - panthor_gpu_irq_suspend(&ptdev->gpu->irq); + panthor_irq_suspend(&ptdev->gpu->irq); =20 /* Wake-up all waiters. */ spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags); @@ -169,13 +174,14 @@ int panthor_gpu_init(struct panthor_device *ptdev) if (irq < 0) return irq; =20 - ret =3D panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq, - ptdev->iomem + GPU_INT_BASE); + ret =3D panthor_irq_request(ptdev, &ptdev->gpu->irq, irq, + ptdev->iomem + GPU_INT_BASE, "gpu", + panthor_gpu_irq_threaded_handler); if (ret) return ret; =20 - panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_INTERRUPTS_MASK); - panthor_gpu_irq_resume(&ptdev->gpu->irq); + panthor_irq_enable_events(&ptdev->gpu->irq, GPU_INTERRUPTS_MASK); + panthor_irq_resume(&ptdev->gpu->irq); return 0; } =20 @@ -183,7 +189,7 @@ int panthor_gpu_power_changed_on(struct panthor_device = *ptdev) { guard(pm_runtime_active)(ptdev->base.dev); =20 - panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK= ); + panthor_irq_enable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK); =20 return 0; } @@ -192,7 +198,7 @@ void panthor_gpu_power_changed_off(struct panthor_devic= e *ptdev) { guard(pm_runtime_active)(ptdev->base.dev); =20 - panthor_gpu_irq_disable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MAS= K); + panthor_irq_disable_events(&ptdev->gpu->irq, GPU_POWER_INTERRUPTS_MASK); } =20 /** @@ -425,7 +431,7 @@ void panthor_gpu_suspend(struct panthor_device *ptdev) else panthor_hw_l2_power_off(ptdev); =20 - panthor_gpu_irq_suspend(&ptdev->gpu->irq); + panthor_irq_suspend(&ptdev->gpu->irq); } =20 /** @@ -437,7 +443,7 @@ void panthor_gpu_suspend(struct panthor_device *ptdev) */ void panthor_gpu_resume(struct panthor_device *ptdev) { - panthor_gpu_irq_resume(&ptdev->gpu->irq); + panthor_irq_resume(&ptdev->gpu->irq); panthor_hw_l2_power_on(ptdev); } =20 diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index 0182b72f1932..d43ba1c7cd2a 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -601,17 +601,13 @@ static u32 panthor_mmu_as_fault_mask(struct panthor_d= evice *ptdev, u32 as) return BIT(as); } =20 -/* Forward declaration to call helpers within as_enable/disable */ -static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 stat= us); -PANTHOR_IRQ_HANDLER(mmu, panthor_mmu_irq_handler); - static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr, u64 transtab, u64 transcfg, u64 memattr) { struct panthor_mmu *mmu =3D ptdev->mmu; =20 - panthor_mmu_irq_enable_events(&ptdev->mmu->irq, - panthor_mmu_as_fault_mask(ptdev, as_nr)); + panthor_irq_enable_events(&ptdev->mmu->irq, + panthor_mmu_as_fault_mask(ptdev, as_nr)); =20 gpu_write64(mmu->iomem, AS_TRANSTAB(as_nr), transtab); gpu_write64(mmu->iomem, AS_MEMATTR(as_nr), memattr); @@ -629,8 +625,8 @@ static int panthor_mmu_as_disable(struct panthor_device= *ptdev, u32 as_nr, =20 lockdep_assert_held(&ptdev->mmu->as.slots_lock); =20 - panthor_mmu_irq_disable_events(&ptdev->mmu->irq, - panthor_mmu_as_fault_mask(ptdev, as_nr)); + panthor_irq_disable_events(&ptdev->mmu->irq, + panthor_mmu_as_fault_mask(ptdev, as_nr)); =20 /* Flush+invalidate RW caches, invalidate RO ones. */ ret =3D panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV, @@ -1859,8 +1855,9 @@ static void panthor_vm_unlock_region(struct panthor_v= m *vm) mutex_unlock(&ptdev->mmu->as.slots_lock); } =20 -static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 stat= us) +static void panthor_mmu_irq_handler(struct panthor_irq *pirq, u32 status) { + struct panthor_device *ptdev =3D pirq->ptdev; struct panthor_mmu *mmu =3D ptdev->mmu; bool has_unhandled_faults =3D false; =20 @@ -1923,6 +1920,11 @@ static void panthor_mmu_irq_handler(struct panthor_d= evice *ptdev, u32 status) panthor_sched_report_mmu_fault(ptdev); } =20 +static irqreturn_t panthor_mmu_irq_threaded_handler(int irq, void *data) +{ + return panthor_irq_default_threaded_handler(data, panthor_mmu_irq_handler= ); +} + /** * panthor_mmu_suspend() - Suspend the MMU logic * @ptdev: Device. @@ -1947,7 +1949,7 @@ void panthor_mmu_suspend(struct panthor_device *ptdev) } mutex_unlock(&ptdev->mmu->as.slots_lock); =20 - panthor_mmu_irq_suspend(&ptdev->mmu->irq); + panthor_irq_suspend(&ptdev->mmu->irq); } =20 /** @@ -1966,7 +1968,7 @@ void panthor_mmu_resume(struct panthor_device *ptdev) ptdev->mmu->as.faulty_mask =3D 0; mutex_unlock(&ptdev->mmu->as.slots_lock); =20 - panthor_mmu_irq_resume(&ptdev->mmu->irq); + panthor_irq_resume(&ptdev->mmu->irq); } =20 /** @@ -1983,7 +1985,7 @@ void panthor_mmu_pre_reset(struct panthor_device *ptd= ev) { struct panthor_vm *vm; =20 - panthor_mmu_irq_suspend(&ptdev->mmu->irq); + panthor_irq_suspend(&ptdev->mmu->irq); =20 mutex_lock(&ptdev->mmu->vm.lock); ptdev->mmu->vm.reset_in_progress =3D true; @@ -2020,7 +2022,7 @@ void panthor_mmu_post_reset(struct panthor_device *pt= dev) =20 mutex_unlock(&ptdev->mmu->as.slots_lock); =20 - panthor_mmu_irq_resume(&ptdev->mmu->irq); + panthor_irq_resume(&ptdev->mmu->irq); =20 /* Restart the VM_BIND queues. */ mutex_lock(&ptdev->mmu->vm.lock); @@ -3352,7 +3354,7 @@ panthor_mmu_reclaim_priv_bos(struct panthor_device *p= tdev, void panthor_mmu_unplug(struct panthor_device *ptdev) { if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) - panthor_mmu_irq_suspend(&ptdev->mmu->irq); + panthor_irq_suspend(&ptdev->mmu->irq); =20 mutex_lock(&ptdev->mmu->as.slots_lock); for (u32 i =3D 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) { @@ -3413,8 +3415,9 @@ int panthor_mmu_init(struct panthor_device *ptdev) if (irq <=3D 0) return -ENODEV; =20 - ret =3D panthor_request_mmu_irq(ptdev, &mmu->irq, irq, - ptdev->iomem + MMU_INT_BASE); + ret =3D panthor_irq_request(ptdev, &mmu->irq, irq, + ptdev->iomem + MMU_INT_BASE, "mmu", + panthor_mmu_irq_threaded_handler); if (ret) return ret; =20 @@ -3435,8 +3438,8 @@ int panthor_mmu_init(struct panthor_device *ptdev) if (ret) return ret; =20 - panthor_mmu_irq_enable_events(&mmu->irq, panthor_mmu_fault_mask(ptdev, ~0= )); - panthor_mmu_irq_resume(&mmu->irq); + panthor_irq_enable_events(&mmu->irq, panthor_mmu_fault_mask(ptdev, ~0)); + panthor_irq_resume(&mmu->irq); return 0; } =20 diff --git a/drivers/gpu/drm/panthor/panthor_pwr.c b/drivers/gpu/drm/pantho= r/panthor_pwr.c index f2c2c3000590..dd7b6ef8ea20 100644 --- a/drivers/gpu/drm/panthor/panthor_pwr.c +++ b/drivers/gpu/drm/panthor/panthor_pwr.c @@ -56,8 +56,9 @@ struct panthor_pwr { wait_queue_head_t reqs_acked; }; =20 -static void panthor_pwr_irq_handler(struct panthor_device *ptdev, u32 stat= us) +static void panthor_pwr_irq_handler(struct panthor_irq *pirq, u32 status) { + struct panthor_device *ptdev =3D pirq->ptdev; struct panthor_pwr *pwr =3D ptdev->pwr; =20 spin_lock(&ptdev->pwr->reqs_lock); @@ -75,7 +76,11 @@ static void panthor_pwr_irq_handler(struct panthor_devic= e *ptdev, u32 status) } spin_unlock(&ptdev->pwr->reqs_lock); } -PANTHOR_IRQ_HANDLER(pwr, panthor_pwr_irq_handler); + +static irqreturn_t panthor_pwr_irq_threaded_handler(int irq, void *data) +{ + return panthor_irq_default_threaded_handler(data, panthor_pwr_irq_handler= ); +} =20 static void panthor_pwr_write_command(struct panthor_device *ptdev, u32 co= mmand, u64 args) { @@ -454,7 +459,7 @@ void panthor_pwr_unplug(struct panthor_device *ptdev) =20 /* Make sure the IRQ handler is not running after that point. */ if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) - panthor_pwr_irq_suspend(&ptdev->pwr->irq); + panthor_irq_suspend(&ptdev->pwr->irq); =20 /* Wake-up all waiters. */ spin_lock_irqsave(&ptdev->pwr->reqs_lock, flags); @@ -484,13 +489,14 @@ int panthor_pwr_init(struct panthor_device *ptdev) if (irq < 0) return irq; =20 - err =3D panthor_request_pwr_irq(ptdev, &pwr->irq, irq, - pwr->iomem + PWR_INT_BASE); + err =3D panthor_irq_request(ptdev, &pwr->irq, irq, + pwr->iomem + PWR_INT_BASE, "pwr", + panthor_pwr_irq_threaded_handler); if (err) return err; =20 - panthor_pwr_irq_enable_events(&pwr->irq, PWR_INTERRUPTS_MASK); - panthor_pwr_irq_resume(&pwr->irq); + panthor_irq_enable_events(&pwr->irq, PWR_INTERRUPTS_MASK); + panthor_irq_resume(&pwr->irq); return 0; } =20 @@ -566,7 +572,7 @@ void panthor_pwr_suspend(struct panthor_device *ptdev) if (!ptdev->pwr) return; =20 - panthor_pwr_irq_suspend(&ptdev->pwr->irq); + panthor_irq_suspend(&ptdev->pwr->irq); } =20 void panthor_pwr_resume(struct panthor_device *ptdev) @@ -574,5 +580,5 @@ void panthor_pwr_resume(struct panthor_device *ptdev) if (!ptdev->pwr) return; =20 - panthor_pwr_irq_resume(&ptdev->pwr->irq); + panthor_irq_resume(&ptdev->pwr->irq); } --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 4A7A0373BFE for ; Tue, 25 Aug 2026 08:01:39 +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=1787644901; cv=none; b=BgXmF2HzbQcnh3TKeZMCrMyV98IcbgFGiKePN8VNvvpv6NcpaFscML6OciLpqQRYJC6EkUyuQ3TrvpL7EgbhUnTEb1Q7h1o2PPsuZllqtWE1VW/jMfqbcY+pi0c9ngW81O2MUFJZ3RiaxHHDrG0wLMYHCC9ebw2bgXuOBLlOKPY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644901; c=relaxed/simple; bh=Xf1RMzh8zNMc/EUp+sv/qMuFLlV70LvZ6DH8SenbbpA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hR6ZHQZU9OXpFyJX82vLH+9aHt5ZMheuBsOkDuqTok5zVks2nEy9QfoCANfsOVzP6ZNgOAgrUa0C8DYwkTH+4M16GBkgy/WgiciL7zBSq+X1qTo58Dz8Q4ee1IKDrFQExSeYJhypsxh0l2clslf6BhscFeK1+pTcmqJ/duOXcHU= 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=I+HzgIHi; 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="I+HzgIHi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644892; bh=Xf1RMzh8zNMc/EUp+sv/qMuFLlV70LvZ6DH8SenbbpA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=I+HzgIHikLvmfP62ws6RnebEFYr9mFrdUopUP6j+/PLaQ5/a592Mz9YAAABi/JypE pTBA0ZC98bmwv0fH3ELsP93AWLsayRYHvFL3p5U8UOvxTw6PyieQkz0Oa9JWkw0PB0 n1vsFEIJpW5eniPdfgUauouclbmiFx0+SB0RbI0ArjFxbkznQnSYxpMrKMQXEAiSuT Wqb3ZQ8qeDD9zeZdJ2K9RylUGfDbMMvh9OtsK9IjBypSWxXI4r0KxxgB5OfJ0fizq+ zJENaqYNb8/VcuyCuTK2lOcIDkDToZ8xVbR0BuVNlfUerdJFwzpbhrnXAFu6nZ3P63 aLyowSVi2TGRQ== Received: from fedora-32.home (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 F316B17E0B92; Tue, 25 Aug 2026 10:01:31 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:25 +0200 Subject: [PATCH v7 4/9] drm/panthor: Don't update might_have_idle_groups in process_idle_event_locked() 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: <20260825-panthor-signal-from-irq-v7-4-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=1083; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=Xf1RMzh8zNMc/EUp+sv/qMuFLlV70LvZ6DH8SenbbpA=; b=oAFvWIOFi9MJfczVyKXWN2NFaVUoHJzC9JS5nxcDcK6OD4HDPfTEH+TYpcyESrVdJKy/RqESJ 5JZsD5oEi7HAvxq2b/D3xXqKlkC7YEF4w2F7PnG/jIaLrmyFhsW0/ej X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= By scheduling an immediate tick, we already force idleness re-evaluation, which gives the scheduler the opportunity to evict idle groups and schedule onces that have jobs pending. Reviewed-by: Liviu Dudau Reviewed-by: Steven Price Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 5832dccfc093..baa06731797c 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -1733,8 +1733,6 @@ static void csg_slot_process_idle_event_locked(struct= panthor_device *ptdev, u32 =20 lockdep_assert_held(&sched->lock); =20 - sched->might_have_idle_groups =3D true; - /* Schedule a tick so we can evict idle groups and schedule non-idle * ones. This will also update runtime PM and devfreq busy/idle states, * so the device can lower its frequency or get suspended. --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 1661C3D7A01 for ; Tue, 25 Aug 2026 08:01:41 +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=1787644903; cv=none; b=aOxK8bJiDED7HpInqCEMzOvdFb7oEeC15nNmcE8RWp+AayM60mSODKzjziLVOW13XWUt4fGIrYctnwQ+SJzk5BPgn5SiZqmVW5gdBtPMobFn/SjA6RmKjf67/AIP6UcNHwFh0ec7lmSXQgHhneUhtu1Z9lQGaOAc1Ze1QKIZBv0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644903; c=relaxed/simple; bh=cuoeQG2pazNi+8YJl21F2Xuphl17v5B8h0qeDM459J8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P0JhkP9lTfZTTioiZG3UwbI/QzSThOSH1R1IWtmAUvi0YpnupaAvWJH9cCLD7iD94Wj0wY3+2Cmej5/r/JJNZDliTWCWA6lDyrpWjwwDYvFl/c8sC61Sqxlrw1EDH7wKhRRurELa8ee9prH6osMy5VPGD7EiP+E/NBbzp9rh2jE= 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=MHH7KxEL; 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="MHH7KxEL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644892; bh=cuoeQG2pazNi+8YJl21F2Xuphl17v5B8h0qeDM459J8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MHH7KxELm2irNFgtVxWOn8pKtag7WT7rxysamsSYtrwEA7Bq32lmzuNui6UOInpBb i68n34FRkaBmdkzss8l0LFYl27saXHHcqwQnsLqvCI5QIay3T33G5pi7zEgzawAScg jpjI/MEoEDrQCnbAivXCPbQtBfs6F0LxokiMWTUQbRz68fmNKMIqyviG5os2PqOgLK KLUdyYj5DF5MXTYDQbkfaFmhGC6dkK4Ralq+KwuYoRAXSLvDXY/O+olihw48+VOGj1 rIpKsvsbWGi/IWXg3p1U76uW5pxcG3Cj5B9LMsthOtQmFUnIYeVZcac+zxoJJFWB8e DMANTSom0Telg== Received: from fedora-32.home (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 8905917E0BBE; Tue, 25 Aug 2026 10:01:32 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:26 +0200 Subject: [PATCH v7 5/9] drm/panthor: Get rid of panthor_group::fatal_lock 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: <20260825-panthor-signal-from-irq-v7-5-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=1191; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=cuoeQG2pazNi+8YJl21F2Xuphl17v5B8h0qeDM459J8=; b=w04oY8pXl+hnGeoyg7SFb4HPblGqb0wVxOVO33lHvddMDmxP388OA4VRexBz+y9WQLPh5Thg2 oLnYfTj94pLCqlC7YjfAF3P8VPVkgv/XLMgwbR82h9jLaDtovcplZFW X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= This lock is never used, and we're about to make fatal_queues an atomic to cope with concurrent updates. Reviewed-by: Liviu Dudau Reviewed-by: Steven Price Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index baa06731797c..9adf1e21eb83 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -565,9 +565,6 @@ struct panthor_group { /** @idle_queues: Bitmask reflecting the idle queues. */ u32 idle_queues; =20 - /** @fatal_lock: Lock used to protect access to fatal fields. */ - spinlock_t fatal_lock; - /** @fatal_queues: Bitmask reflecting the queues that hit a fatal excepti= on. */ u32 fatal_queues; =20 @@ -3675,7 +3672,6 @@ int panthor_group_create(struct panthor_file *pfile, if (!group) return -ENOMEM; =20 - spin_lock_init(&group->fatal_lock); kref_init(&group->refcount); group->state =3D PANTHOR_CS_GROUP_CREATED; group->csg_id =3D -1; --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 165823D566A for ; Tue, 25 Aug 2026 08:01:41 +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=1787644905; cv=none; b=e32tq8Cay7gVbSTgV9Jc1T8uuY7vFgX1mFYeIY6l7ZyXs5OK7m4D4v2yXnI4vVScoL6DfE6wlhGBFOCBjJak9LQGswpAiI8gn0bHpnv711md0nMz6SOyfbOaCp38lqlQE3Jrq4LNKebHGWgIrXGo20Qrs88l6aWnOpV0TAdNSts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644905; c=relaxed/simple; bh=+2ohjJUid7weiQylVIDJ9OoeuPnFjoyZUfJCRsZnLq0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=olxdglcmP3WQS+fcucoNxpoGlk215V9sBLDFe59Pp/Shyi4Ex7lSrJyiXkJ2WaJFuwAtTiLjmP4YH8cQiGi8cbH/VyHtbvcAdFPAu0Nef5f2zUozazDkWUZQUfvO+7P/gC34hYQSXyf336F/DaGnsRUaMVt5esEqDCX5HRAty/M= 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=jK/X8phY; 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="jK/X8phY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644893; bh=+2ohjJUid7weiQylVIDJ9OoeuPnFjoyZUfJCRsZnLq0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jK/X8phYWgFkEQetc2gHEB5Gt7X0bg/XP0iJ0kilV71TG1hOkmIXQ9Ttj3nT0KtOw dIHUI8YTUP+8WPpRUZHgseVknIICBJhXdP3oBsbg/TpfkjXDZ6oBHeNW3rP0qJ96pT zhfgco3S0fSipNhmxyFVoFGRDQnVvi+0nDI3zb2X7wsuyncth15Od3/s6z+Lnf+7mF 8ZFswp7iHRFv5kSjzNaU4+VZgCUoeJ5NdEzHR2YPAUWXxon/CbuMDzxJ47qIo5DCJ1 kjB66/+PQ4whuZ9Qbz1gY7+P26A1Blba5w760g29OUjPtYievJOfVbDTNd0S8JKy3h DQNjPYcE6aM9w== Received: from fedora-32.home (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 1A50717E0BDC; Tue, 25 Aug 2026 10:01:33 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:27 +0200 Subject: [PATCH v7 6/9] drm/panthor: Protect events processing with a separate spinlock 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: <20260825-panthor-signal-from-irq-v7-6-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=14507; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=+2ohjJUid7weiQylVIDJ9OoeuPnFjoyZUfJCRsZnLq0=; b=fOTq+SGWatV+odDI64VAA3mh5cJbSGt1BFQ2VRZO8xcgw28eSchmEFbar6IuRbsT8o7hzYJbI nazwzNpO+ltAs8jf8wuKMNKjXnnZvp7nq5FwxqPxly+7QvuLIg+9zB2 X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Add a specific spinlock for events processing so we can selectively move some event processing to the threaded IRQ handler. For events to be processed, we need to have access to the group attached to the CSG slot which also forces us to protect the csg_slots[] updates with this lock. Note that fatal_queues/timedout are turned into atomics to avoid having to take the events_lock every time those are checked or updated. Reviewed-by: Liviu Dudau Reviewed-by: Steven Price Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 124 ++++++++++++++++++++--------= ---- 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 9adf1e21eb83..5e1bf52fa282 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -254,8 +254,22 @@ struct panthor_scheduler { struct list_head waiting; } groups; =20 + /** + * @events_lock: Lock taken when processing events. + * + * This also needs to be taken when csg_slots are updated, to make sure + * the event processing logic doesn't touch groups that have left the CSG + * slot. + */ + spinlock_t events_lock; + /** * @csg_slots: FW command stream group slots. + * + * Updates to the group binding must happen with both + * panthor_scheduler::lock and panthor_scheduler::events_lock held. + * The group binding may therefore be read while holding either lock. + * Other slot fields are protected by panthor_scheduler::lock. */ struct panthor_csg_slot csg_slots[MAX_CSGS]; =20 @@ -565,8 +579,13 @@ struct panthor_group { /** @idle_queues: Bitmask reflecting the idle queues. */ u32 idle_queues; =20 - /** @fatal_queues: Bitmask reflecting the queues that hit a fatal excepti= on. */ - u32 fatal_queues; + /** + * @fatal_queues: Bitmask reflecting the queues that hit a fatal exceptio= n. + * + * This is an atomic because we don't want to acquire the events_lock + * every time we need to check the group state. + */ + atomic_t fatal_queues; =20 /** @tiler_oom: Mask of queues that have a tiler OOM event to process. */ atomic_t tiler_oom; @@ -602,8 +621,14 @@ struct panthor_group { * any timeout situation is unrecoverable, and the group becomes useless.= We * simply wait for all references to be dropped so we can release the gro= up * object. + * + * This is an atomic because it can be set from both a scheduling context + * (protected with panthor_scheduler::lock) and an event processing conte= xt + * (protected with panthor_scheduler::events_lock). We could protect acce= ss + * with the events_lock, but this is simpler to make it an atomic since t= he + * only allowed transition is false -> true. */ - bool timedout; + atomic_t timedout; =20 /** * @innocent: True when the group becomes unusable because the group susp= ension @@ -996,7 +1021,6 @@ static int group_bind_locked(struct panthor_group *group, u32 csg_id) { struct panthor_device *ptdev =3D group->ptdev; - struct panthor_csg_slot *csg_slot; int ret; =20 lockdep_assert_held(&ptdev->scheduler->lock); @@ -1009,9 +1033,7 @@ group_bind_locked(struct panthor_group *group, u32 cs= g_id) if (ret) return ret; =20 - csg_slot =3D &ptdev->scheduler->csg_slots[csg_id]; group_get(group); - group->csg_id =3D csg_id; =20 /* Dummy doorbell allocation: doorbell is assigned to the group and * all queues use the same doorbell. @@ -1023,7 +1045,10 @@ group_bind_locked(struct panthor_group *group, u32 c= sg_id) for (u32 i =3D 0; i < group->queue_count; i++) group->queues[i]->doorbell_id =3D csg_id + 1; =20 - csg_slot->group =3D group; + scoped_guard(spinlock, &ptdev->scheduler->events_lock) { + ptdev->scheduler->csg_slots[csg_id].group =3D group; + group->csg_id =3D csg_id; + } =20 return 0; } @@ -1038,7 +1063,6 @@ static int group_unbind_locked(struct panthor_group *group) { struct panthor_device *ptdev =3D group->ptdev; - struct panthor_csg_slot *slot; =20 lockdep_assert_held(&ptdev->scheduler->lock); =20 @@ -1048,9 +1072,12 @@ group_unbind_locked(struct panthor_group *group) if (drm_WARN_ON(&ptdev->base, group->state =3D=3D PANTHOR_CS_GROUP_ACTIVE= )) return -EINVAL; =20 - slot =3D &ptdev->scheduler->csg_slots[group->csg_id]; + scoped_guard(spinlock, &ptdev->scheduler->events_lock) { + ptdev->scheduler->csg_slots[group->csg_id].group =3D NULL; + group->csg_id =3D -1; + } + panthor_vm_idle(group->vm); - group->csg_id =3D -1; =20 /* Tiler OOM events will be re-issued next time the group is scheduled. */ atomic_set(&group->tiler_oom, 0); @@ -1060,8 +1087,6 @@ group_unbind_locked(struct panthor_group *group) for (u32 i =3D 0; i < group->queue_count; i++) group->queues[i]->doorbell_id =3D -1; =20 - slot->group =3D NULL; - group_put(group); return 0; } @@ -1079,8 +1104,9 @@ group_can_run(struct panthor_group *group) { return group->state !=3D PANTHOR_CS_GROUP_TERMINATED && group->state !=3D PANTHOR_CS_GROUP_UNKNOWN_STATE && - !group->destroyed && group->fatal_queues =3D=3D 0 && - !group->timedout; + !group->destroyed && + !atomic_read(&group->fatal_queues) && + !atomic_read(&group->timedout); } =20 static bool @@ -1479,7 +1505,7 @@ cs_slot_process_fatal_event_locked(struct panthor_dev= ice *ptdev, u32 fatal; u64 info; =20 - lockdep_assert_held(&sched->lock); + lockdep_assert_held(&sched->events_lock); =20 cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); fatal =3D cs_iface->output->fatal; @@ -1489,7 +1515,7 @@ cs_slot_process_fatal_event_locked(struct panthor_dev= ice *ptdev, drm_warn(&ptdev->base, "CS_FATAL: pid=3D%d, comm=3D%s\n", group->task_info.pid, group->task_info.comm); =20 - group->fatal_queues |=3D BIT(cs_id); + atomic_or(BIT(cs_id), &group->fatal_queues); } =20 if (CS_EXCEPTION_TYPE(fatal) =3D=3D DRM_PANTHOR_EXCEPTION_CS_UNRECOVERABL= E) { @@ -1527,7 +1553,7 @@ cs_slot_process_fault_event_locked(struct panthor_dev= ice *ptdev, u32 fault; u64 info; =20 - lockdep_assert_held(&sched->lock); + lockdep_assert_held(&sched->events_lock); =20 cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); fault =3D cs_iface->output->fault; @@ -1619,7 +1645,7 @@ static int group_process_tiler_oom(struct panthor_gro= up *group, u32 cs_id) */ if (ret && ret !=3D -ENOMEM) { drm_warn(&ptdev->base, "Failed to extend the tiler heap\n"); - group->fatal_queues |=3D BIT(cs_id); + atomic_or(BIT(cs_id), &group->fatal_queues); sched_queue_delayed_work(sched, tick, 0); goto out_put_heap_pool; } @@ -1679,7 +1705,7 @@ cs_slot_process_tiler_oom_event_locked(struct panthor= _device *ptdev, struct panthor_csg_slot *csg_slot =3D &sched->csg_slots[csg_id]; struct panthor_group *group =3D csg_slot->group; =20 - lockdep_assert_held(&sched->lock); + lockdep_assert_held(&sched->events_lock); =20 if (drm_WARN_ON(&ptdev->base, !group)) return; @@ -1700,7 +1726,7 @@ static bool cs_slot_process_irq_locked(struct panthor= _device *ptdev, struct panthor_fw_cs_iface *cs_iface; u32 req, ack, events; =20 - lockdep_assert_held(&ptdev->scheduler->lock); + lockdep_assert_held(&ptdev->scheduler->events_lock); =20 cs_iface =3D panthor_fw_get_cs_iface(ptdev, csg_id, cs_id); req =3D cs_iface->input->req; @@ -1728,7 +1754,7 @@ static void csg_slot_process_idle_event_locked(struct= panthor_device *ptdev, u32 { struct panthor_scheduler *sched =3D ptdev->scheduler; =20 - lockdep_assert_held(&sched->lock); + lockdep_assert_held(&sched->events_lock); =20 /* Schedule a tick so we can evict idle groups and schedule non-idle * ones. This will also update runtime PM and devfreq busy/idle states, @@ -1743,7 +1769,7 @@ static void csg_slot_sync_update_locked(struct pantho= r_device *ptdev, struct panthor_csg_slot *csg_slot =3D &ptdev->scheduler->csg_slots[csg_id= ]; struct panthor_group *group =3D csg_slot->group; =20 - lockdep_assert_held(&ptdev->scheduler->lock); + lockdep_assert_held(&ptdev->scheduler->events_lock); =20 if (group) group_queue_work(group, sync_upd); @@ -1758,14 +1784,14 @@ csg_slot_process_progress_timer_event_locked(struct= panthor_device *ptdev, u32 c struct panthor_csg_slot *csg_slot =3D &sched->csg_slots[csg_id]; struct panthor_group *group =3D csg_slot->group; =20 - lockdep_assert_held(&sched->lock); + lockdep_assert_held(&sched->events_lock); =20 group =3D csg_slot->group; if (!drm_WARN_ON(&ptdev->base, !group)) { drm_warn(&ptdev->base, "CSG_PROGRESS_TIMER_EVENT: pid=3D%d, comm=3D%s\n", group->task_info.pid, group->task_info.comm); =20 - group->timedout =3D true; + atomic_set(&group->timedout, true); } =20 drm_warn(&ptdev->base, "CSG slot %d progress timeout\n", csg_id); @@ -1779,7 +1805,7 @@ static void sched_process_csg_irq_locked(struct panth= or_device *ptdev, u32 csg_i struct panthor_fw_csg_iface *csg_iface; u32 ring_cs_db_mask =3D 0; =20 - lockdep_assert_held(&ptdev->scheduler->lock); + lockdep_assert_held(&ptdev->scheduler->events_lock); =20 if (drm_WARN_ON(&ptdev->base, csg_id >=3D ptdev->scheduler->csg_slot_coun= t)) return; @@ -1837,7 +1863,7 @@ static void sched_process_idle_event_locked(struct pa= nthor_device *ptdev) { struct panthor_fw_global_iface *glb_iface =3D panthor_fw_get_glb_iface(pt= dev); =20 - lockdep_assert_held(&ptdev->scheduler->lock); + lockdep_assert_held(&ptdev->scheduler->events_lock); =20 /* Acknowledge the idle event and schedule a tick. */ panthor_fw_update_reqs(glb_iface, req, glb_iface->output->ack, GLB_IDLE); @@ -1853,7 +1879,7 @@ static void sched_process_global_irq_locked(struct pa= nthor_device *ptdev) struct panthor_fw_global_iface *glb_iface =3D panthor_fw_get_glb_iface(pt= dev); u32 req, ack, evts; =20 - lockdep_assert_held(&ptdev->scheduler->lock); + lockdep_assert_held(&ptdev->scheduler->events_lock); =20 req =3D READ_ONCE(glb_iface->input->req); ack =3D READ_ONCE(glb_iface->output->ack); @@ -1870,7 +1896,7 @@ static void process_fw_events_work(struct work_struct= *work) u32 events =3D atomic_xchg(&sched->fw_events, 0); struct panthor_device *ptdev =3D sched->ptdev; =20 - mutex_lock(&sched->lock); + guard(spinlock)(&sched->events_lock); =20 if (events & JOB_INT_GLOBAL_IF) { sched_process_global_irq_locked(ptdev); @@ -1883,8 +1909,6 @@ static void process_fw_events_work(struct work_struct= *work) sched_process_csg_irq_locked(ptdev, csg_id); events &=3D ~BIT(csg_id); } - - mutex_unlock(&sched->lock); } =20 /** @@ -2131,11 +2155,12 @@ tick_ctx_init(struct panthor_scheduler *sched, * CSG IRQs, so we can flag the faulty queue. */ if (panthor_vm_has_unhandled_faults(group->vm)) { - sched_process_csg_irq_locked(ptdev, i); + scoped_guard(spinlock, &sched->events_lock) + sched_process_csg_irq_locked(ptdev, i); =20 /* No fatal fault reported, flag all queues as faulty. */ - if (!group->fatal_queues) - group->fatal_queues |=3D GENMASK(group->queue_count - 1, 0); + atomic_cmpxchg(&group->fatal_queues, 0, + GENMASK(group->queue_count - 1, 0)); } =20 tick_ctx_insert_old_group(sched, ctx, group); @@ -2168,9 +2193,9 @@ group_term_post_processing(struct panthor_group *grou= p) struct panthor_syncobj_64b *syncobj; int err; =20 - if (group->fatal_queues & BIT(i)) + if (atomic_read(&group->fatal_queues) & BIT(i)) err =3D -EINVAL; - else if (group->timedout) + else if (atomic_read(&group->timedout)) err =3D -ETIMEDOUT; else err =3D -ECANCELED; @@ -2331,8 +2356,10 @@ tick_ctx_apply(struct panthor_scheduler *sched, stru= ct panthor_sched_tick_ctx *c * any pending interrupts before we start the new * group. */ - if (group->csg_id >=3D 0) + if (group->csg_id >=3D 0) { + guard(spinlock)(&sched->events_lock); sched_process_csg_irq_locked(ptdev, group->csg_id); + } =20 group_unbind_locked(group); } @@ -2861,7 +2888,7 @@ void panthor_sched_suspend(struct panthor_device *ptd= ev) /* We consider group suspension failures as fatal and flag the * group as unusable by setting timedout=3Dtrue. */ - csg_slot->group->timedout =3D true; + atomic_set(&csg_slot->group->timedout, true); =20 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, CSG_STATE_TERMINATE, @@ -2910,10 +2937,12 @@ void panthor_sched_suspend(struct panthor_device *p= tdev) u32 csg_id =3D ffs(slot_mask) - 1; struct panthor_csg_slot *csg_slot =3D &sched->csg_slots[csg_id]; =20 - if (flush_caches_failed) + if (flush_caches_failed) { csg_slot->group->state =3D PANTHOR_CS_GROUP_TERMINATED; - else + } else { + guard(spinlock)(&sched->events_lock); csg_slot_sync_update_locked(ptdev, csg_id); + } =20 slot_mask &=3D ~BIT(csg_id); } @@ -2928,8 +2957,10 @@ void panthor_sched_suspend(struct panthor_device *pt= dev) =20 group_get(group); =20 - if (group->csg_id >=3D 0) + if (group->csg_id >=3D 0) { + guard(spinlock)(&sched->events_lock); sched_process_csg_irq_locked(ptdev, group->csg_id); + } =20 group_unbind_locked(group); =20 @@ -3421,7 +3452,7 @@ queue_timedout_job(struct drm_sched_job *sched_job) queue_stop(queue, job); =20 mutex_lock(&sched->lock); - group->timedout =3D true; + atomic_set(&group->timedout, true); if (group->csg_id >=3D 0) { sched_queue_delayed_work(ptdev->scheduler, tick, 0); } else { @@ -3843,12 +3874,13 @@ int panthor_group_get_state(struct panthor_file *pf= ile, memset(get_state, 0, sizeof(*get_state)); =20 mutex_lock(&sched->lock); - if (group->timedout) + if (atomic_read(&group->timedout)) get_state->state |=3D DRM_PANTHOR_GROUP_STATE_TIMEDOUT; - if (group->fatal_queues) { + + get_state->fatal_queues =3D atomic_read(&group->fatal_queues); + if (get_state->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; mutex_unlock(&sched->lock); @@ -4146,6 +4178,8 @@ int panthor_sched_init(struct panthor_device *ptdev) INIT_WORK(&sched->sync_upd_work, sync_upd_work); INIT_WORK(&sched->fw_events_work, process_fw_events_work); =20 + spin_lock_init(&sched->events_lock); + ret =3D drmm_mutex_init(&ptdev->base, &sched->lock); if (ret) return ret; --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 53BC03D7D82 for ; Tue, 25 Aug 2026 08:01:42 +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=1787644904; cv=none; b=Hwt3GvaT9wZ9cFTZ4LFJME/pOwRzgTzGGHJINuIbf5xEllYDMEKQzLasfxkaNE5KeeDrakEXFlDPJrAdtiUgFKdfCw/gKQPJfqArqK+T6x/EB1JovGPutAQkiEB1y0VHUOp65fnSNO6moTK0sa915xn+YNFZqErNX09CP3Lj5nY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644904; c=relaxed/simple; bh=gaNkNRKAasOwOC23lTZpB/dymgiTsNwmRAr3PtaChXg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sUfDSytr8uMNcvvz191yQAHo01IWufkU/4GGaBpHfOXD8U60VLISbXHHs5jAGJIxdEihcC3lrarVNPrgwm2XLGEnckV/I17sAIXf0jDj7fgLP+wPbIrj9ljb2Es6O2XSW1mQ12D+aJjWzANXnQSYZCKTG91E8X4JVvJCvgrl7r0= 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=UobrPBvA; 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="UobrPBvA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644894; bh=gaNkNRKAasOwOC23lTZpB/dymgiTsNwmRAr3PtaChXg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UobrPBvAGYJMz4fZU5ln2Psutsudfy0+JMMy6KKFfxsY1fUSmdvtoBbTlkVg+eWtB yHvozBPWAuj7CNcIQI2epxlxnlcZeW6iOpiEVRlr2fsbfwuGgMUGPkc5+yxfWuK6Uu g942hlXgPw44irO1ZTZZFsrME1Ey9YS660WyvkeTot94OPpRtODO7dQoRwFvjlstTy qL1DspcWMECY8LX1+HCkj/AT/7GUz2XgcpMZMNOq1b9j4XfINLNp+JFidomWKCs8SY F767JzDL6iLlh4A2v9wTdQppoVAiDVrGuX/Kz+bvIrFQ7aBgL9mWWjUkhKMQmWP0gd bwia3zfv5l5eA== Received: from fedora-32.home (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 A04FA17E0D1D; Tue, 25 Aug 2026 10:01:33 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:28 +0200 Subject: [PATCH v7 7/9] drm/panthor: Don't defer job completion checks 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: <20260825-panthor-signal-from-irq-v7-7-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=7844; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=gaNkNRKAasOwOC23lTZpB/dymgiTsNwmRAr3PtaChXg=; b=ENi7eIceiB+4bA/GYnM4s5stCbSeGP/WEelqm1HSp3YXI9OYo49Yw1FpmbHqGE/M/SrsHfu6T WxgciROV17kCwWH3mHN5q8hkhInZLwD1brlHRjdWRt+AdqpRU8NA6i3 X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Call group_check_job_completion() directly from csg_slot_sync_update_locked() instead of deferring it. Reviewed-by: Steven Price Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 182 +++++++++++++++-------------= ---- 1 file changed, 87 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 5e1bf52fa282..64b5fc1a0984 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -698,9 +698,6 @@ struct panthor_group { */ struct panthor_kernel_bo *protm_suspend_buf; =20 - /** @sync_upd_work: Work used to check/signal job fences. */ - struct work_struct sync_upd_work; - /** @tiler_oom_work: Work used to process tiler OOM events happening on t= his group. */ struct work_struct tiler_oom_work; =20 @@ -1763,6 +1760,92 @@ static void csg_slot_process_idle_event_locked(struc= t panthor_device *ptdev, u32 sched_queue_delayed_work(sched, tick, 0); } =20 +static void update_fdinfo_stats(struct panthor_job *job) +{ + struct panthor_group *group =3D job->group; + struct panthor_queue *queue =3D group->queues[job->queue_idx]; + struct panthor_gpu_usage *fdinfo =3D &group->fdinfo.data; + struct panthor_job_profiling_data *slots =3D queue->profiling.slots->kmap; + struct panthor_job_profiling_data *data =3D &slots[job->profiling.slot]; + + scoped_guard(spinlock, &group->fdinfo.lock) { + if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES) + fdinfo->cycles +=3D data->cycles.after - data->cycles.before; + if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP) + fdinfo->time +=3D data->time.after - data->time.before; + } +} + +static bool queue_check_job_completion(struct panthor_queue *queue) +{ + struct panthor_syncobj_64b *syncobj =3D NULL; + struct panthor_job *job, *job_tmp; + bool cookie, progress =3D false; + LIST_HEAD(done_jobs); + + cookie =3D dma_fence_begin_signalling(); + scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) { + list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs,= node) { + if (!syncobj) { + struct panthor_group *group =3D job->group; + + syncobj =3D group->syncobjs->kmap + + (job->queue_idx * sizeof(*syncobj)); + } + + if (syncobj->seqno < job->done_fence->seqno) + break; + + list_move_tail(&job->node, &done_jobs); + dma_fence_signal_locked(job->done_fence); + } + + if (list_empty(&queue->fence_ctx.in_flight_jobs)) { + /* If we have no job left, we cancel the timer, and reset remaining + * time to its default so it can be restarted next time + * queue_resume_timeout() is called. + */ + queue_suspend_timeout_locked(queue); + + /* If there's no job pending, we consider it progress to avoid a + * spurious timeout if the timeout handler and the sync update + * handler raced. + */ + progress =3D true; + } else if (!list_empty(&done_jobs)) { + queue_reset_timeout_locked(queue); + progress =3D true; + } + } + dma_fence_end_signalling(cookie); + + list_for_each_entry_safe(job, job_tmp, &done_jobs, node) { + if (job->profiling.mask) + update_fdinfo_stats(job); + list_del_init(&job->node); + panthor_job_put(&job->base); + } + + return progress; +} + +static void group_check_job_completion(struct panthor_group *group) +{ + u32 queue_idx; + bool cookie; + + cookie =3D dma_fence_begin_signalling(); + for (queue_idx =3D 0; queue_idx < group->queue_count; queue_idx++) { + struct panthor_queue *queue =3D group->queues[queue_idx]; + + if (!queue) + continue; + + queue_check_job_completion(queue); + } + dma_fence_end_signalling(cookie); +} + static void csg_slot_sync_update_locked(struct panthor_device *ptdev, u32 csg_id) { @@ -1772,7 +1855,7 @@ static void csg_slot_sync_update_locked(struct pantho= r_device *ptdev, lockdep_assert_held(&ptdev->scheduler->events_lock); =20 if (group) - group_queue_work(group, sync_upd); + group_check_job_completion(group); =20 sched_queue_work(ptdev->scheduler, sync_upd); } @@ -3044,22 +3127,6 @@ void panthor_sched_post_reset(struct panthor_device = *ptdev, bool reset_failed) } } =20 -static void update_fdinfo_stats(struct panthor_job *job) -{ - struct panthor_group *group =3D job->group; - struct panthor_queue *queue =3D group->queues[job->queue_idx]; - struct panthor_gpu_usage *fdinfo =3D &group->fdinfo.data; - struct panthor_job_profiling_data *slots =3D queue->profiling.slots->kmap; - struct panthor_job_profiling_data *data =3D &slots[job->profiling.slot]; - - scoped_guard(spinlock, &group->fdinfo.lock) { - if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES) - fdinfo->cycles +=3D data->cycles.after - data->cycles.before; - if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP) - fdinfo->time +=3D data->time.after - data->time.before; - } -} - void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile) { struct panthor_group_pool *gpool =3D pfile->groups; @@ -3080,80 +3147,6 @@ void panthor_fdinfo_gather_group_samples(struct pant= hor_file *pfile) xa_unlock(&gpool->xa); } =20 -static bool queue_check_job_completion(struct panthor_queue *queue) -{ - struct panthor_syncobj_64b *syncobj =3D NULL; - struct panthor_job *job, *job_tmp; - bool cookie, progress =3D false; - LIST_HEAD(done_jobs); - - cookie =3D dma_fence_begin_signalling(); - scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) { - list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs,= node) { - if (!syncobj) { - struct panthor_group *group =3D job->group; - - syncobj =3D group->syncobjs->kmap + - (job->queue_idx * sizeof(*syncobj)); - } - - if (syncobj->seqno < job->done_fence->seqno) - break; - - list_move_tail(&job->node, &done_jobs); - dma_fence_signal_locked(job->done_fence); - } - - if (list_empty(&queue->fence_ctx.in_flight_jobs)) { - /* If we have no job left, we cancel the timer, and reset remaining - * time to its default so it can be restarted next time - * queue_resume_timeout() is called. - */ - queue_suspend_timeout_locked(queue); - - /* If there's no job pending, we consider it progress to avoid a - * spurious timeout if the timeout handler and the sync update - * handler raced. - */ - progress =3D true; - } else if (!list_empty(&done_jobs)) { - queue_reset_timeout_locked(queue); - progress =3D true; - } - } - dma_fence_end_signalling(cookie); - - list_for_each_entry_safe(job, job_tmp, &done_jobs, node) { - if (job->profiling.mask) - update_fdinfo_stats(job); - list_del_init(&job->node); - panthor_job_put(&job->base); - } - - return progress; -} - -static void group_sync_upd_work(struct work_struct *work) -{ - struct panthor_group *group =3D - container_of(work, struct panthor_group, sync_upd_work); - u32 queue_idx; - bool cookie; - - cookie =3D dma_fence_begin_signalling(); - for (queue_idx =3D 0; queue_idx < group->queue_count; queue_idx++) { - struct panthor_queue *queue =3D group->queues[queue_idx]; - - if (!queue) - continue; - - queue_check_job_completion(queue); - } - dma_fence_end_signalling(cookie); - - group_put(group); -} - struct panthor_job_ringbuf_instrs { u64 buffer[MAX_INSTRS_PER_JOB]; u32 count; @@ -3719,7 +3712,6 @@ int panthor_group_create(struct panthor_file *pfile, INIT_LIST_HEAD(&group->wait_node); INIT_LIST_HEAD(&group->run_node); INIT_WORK(&group->term_work, group_term_work); - INIT_WORK(&group->sync_upd_work, group_sync_upd_work); INIT_WORK(&group->tiler_oom_work, group_tiler_oom_work); INIT_WORK(&group->release_work, group_release_work); =20 --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 53ABD3D7D80 for ; Tue, 25 Aug 2026 08:01:42 +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=1787644904; cv=none; b=UYZJM2K6k3ZKrC2aT388PkV1CfcNl1PL3VsNFPJT7/eQOlWkRY9PfqvgBdOPLVYnJIreUThEKLqPOCdmc3ByD1oEb0WtGQdGeQw91c3vx3iktp8fOOmg00t0YUK5IBDq3yTGcMnZVJ2rtvwbrBJ/LF4iQB0IO5N0rwv3kPAaBHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644904; c=relaxed/simple; bh=ZOzLnpEc74qf635B40vazgd019LdXi45edpX3TzczUI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GoxTGsJrJGD8cUyLtgzZS/kboZ/6LJxGFLHxQO+16Ji6ZbP4K2Jxr7hf5X84Rx7doSNfsEwx+f5HKNUq2rXCbDsLy7VFpnDjEMKiqmnVNODVRnLa/dQEbNYwGRloLnGy91mp7QcDiVHoYTLzWH/kzJUbiJqGzh7TTsAIhxihI98= 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=PnuhYEex; 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="PnuhYEex" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644894; bh=ZOzLnpEc74qf635B40vazgd019LdXi45edpX3TzczUI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PnuhYEexhlIq6nmil8N9oaD/CM2tJ0zPBqPwABN7sMofvul22X4JzpegNkfXk/3Kk uF8BuhPnLorhrbvshZNCW+9BHWvph6If0RGeBflBVcj69bwPBET+/uOQ941fOonmWE 8XHOeT8UB8+auAHd0uQD5CRxyfJMZ0I5xB2MjRRsswxnPAl3X2OmEOVDG1C0QRtTE9 qKIHAryjyaKPRABHxLtBtQQo5Y4pnEIrqRhN9W3/+bG0RE+vyAVv6QI9+eS0ATG/dA C1vL5hf1OeqVLuD1XeH24Q9zsrngbHE6G6P3U8swNQ1HY9qFz1kZIIHNxENzXDUsni pdOS9sivhFnfQ== Received: from fedora-32.home (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 3327A17E0D48; Tue, 25 Aug 2026 10:01:34 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:29 +0200 Subject: [PATCH v7 8/9] drm/panthor: Don't defer FW event processing 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: <20260825-panthor-signal-from-irq-v7-8-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=3573; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=ZOzLnpEc74qf635B40vazgd019LdXi45edpX3TzczUI=; b=NJ7rZTr5SWXXPkHXGgAmwm2JAShHnuciu2C4RubLPOhCR6nyVteZFdupFFYVFLAOoLI2T8PbC nXuAeNbItNLDFC1261NjoW27uvn9fL+AeE0r5AFSOJ28BKY+9BuaJ93 X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Avoid a workqueue roundtrip and process things immediately from panthor_sched_report_fw_events(). Reviewed-by: Liviu Dudau Reviewed-by: Steven Price Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 48 +++++++----------------------= ---- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 64b5fc1a0984..7f99745ff404 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -177,23 +177,6 @@ struct panthor_scheduler { */ struct work_struct sync_upd_work; =20 - /** - * @fw_events_work: Work used to process FW events outside the interrupt = path. - * - * Even if the interrupt is threaded, we need any event processing - * that require taking the panthor_scheduler::lock to be processed - * outside the interrupt path so we don't block the tick logic when - * it calls panthor_fw_{csg,wait}_wait_acks(). Since most of the - * event processing requires taking this lock, we just delegate all - * FW event processing to the scheduler workqueue. - */ - struct work_struct fw_events_work; - - /** - * @fw_events: Bitmask encoding pending FW events. - */ - atomic_t fw_events; - /** * @resched_target: When the next tick should occur. * @@ -1972,14 +1955,17 @@ static void sched_process_global_irq_locked(struct = panthor_device *ptdev) sched_process_idle_event_locked(ptdev); } =20 -static void process_fw_events_work(struct work_struct *work) +/** + * panthor_sched_report_fw_events() - Report FW events to the scheduler. + * @ptdev: Device. + * @events: Bitmask of pending FW events to report. + */ +void panthor_sched_report_fw_events(struct panthor_device *ptdev, u32 even= ts) { - struct panthor_scheduler *sched =3D container_of(work, struct panthor_sch= eduler, - fw_events_work); - u32 events =3D atomic_xchg(&sched->fw_events, 0); - struct panthor_device *ptdev =3D sched->ptdev; + if (!ptdev->scheduler) + return; =20 - guard(spinlock)(&sched->events_lock); + guard(spinlock)(&ptdev->scheduler->events_lock); =20 if (events & JOB_INT_GLOBAL_IF) { sched_process_global_irq_locked(ptdev); @@ -1994,20 +1980,6 @@ static void process_fw_events_work(struct work_struc= t *work) } } =20 -/** - * panthor_sched_report_fw_events() - Report FW events to the scheduler. - * @ptdev: Device. - * @events: Bitmask of pending FW events to report. - */ -void panthor_sched_report_fw_events(struct panthor_device *ptdev, u32 even= ts) -{ - if (!ptdev->scheduler) - return; - - atomic_or(events, &ptdev->scheduler->fw_events); - sched_queue_work(ptdev->scheduler, fw_events); -} - static const char *fence_get_driver_name(struct dma_fence *fence) { return "panthor"; @@ -4083,7 +4055,6 @@ void panthor_sched_unplug(struct panthor_device *ptde= v) struct panthor_scheduler *sched =3D ptdev->scheduler; =20 disable_delayed_work_sync(&sched->tick_work); - disable_work_sync(&sched->fw_events_work); disable_work_sync(&sched->sync_upd_work); =20 mutex_lock(&sched->lock); @@ -4168,7 +4139,6 @@ int panthor_sched_init(struct panthor_device *ptdev) sched->tick_period =3D msecs_to_jiffies(10); INIT_DELAYED_WORK(&sched->tick_work, tick_work); INIT_WORK(&sched->sync_upd_work, sync_upd_work); - INIT_WORK(&sched->fw_events_work, process_fw_events_work); =20 spin_lock_init(&sched->events_lock); =20 --=20 2.55.0 From nobody Mon Sep 28 07:19:42 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 539BD3D7D7E for ; Tue, 25 Aug 2026 08:01:42 +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=1787644904; cv=none; b=kFTndzzyA9q+45g7LVTS+FrW9N2MHrSL6L/6xSeGGfsj8x/jFSy88NNYiAR0RRwo6PkFPwB6Qpb8Tl3NE/wPwtmGEUNGgSZOsNgH3VyozFFlj3qAP5zpP+UWt3VhA0yTqwTC8E4w1McO69OyG/V0nm1W08pNKNbMl5T7Si7Gj5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787644904; c=relaxed/simple; bh=44loqDAeBJ9qoMVgI7evmyZ62X5Ajr1hRTSjwtXDoPI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VoMh7wX47m9QFTFmYkFxHSYts2xxn/um+Dos0yC5obZvkCewvndUqaxSahEqAlAab6PFvslLrMhlPwVQCzwkKk6N/+pRXQ86YETPBHA44SSNs1pvxZfA4jBOdDFcClZGFqYeuXmdrcJ9OmFZJmrnh2DvHEl5SLYyAvxjyY52+50= 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=EWglO94I; 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="EWglO94I" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1787644895; bh=44loqDAeBJ9qoMVgI7evmyZ62X5Ajr1hRTSjwtXDoPI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EWglO94IfbmLkSZsboOsC5aBscJUBPiiHiT9vfd0IPhZhwUyFYeEw6IPrgRJhQXGz B/o+sxgun9uSK2ZBed+OhNX4LGIWbqSx6UilMNQxm8is3U1Gp5+t/JaX39NNQhIOi7 BI0j6X5cCMWlMcmJgUEJhITWxfbhm9NIzEr5Wo4tQd3Iu6UDsXIbEMiYEInxjIvrUK ODoO7Q+3lZ4IfX/RyXTPn9HMD4qUjVTH+DBCcxlmczNdPNYuulSglcJ/jTunSP21EQ EV8jfdrcU0nAS5pQpCib//0x/quXyvldCm5sdjW9HGDvCC31zMjAUjPB09Nj8riPtV NS2tjiHlzMe0A== Received: from fedora-32.home (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 B826E17E0D4B; Tue, 25 Aug 2026 10:01:34 +0200 (CEST) From: Boris Brezillon Date: Tue, 25 Aug 2026 10:01:30 +0200 Subject: [PATCH v7 9/9] drm/panthor: Automate CSG IRQ processing at group unbind time 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: <20260825-panthor-signal-from-irq-v7-9-ebb5b4c891a4@collabora.com> References: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> In-Reply-To: <20260825-panthor-signal-from-irq-v7-0-ebb5b4c891a4@collabora.com> To: Steven Price , Liviu Dudau , Chia-I Wu Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787644889; l=6913; i=boris.brezillon@collabora.com; s=20260429; h=from:subject:message-id; bh=44loqDAeBJ9qoMVgI7evmyZ62X5Ajr1hRTSjwtXDoPI=; b=0OpdvkvCvNubVa44fSeKKs3KiBWg1jAzEP32MF9EWjVvFKGr7cOMXuq9aWqh3qZSQJtnXZzMh PKfmlAysJxvD8r+hqOBau+vsBqjo7T4Lvpgy4wdSVAq94n9JF2jvmdJ X-Developer-Key: i=boris.brezillon@collabora.com; a=ed25519; pk=eN+ORdOgQY7d5U+0kA8h5bf67XdD8bhKbjD/TCHexSY= Make the sched_process_csg_irq_locked() call part of group_unbind_locked() so we don't have to manually call it in tick_ctx_apply()/panthor_sched_suspend(). This implies moving group_[un]bind_locked() around to avoid a forward declaration. Reviewed-by: Steven Price Reviewed-by: Chia-I Wu Reviewed-by: Liviu Dudau Signed-off-by: Boris Brezillon --- drivers/gpu/drm/panthor/panthor_sched.c | 182 +++++++++++++++-------------= ---- 1 file changed, 84 insertions(+), 98 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/pant= hor/panthor_sched.c index 7f99745ff404..42adfc76b9e1 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -990,87 +990,6 @@ group_get(struct panthor_group *group) return group; } =20 -/** - * group_bind_locked() - Bind a group to a group slot - * @group: Group. - * @csg_id: Slot. - * - * Return: 0 on success, a negative error code otherwise. - */ -static int -group_bind_locked(struct panthor_group *group, u32 csg_id) -{ - struct panthor_device *ptdev =3D group->ptdev; - int ret; - - lockdep_assert_held(&ptdev->scheduler->lock); - - if (drm_WARN_ON(&ptdev->base, group->csg_id !=3D -1 || csg_id >=3D MAX_CS= GS || - ptdev->scheduler->csg_slots[csg_id].group)) - return -EINVAL; - - ret =3D panthor_vm_active(group->vm); - if (ret) - return ret; - - group_get(group); - - /* Dummy doorbell allocation: doorbell is assigned to the group and - * all queues use the same doorbell. - * - * TODO: Implement LRU-based doorbell assignment, so the most often - * updated queues get their own doorbell, thus avoiding useless checks - * on queues belonging to the same group that are rarely updated. - */ - for (u32 i =3D 0; i < group->queue_count; i++) - group->queues[i]->doorbell_id =3D csg_id + 1; - - scoped_guard(spinlock, &ptdev->scheduler->events_lock) { - ptdev->scheduler->csg_slots[csg_id].group =3D group; - group->csg_id =3D csg_id; - } - - return 0; -} - -/** - * group_unbind_locked() - Unbind a group from a slot. - * @group: Group to unbind. - * - * Return: 0 on success, a negative error code otherwise. - */ -static int -group_unbind_locked(struct panthor_group *group) -{ - struct panthor_device *ptdev =3D group->ptdev; - - lockdep_assert_held(&ptdev->scheduler->lock); - - if (drm_WARN_ON(&ptdev->base, group->csg_id < 0 || group->csg_id >=3D MAX= _CSGS)) - return -EINVAL; - - if (drm_WARN_ON(&ptdev->base, group->state =3D=3D PANTHOR_CS_GROUP_ACTIVE= )) - return -EINVAL; - - scoped_guard(spinlock, &ptdev->scheduler->events_lock) { - ptdev->scheduler->csg_slots[group->csg_id].group =3D NULL; - group->csg_id =3D -1; - } - - panthor_vm_idle(group->vm); - - /* Tiler OOM events will be re-issued next time the group is scheduled. */ - atomic_set(&group->tiler_oom, 0); - if (cancel_work(&group->tiler_oom_work)) - group_put(group); - - for (u32 i =3D 0; i < group->queue_count; i++) - group->queues[i]->doorbell_id =3D -1; - - group_put(group); - return 0; -} - static bool group_is_idle(struct panthor_group *group) { @@ -1980,6 +1899,89 @@ void panthor_sched_report_fw_events(struct panthor_d= evice *ptdev, u32 events) } } =20 +/** + * group_bind_locked() - Bind a group to a group slot + * @group: Group. + * @csg_id: Slot. + * + * Return: 0 on success, a negative error code otherwise. + */ +static int +group_bind_locked(struct panthor_group *group, u32 csg_id) +{ + struct panthor_device *ptdev =3D group->ptdev; + int ret; + + lockdep_assert_held(&ptdev->scheduler->lock); + + if (drm_WARN_ON(&ptdev->base, group->csg_id !=3D -1 || csg_id >=3D MAX_CS= GS || + ptdev->scheduler->csg_slots[csg_id].group)) + return -EINVAL; + + ret =3D panthor_vm_active(group->vm); + if (ret) + return ret; + + group_get(group); + + /* Dummy doorbell allocation: doorbell is assigned to the group and + * all queues use the same doorbell. + * + * TODO: Implement LRU-based doorbell assignment, so the most often + * updated queues get their own doorbell, thus avoiding useless checks + * on queues belonging to the same group that are rarely updated. + */ + for (u32 i =3D 0; i < group->queue_count; i++) + group->queues[i]->doorbell_id =3D csg_id + 1; + + scoped_guard(spinlock, &ptdev->scheduler->events_lock) { + ptdev->scheduler->csg_slots[csg_id].group =3D group; + group->csg_id =3D csg_id; + } + + return 0; +} + +/** + * group_unbind_locked() - Unbind a group from a slot. + * @group: Group to unbind. + * + * Return: 0 on success, a negative error code otherwise. + */ +static int +group_unbind_locked(struct panthor_group *group) +{ + struct panthor_device *ptdev =3D group->ptdev; + + lockdep_assert_held(&ptdev->scheduler->lock); + + if (drm_WARN_ON(&ptdev->base, group->csg_id < 0 || group->csg_id >=3D MAX= _CSGS)) + return -EINVAL; + + if (drm_WARN_ON(&ptdev->base, group->state =3D=3D PANTHOR_CS_GROUP_ACTIVE= )) + return -EINVAL; + + scoped_guard(spinlock, &ptdev->scheduler->events_lock) { + /* Process all pending IRQs before returning the slot. */ + sched_process_csg_irq_locked(ptdev, group->csg_id); + ptdev->scheduler->csg_slots[group->csg_id].group =3D NULL; + group->csg_id =3D -1; + } + + panthor_vm_idle(group->vm); + + /* Tiler OOM events will be re-issued next time the group is scheduled. */ + atomic_set(&group->tiler_oom, 0); + if (cancel_work(&group->tiler_oom_work)) + group_put(group); + + for (u32 i =3D 0; i < group->queue_count; i++) + group->queues[i]->doorbell_id =3D -1; + + group_put(group); + return 0; +} + static const char *fence_get_driver_name(struct dma_fence *fence) { return "panthor"; @@ -2406,18 +2408,8 @@ tick_ctx_apply(struct panthor_scheduler *sched, stru= ct panthor_sched_tick_ctx *c =20 /* Unbind evicted groups. */ for (prio =3D PANTHOR_CSG_PRIORITY_COUNT - 1; prio >=3D 0; prio--) { - list_for_each_entry(group, &ctx->old_groups[prio], run_node) { - /* This group is gone. Process interrupts to clear - * any pending interrupts before we start the new - * group. - */ - if (group->csg_id >=3D 0) { - guard(spinlock)(&sched->events_lock); - sched_process_csg_irq_locked(ptdev, group->csg_id); - } - + list_for_each_entry(group, &ctx->old_groups[prio], run_node) group_unbind_locked(group); - } } =20 for (i =3D 0; i < sched->csg_slot_count; i++) { @@ -3011,12 +3003,6 @@ void panthor_sched_suspend(struct panthor_device *pt= dev) continue; =20 group_get(group); - - if (group->csg_id >=3D 0) { - guard(spinlock)(&sched->events_lock); - sched_process_csg_irq_locked(ptdev, group->csg_id); - } - group_unbind_locked(group); =20 drm_WARN_ON(&group->ptdev->base, !list_empty(&group->run_node)); --=20 2.55.0