diff mbox series

spi: Fix per-cpu stats access on 32 bit systems

Message ID 20220609121334.2984808-1-david@protonic.nl (mailing list archive)
State Accepted
Commit 67b9d64139e13621d3ab8bb0daad7602e5fe0778
Headers show
Series spi: Fix per-cpu stats access on 32 bit systems | expand

Commit Message

David Jander June 9, 2022, 12:13 p.m. UTC
On 32 bit systems, the following kernel BUG is hit:

BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
caller is debug_smp_processor_id+0x18/0x24
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.19.0-rc1-00001-g6ae0aec8a366 #181
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
 dump_backtrace from show_stack+0x20/0x24
 r7:81024ffd r6:00000000 r5:81024ffd r4:60000013
 show_stack from dump_stack_lvl+0x60/0x78
 dump_stack_lvl from dump_stack+0x14/0x1c
 r7:81024ffd r6:80f652de r5:80bec180 r4:819a2500
 dump_stack from check_preemption_disabled+0xc8/0xf0
 check_preemption_disabled from debug_smp_processor_id+0x18/0x24
 r8:8119b7e0 r7:81205534 r6:819f5c00 r5:819f4c00 r4:c083d724
 debug_smp_processor_id from __spi_sync+0x78/0x220
 __spi_sync from spi_sync+0x34/0x4c
 r10:bb7bf4e0 r9:c083d724 r8:00000007 r7:81a068c0 r6:822a83c0 r5:c083d724
 r4:819f4c00
 spi_sync from spi_mem_exec_op+0x338/0x370
 r5:000000b4 r4:c083d910
 spi_mem_exec_op from spi_nor_read_id+0x98/0xdc
 r10:bb7bf4e0 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:82358040
 r4:819f7c40
 spi_nor_read_id from spi_nor_detect+0x38/0x114
 r7:82358040 r6:00000000 r5:819f7c40 r4:819f7c40
 spi_nor_detect from spi_nor_scan+0x11c/0xbec
 r10:bb7bf4e0 r9:00000000 r8:00000000 r7:c083da4c r6:00000000 r5:00010101
 r4:819f7c40
 spi_nor_scan from spi_nor_probe+0x10c/0x2d0
 r10:bb7bf4e0 r9:bb7bf4d0 r8:00000000 r7:819f4c00 r6:00000000 r5:00000000
 r4:819f7c40

per-cpu access needs to be guarded against preemption.

Fixes: 6598b91b5ac3 ("spi: spi.c: Convert statistics to per-cpu u64_stats_t")
Reported-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: David Jander <david@protonic.nl>
---
 drivers/spi/spi.c       |  5 ++++-
 include/linux/spi/spi.h | 10 ++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

Comments

Nícolas F. R. A. Prado June 9, 2022, 9:08 p.m. UTC | #1
On Thu, Jun 09, 2022 at 02:13:34PM +0200, David Jander wrote:
> On 32 bit systems, the following kernel BUG is hit:
> 
> BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
> caller is debug_smp_processor_id+0x18/0x24
> CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.19.0-rc1-00001-g6ae0aec8a366 #181
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> Backtrace:
>  dump_backtrace from show_stack+0x20/0x24
>  r7:81024ffd r6:00000000 r5:81024ffd r4:60000013
>  show_stack from dump_stack_lvl+0x60/0x78
>  dump_stack_lvl from dump_stack+0x14/0x1c
>  r7:81024ffd r6:80f652de r5:80bec180 r4:819a2500
>  dump_stack from check_preemption_disabled+0xc8/0xf0
>  check_preemption_disabled from debug_smp_processor_id+0x18/0x24
>  r8:8119b7e0 r7:81205534 r6:819f5c00 r5:819f4c00 r4:c083d724
>  debug_smp_processor_id from __spi_sync+0x78/0x220
>  __spi_sync from spi_sync+0x34/0x4c
>  r10:bb7bf4e0 r9:c083d724 r8:00000007 r7:81a068c0 r6:822a83c0 r5:c083d724
>  r4:819f4c00
>  spi_sync from spi_mem_exec_op+0x338/0x370
>  r5:000000b4 r4:c083d910
>  spi_mem_exec_op from spi_nor_read_id+0x98/0xdc
>  r10:bb7bf4e0 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:82358040
>  r4:819f7c40
>  spi_nor_read_id from spi_nor_detect+0x38/0x114
>  r7:82358040 r6:00000000 r5:819f7c40 r4:819f7c40
>  spi_nor_detect from spi_nor_scan+0x11c/0xbec
>  r10:bb7bf4e0 r9:00000000 r8:00000000 r7:c083da4c r6:00000000 r5:00010101
>  r4:819f7c40
>  spi_nor_scan from spi_nor_probe+0x10c/0x2d0
>  r10:bb7bf4e0 r9:bb7bf4d0 r8:00000000 r7:819f4c00 r6:00000000 r5:00000000
>  r4:819f7c40
> 
> per-cpu access needs to be guarded against preemption.
> 
> Fixes: 6598b91b5ac3 ("spi: spi.c: Convert statistics to per-cpu u64_stats_t")
> Reported-by: Marc Kleine-Budde <mkl@pengutronix.de>
> Signed-off-by: David Jander <david@protonic.nl>

Hi, the issue isn't 32-bit specific. I'm seeing it on an aarch64 machine
(mt8192-asurada-spherion) running next-20220609.

The fix did work for me, so

Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>

Thanks!
Nícolas
Andy Shevchenko June 10, 2022, 2:05 p.m. UTC | #2
On Thu, Jun 9, 2022 at 2:29 PM David Jander <david@protonic.nl> wrote:
>
> On 32 bit systems, the following kernel BUG is hit:
>
> BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#backtraces-in-commit-mesages
Mark Brown June 10, 2022, 3:59 p.m. UTC | #3
On Thu, 9 Jun 2022 14:13:34 +0200, David Jander wrote:
> On 32 bit systems, the following kernel BUG is hit:
> 
> BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
> caller is debug_smp_processor_id+0x18/0x24
> CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.19.0-rc1-00001-g6ae0aec8a366 #181
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> Backtrace:
>  dump_backtrace from show_stack+0x20/0x24
>  r7:81024ffd r6:00000000 r5:81024ffd r4:60000013
>  show_stack from dump_stack_lvl+0x60/0x78
>  dump_stack_lvl from dump_stack+0x14/0x1c
>  r7:81024ffd r6:80f652de r5:80bec180 r4:819a2500
>  dump_stack from check_preemption_disabled+0xc8/0xf0
>  check_preemption_disabled from debug_smp_processor_id+0x18/0x24
>  r8:8119b7e0 r7:81205534 r6:819f5c00 r5:819f4c00 r4:c083d724
>  debug_smp_processor_id from __spi_sync+0x78/0x220
>  __spi_sync from spi_sync+0x34/0x4c
>  r10:bb7bf4e0 r9:c083d724 r8:00000007 r7:81a068c0 r6:822a83c0 r5:c083d724
>  r4:819f4c00
>  spi_sync from spi_mem_exec_op+0x338/0x370
>  r5:000000b4 r4:c083d910
>  spi_mem_exec_op from spi_nor_read_id+0x98/0xdc
>  r10:bb7bf4e0 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:82358040
>  r4:819f7c40
>  spi_nor_read_id from spi_nor_detect+0x38/0x114
>  r7:82358040 r6:00000000 r5:819f7c40 r4:819f7c40
>  spi_nor_detect from spi_nor_scan+0x11c/0xbec
>  r10:bb7bf4e0 r9:00000000 r8:00000000 r7:c083da4c r6:00000000 r5:00010101
>  r4:819f7c40
>  spi_nor_scan from spi_nor_probe+0x10c/0x2d0
>  r10:bb7bf4e0 r9:bb7bf4d0 r8:00000000 r7:819f4c00 r6:00000000 r5:00000000
>  r4:819f7c40
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: Fix per-cpu stats access on 32 bit systems
      commit: 67b9d64139e13621d3ab8bb0daad7602e5fe0778

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark
diff mbox series

Patch

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d94822bf3cec..ac61824b87b5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -314,11 +314,13 @@  static void spi_statistics_add_transfer_stats(struct spi_statistics *pcpu_stats,
 					      struct spi_controller *ctlr)
 {
 	int l2len = min(fls(xfer->len), SPI_STATISTICS_HISTO_SIZE) - 1;
-	struct spi_statistics *stats = this_cpu_ptr(pcpu_stats);
+	struct spi_statistics *stats;
 
 	if (l2len < 0)
 		l2len = 0;
 
+	get_cpu();
+	stats = this_cpu_ptr(pcpu_stats);
 	u64_stats_update_begin(&stats->syncp);
 
 	u64_stats_inc(&stats->transfers);
@@ -333,6 +335,7 @@  static void spi_statistics_add_transfer_stats(struct spi_statistics *pcpu_stats,
 		u64_stats_add(&stats->bytes_rx, xfer->len);
 
 	u64_stats_update_end(&stats->syncp);
+	put_cpu();
 }
 
 /*
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 2e63b4935deb..c96f526d9a20 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -84,18 +84,24 @@  struct spi_statistics {
 
 #define SPI_STATISTICS_ADD_TO_FIELD(pcpu_stats, field, count)		\
 	do {								\
-		struct spi_statistics *__lstats = this_cpu_ptr(pcpu_stats); \
+		struct spi_statistics *__lstats;			\
+		get_cpu();						\
+		__lstats = this_cpu_ptr(pcpu_stats);			\
 		u64_stats_update_begin(&__lstats->syncp);		\
 		u64_stats_add(&__lstats->field, count);			\
 		u64_stats_update_end(&__lstats->syncp);			\
+		put_cpu();						\
 	} while (0)
 
 #define SPI_STATISTICS_INCREMENT_FIELD(pcpu_stats, field)		\
 	do {								\
-		struct spi_statistics *__lstats = this_cpu_ptr(pcpu_stats); \
+		struct spi_statistics *__lstats;			\
+		get_cpu();						\
+		__lstats = this_cpu_ptr(pcpu_stats);			\
 		u64_stats_update_begin(&__lstats->syncp);		\
 		u64_stats_inc(&__lstats->field);			\
 		u64_stats_update_end(&__lstats->syncp);			\
+		put_cpu();						\
 	} while (0)
 
 /**