All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	"David S. Miller" <davem@davemloft.net>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.15 10/45] u64_stats: Disable preemption on 32bit UP+SMP PREEMPT_RT during updates.
Date: Mon, 15 Apr 2024 16:21:17 +0200	[thread overview]
Message-ID: <20240415141942.551569823@linuxfoundation.org> (raw)
In-Reply-To: <20240415141942.235939111@linuxfoundation.org>

5.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

[ Upstream commit 3c118547f87e930d45a5787e386734015dd93b32 ]

On PREEMPT_RT the seqcount_t for synchronisation is required on 32bit
architectures even on UP because the softirq (and the threaded IRQ handler) can
be preempted.

With the seqcount_t for synchronisation, a reader with higher priority can
preempt the writer and then spin endlessly in read_seqcount_begin() while the
writer can't make progress.

To avoid such a lock up on PREEMPT_RT the writer must disable preemption during
the update. There is no need to disable interrupts because no writer is using
this API in hard-IRQ context on PREEMPT_RT.

Disable preemption on 32bit-RT within the u64_stats write section.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: 38a15d0a50e0 ("u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/u64_stats_sync.h | 42 ++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h
index e81856c0ba134..6a0f2097d3709 100644
--- a/include/linux/u64_stats_sync.h
+++ b/include/linux/u64_stats_sync.h
@@ -66,7 +66,7 @@
 #include <linux/seqlock.h>
 
 struct u64_stats_sync {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 	seqcount_t	seq;
 #endif
 };
@@ -115,7 +115,7 @@ static inline void u64_stats_inc(u64_stats_t *p)
 }
 #endif
 
-#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 #define u64_stats_init(syncp)	seqcount_init(&(syncp)->seq)
 #else
 static inline void u64_stats_init(struct u64_stats_sync *syncp)
@@ -125,15 +125,19 @@ static inline void u64_stats_init(struct u64_stats_sync *syncp)
 
 static inline void u64_stats_update_begin(struct u64_stats_sync *syncp)
 {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
+	if (IS_ENABLED(CONFIG_PREEMPT_RT))
+		preempt_disable();
 	write_seqcount_begin(&syncp->seq);
 #endif
 }
 
 static inline void u64_stats_update_end(struct u64_stats_sync *syncp)
 {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 	write_seqcount_end(&syncp->seq);
+	if (IS_ENABLED(CONFIG_PREEMPT_RT))
+		preempt_enable();
 #endif
 }
 
@@ -142,8 +146,11 @@ u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp)
 {
 	unsigned long flags = 0;
 
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
-	local_irq_save(flags);
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
+	if (IS_ENABLED(CONFIG_PREEMPT_RT))
+		preempt_disable();
+	else
+		local_irq_save(flags);
 	write_seqcount_begin(&syncp->seq);
 #endif
 	return flags;
@@ -153,15 +160,18 @@ static inline void
 u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp,
 				unsigned long flags)
 {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 	write_seqcount_end(&syncp->seq);
-	local_irq_restore(flags);
+	if (IS_ENABLED(CONFIG_PREEMPT_RT))
+		preempt_enable();
+	else
+		local_irq_restore(flags);
 #endif
 }
 
 static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *syncp)
 {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 	return read_seqcount_begin(&syncp->seq);
 #else
 	return 0;
@@ -170,7 +180,7 @@ static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *
 
 static inline unsigned int u64_stats_fetch_begin(const struct u64_stats_sync *syncp)
 {
-#if BITS_PER_LONG==32 && !defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (!defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_RT))
 	preempt_disable();
 #endif
 	return __u64_stats_fetch_begin(syncp);
@@ -179,7 +189,7 @@ static inline unsigned int u64_stats_fetch_begin(const struct u64_stats_sync *sy
 static inline bool __u64_stats_fetch_retry(const struct u64_stats_sync *syncp,
 					 unsigned int start)
 {
-#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT))
 	return read_seqcount_retry(&syncp->seq, start);
 #else
 	return false;
@@ -189,7 +199,7 @@ static inline bool __u64_stats_fetch_retry(const struct u64_stats_sync *syncp,
 static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp,
 					 unsigned int start)
 {
-#if BITS_PER_LONG==32 && !defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && (!defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_RT))
 	preempt_enable();
 #endif
 	return __u64_stats_fetch_retry(syncp, start);
@@ -203,7 +213,9 @@ static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp,
  */
 static inline unsigned int u64_stats_fetch_begin_irq(const struct u64_stats_sync *syncp)
 {
-#if BITS_PER_LONG==32 && !defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && defined(CONFIG_PREEMPT_RT)
+	preempt_disable();
+#elif BITS_PER_LONG == 32 && !defined(CONFIG_SMP)
 	local_irq_disable();
 #endif
 	return __u64_stats_fetch_begin(syncp);
@@ -212,7 +224,9 @@ static inline unsigned int u64_stats_fetch_begin_irq(const struct u64_stats_sync
 static inline bool u64_stats_fetch_retry_irq(const struct u64_stats_sync *syncp,
 					     unsigned int start)
 {
-#if BITS_PER_LONG==32 && !defined(CONFIG_SMP)
+#if BITS_PER_LONG == 32 && defined(CONFIG_PREEMPT_RT)
+	preempt_enable();
+#elif BITS_PER_LONG == 32 && !defined(CONFIG_SMP)
 	local_irq_enable();
 #endif
 	return __u64_stats_fetch_retry(syncp, start);
-- 
2.43.0




  parent reply	other threads:[~2024-04-15 14:44 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-15 14:21 [PATCH 5.15 00/45] 5.15.156-rc1 review Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 01/45] batman-adv: Avoid infinite loop trying to resize local TT Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 02/45] ring-buffer: Only update pages_touched when a new page is touched Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 03/45] Bluetooth: Fix memory leak in hci_req_sync_complete() Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 04/45] media: cec: core: remove length check of Timer Status Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 05/45] arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 06/45] Revert "drm/qxl: simplify qxl_fence_wait" Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 07/45] nouveau: fix function cast warning Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 08/45] scsi: qla2xxx: Fix off by one in qla_edif_app_getstats() Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 09/45] net: openvswitch: fix unwanted error log on timeout policy probing Greg Kroah-Hartman
2024-04-15 14:21 ` Greg Kroah-Hartman [this message]
2024-04-15 14:21 ` [PATCH 5.15 11/45] xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 12/45] geneve: fix header validation in geneve[6]_xmit_skb Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 13/45] af_unix: Clear stale u->oob_skb Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 14/45] octeontx2-af: Fix NIX SQ mode and BP config Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 15/45] ipv6: fib: hide unused pn variable Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 16/45] ipv4/route: avoid unused-but-set-variable warning Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 17/45] ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 18/45] netfilter: complete validation of user input Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 19/45] net/mlx5: Properly link new fs rules into the tree Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 20/45] net: sparx5: fix wrong config being used when reconfiguring PCS Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 21/45] net: dsa: mt7530: trap link-local frames regardless of ST Port State Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 22/45] af_unix: Do not use atomic ops for unix_sk(sk)->inflight Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 23/45] af_unix: Fix garbage collector racing against connect() Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 24/45] net: ena: Fix potential sign extension issue Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 25/45] net: ena: Wrong missing IO completions check order Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 26/45] net: ena: Fix incorrect descriptor free behavior Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 27/45] tracing: hide unused ftrace_event_id_fops Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 28/45] iommu/vt-d: Allocate local memory for page request queue Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 29/45] btrfs: qgroup: correctly model root qgroup rsv in convert Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 30/45] drm/client: Fully protect modes[] with dev->mode_config.mutex Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 31/45] vhost: Add smp_rmb() in vhost_vq_avail_empty() Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 32/45] perf/x86: Fix out of range data Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 33/45] x86/cpu: Actually turn off mitigations by default for SPECULATION_MITIGATIONS=n Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 34/45] selftests: timers: Fix abs() warning in posix_timers test Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 35/45] x86/apic: Force native_apic_mem_read() to use the MOV instruction Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 36/45] irqflags: Explicitly ignore lockdep_hrtimer_exit() argument Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 37/45] x86/bugs: Fix return type of spectre_bhi_state() Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 38/45] x86/bugs: Fix BHI documentation Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 39/45] x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 40/45] x86/bugs: Rename various ia32_cap variables to x86_arch_cap_msr Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 41/45] x86/bugs: Fix BHI handling of RRSBA Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 42/45] x86/bugs: Clarify that syscall hardening isnt a BHI mitigation Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 43/45] x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 44/45] x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with CONFIG_MITIGATION_SPECTRE_BHI Greg Kroah-Hartman
2024-04-15 14:21 ` [PATCH 5.15 45/45] drm/i915/cdclk: Fix CDCLK programming order when pipes are active Greg Kroah-Hartman
2024-04-15 16:47 ` [PATCH 5.15 00/45] 5.15.156-rc1 review Florian Fainelli
2024-04-15 23:53 ` Kelsey Steele
2024-04-16  0:20 ` Mark Brown
2024-04-16  6:45 ` Ron Economos
2024-04-16  7:45 ` Harshit Mogalapalli
2024-04-16 10:37 ` Jon Hunter
2024-04-16 14:30 ` Pascal Ernster
2024-04-16 14:46   ` Greg Kroah-Hartman
2024-04-17  7:12 ` Naresh Kamboju

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20240415141942.551569823@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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