All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Vladimir Oltean <vladimir.oltean@nxp.com>,
	Michael Walle <michael@walle.cc>, Mark Brown <broonie@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	linux-spi@vger.kernel.org
Subject: [PATCH AUTOSEL 5.5 49/56] spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion
Date: Thu,  9 Apr 2020 23:47:53 -0400	[thread overview]
Message-ID: <20200410034800.8381-49-sashal@kernel.org> (raw)
In-Reply-To: <20200410034800.8381-1-sashal@kernel.org>

From: Vladimir Oltean <vladimir.oltean@nxp.com>

[ Upstream commit 4f5ee75ea1718a09149460b3df993f389a67b56a ]

Currently the driver puts the process in interruptible sleep waiting for
the interrupt train to finish transfer to/from the tx_buf and rx_buf.

But exiting the process with ctrl-c may make the kernel panic: the
wait_event_interruptible call will return -ERESTARTSYS, which a proper
driver implementation is perhaps supposed to handle, but nonetheless
this one doesn't, and aborts the transfer altogether.

Actually when the task is interrupted, there is still a high chance that
the dspi_interrupt is still triggering. And if dspi_transfer_one_message
returns execution all the way to the spi_device driver, that can free
the spi_message and spi_transfer structures, leaving the interrupts to
access a freed tx_buf and rx_buf.

hexdump -C /dev/mtd0
00000000  00 75 68 75 0a ff ff ff  ff ff ff ff ff ff ff ff
|.uhu............|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
|................|
*
^C[   38.495955] fsl-dspi 2120000.spi: Waiting for transfer to complete failed!
[   38.503097] spi_master spi2: failed to transfer one message from queue
[   38.509729] Unable to handle kernel paging request at virtual address ffff800095ab3377
[   38.517676] Mem abort info:
[   38.520474]   ESR = 0x96000045
[   38.523533]   EC = 0x25: DABT (current EL), IL = 32 bits
[   38.528861]   SET = 0, FnV = 0
[   38.531921]   EA = 0, S1PTW = 0
[   38.535067] Data abort info:
[   38.537952]   ISV = 0, ISS = 0x00000045
[   38.541797]   CM = 0, WnR = 1
[   38.544771] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000082621000
[   38.551494] [ffff800095ab3377] pgd=00000020fffff003, p4d=00000020fffff003, pud=0000000000000000
[   38.560229] Internal error: Oops: 96000045 [#1] PREEMPT SMP
[   38.565819] Modules linked in:
[   38.568882] CPU: 0 PID: 2729 Comm: hexdump Not tainted 5.6.0-rc4-next-20200306-00052-gd8730cdc8a0b-dirty #193
[   38.578834] Hardware name: Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier (DT)
[   38.587129] pstate: 20000085 (nzCv daIf -PAN -UAO)
[   38.591941] pc : ktime_get_real_ts64+0x3c/0x110
[   38.596487] lr : spi_take_timestamp_pre+0x40/0x90
[   38.601203] sp : ffff800010003d90
[   38.604525] x29: ffff800010003d90 x28: ffff80001200e000
[   38.609854] x27: ffff800011da9000 x26: ffff002079c40400
[   38.615184] x25: ffff8000117fe018 x24: ffff800011daa1a0
[   38.620513] x23: ffff800015ab3860 x22: ffff800095ab3377
[   38.625841] x21: 000000000000146e x20: ffff8000120c3000
[   38.631170] x19: ffff0020795f6e80 x18: ffff800011da9948
[   38.636498] x17: 0000000000000000 x16: 0000000000000000
[   38.641826] x15: ffff800095ab3377 x14: 0720072007200720
[   38.647155] x13: 0720072007200765 x12: 0775076507750771
[   38.652483] x11: 0720076d076f0772 x10: 0000000000000040
[   38.657812] x9 : ffff8000108e2100 x8 : ffff800011dcabe8
[   38.663139] x7 : 0000000000000000 x6 : ffff800015ab3a60
[   38.668468] x5 : 0000000007200720 x4 : ffff800095ab3377
[   38.673796] x3 : 0000000000000000 x2 : 0000000000000ab0
[   38.679125] x1 : ffff800011daa000 x0 : 0000000000000026
[   38.684454] Call trace:
[   38.686905]  ktime_get_real_ts64+0x3c/0x110
[   38.691100]  spi_take_timestamp_pre+0x40/0x90
[   38.695470]  dspi_fifo_write+0x58/0x2c0
[   38.699315]  dspi_interrupt+0xbc/0xd0
[   38.702987]  __handle_irq_event_percpu+0x78/0x2c0
[   38.707706]  handle_irq_event_percpu+0x3c/0x90
[   38.712161]  handle_irq_event+0x4c/0xd0
[   38.716008]  handle_fasteoi_irq+0xbc/0x170
[   38.720115]  generic_handle_irq+0x2c/0x40
[   38.724135]  __handle_domain_irq+0x68/0xc0
[   38.728243]  gic_handle_irq+0xc8/0x160
[   38.732000]  el1_irq+0xb8/0x180
[   38.735149]  spi_nor_spimem_read_data+0xe0/0x140
[   38.739779]  spi_nor_read+0xc4/0x120
[   38.743364]  mtd_read_oob+0xa8/0xc0
[   38.746860]  mtd_read+0x4c/0x80
[   38.750007]  mtdchar_read+0x108/0x2a0
[   38.753679]  __vfs_read+0x20/0x50
[   38.757002]  vfs_read+0xa4/0x190
[   38.760237]  ksys_read+0x6c/0xf0
[   38.763471]  __arm64_sys_read+0x20/0x30
[   38.767319]  el0_svc_common.constprop.3+0x90/0x160
[   38.772125]  do_el0_svc+0x28/0x90
[   38.775449]  el0_sync_handler+0x118/0x190
[   38.779468]  el0_sync+0x140/0x180
[   38.782793] Code: 91000294 1400000f d50339bf f9405e80 (f90002c0)
[   38.788910] ---[ end trace 55da560db4d6bef7 ]---
[   38.793540] Kernel panic - not syncing: Fatal exception in interrupt
[   38.799914] SMP: stopping secondary CPUs
[   38.803849] Kernel Offset: disabled
[   38.807344] CPU features: 0x10002,20006008
[   38.811451] Memory Limit: none
[   38.814513] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

So it is clear that the "interruptible" part isn't handled correctly.
When the process receives a signal, one could either attempt a clean
abort (which appears to be difficult with this hardware) or just keep
restarting the sleep until the wait queue really completes. But checking
in a loop for -ERESTARTSYS is a bit too complicated for this driver, so
just make the sleep uninterruptible, to avoid all that nonsense.

The wait queue was actually restructured as a completion, after polling
other drivers for the most "popular" approach.

Fixes: 349ad66c0ab0 ("spi:Add Freescale DSPI driver for Vybrid VF610 platform")
Reported-by: Michael Walle <michael@walle.cc>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20200318001603.9650-7-olteanv@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/spi/spi-fsl-dspi.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index a534b8af27b8d..f9d44bb1040f8 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -196,8 +196,7 @@ struct fsl_dspi {
 	u8					bytes_per_word;
 	const struct fsl_dspi_devtype_data	*devtype_data;
 
-	wait_queue_head_t			waitq;
-	u32					waitflags;
+	struct completion			xfer_done;
 
 	struct fsl_dspi_dma			*dma;
 };
@@ -714,10 +713,8 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 	if (!(spi_sr & SPI_SR_EOQF))
 		return IRQ_NONE;
 
-	if (dspi_rxtx(dspi) == 0) {
-		dspi->waitflags = 1;
-		wake_up_interruptible(&dspi->waitq);
-	}
+	if (dspi_rxtx(dspi) == 0)
+		complete(&dspi->xfer_done);
 
 	return IRQ_HANDLED;
 }
@@ -815,13 +812,9 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
 				status = dspi_poll(dspi);
 			} while (status == -EINPROGRESS);
 		} else if (trans_mode != DSPI_DMA_MODE) {
-			status = wait_event_interruptible(dspi->waitq,
-							  dspi->waitflags);
-			dspi->waitflags = 0;
+			wait_for_completion(&dspi->xfer_done);
+			reinit_completion(&dspi->xfer_done);
 		}
-		if (status)
-			dev_err(&dspi->pdev->dev,
-				"Waiting for transfer to complete failed!\n");
 
 		spi_transfer_delay_exec(transfer);
 	}
@@ -1161,7 +1154,7 @@ static int dspi_probe(struct platform_device *pdev)
 		goto out_clk_put;
 	}
 
-	init_waitqueue_head(&dspi->waitq);
+	init_completion(&dspi->xfer_done);
 
 poll_mode:
 
-- 
2.20.1


  parent reply	other threads:[~2020-04-10  3:57 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-10  3:47 [PATCH AUTOSEL 5.5 01/56] cpufreq: imx6q: Fixes unwanted cpu overclocking on i.MX6ULL Sasha Levin
2020-04-10  3:47 ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 02/56] EDAC/mc: Report "unknown memory" on too many DIMM labels found Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 03/56] usb: ucsi: ccg: disable runtime pm during fw flashing Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 04/56] staging: wilc1000: avoid double unlocking of 'wilc->hif_cs' mutex Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 05/56] media: vimc: streamer: fix memory leak in vimc subdevs if kthread_run fails Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 06/56] media: venus: hfi_parser: Ignore HEVC encoding for V1 Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 07/56] firmware: arm_sdei: fix double-lock on hibernate with shared events Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 08/56] driver core: Reevaluate dev->links.need_for_probe as suppliers are added Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 09/56] sched/vtime: Prevent unstable evaluation of WARN(vtime->state) Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 10/56] null_blk: Fix the null_add_dev() error path Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 11/56] blk-mq: Fix a recently introduced regression in blk_mq_realloc_hw_ctxs() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 12/56] null_blk: Handle null_add_dev() failures properly Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 13/56] null_blk: fix spurious IO errors after failed past-wp access Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 14/56] media: imx: imx7_mipi_csis: Power off the source when stopping streaming Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 15/56] media: imx: imx7-media-csi: Fix video field handling Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 16/56] xhci: bail out early if driver can't accress host in resume Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 17/56] ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 18/56] x86: Don't let pgprot_modify() change the page encryption bit Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 19/56] dma-mapping: Fix dma_pgprot() for unencrypted coherent pages Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 20/56] block: keep bdi->io_pages in sync with max_sectors_kb for stacked devices Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 21/56] debugfs: Check module state before warning in {full/open}_proxy_open() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 22/56] spi: spi-fsl-dspi: Avoid NULL pointer in dspi_slave_abort for non-DMA mode Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 23/56] irqchip/versatile-fpga: Handle chained IRQs properly Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 24/56] time/sched_clock: Expire timer in hardirq context Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 25/56] media: allegro: fix type of gop_length in channel_create message Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 26/56] sched: Avoid scale real weight down to zero Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 27/56] sched/fair: Fix condition of avg_load calculation Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 28/56] selftests/x86/ptrace_syscall_32: Fix no-vDSO segfault Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 29/56] PCI/switchtec: Fix init_completion race condition with poll_wait() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 30/56] block, bfq: move forward the getting of an extra ref in bfq_bfqq_move Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 31/56] media: i2c: video-i2c: fix build errors due to 'imply hwmon' Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 32/56] libata: Remove extra scsi_host_put() in ata_scsi_add_hosts() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 33/56] pstore/platform: fix potential mem leak if pstore_init_fs failed Sasha Levin
2020-04-10  3:47 ` [Cluster-devel] [PATCH AUTOSEL 5.5 34/56] gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [Cluster-devel] [PATCH AUTOSEL 5.5 35/56] gfs2: Don't demote a glock until its revokes are written Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 36/56] cpufreq: imx6q: fix error handling Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 37/56] x86/boot: Use unsigned comparison for addresses Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 38/56] efi/x86: Ignore the memory attributes table on i386 Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 39/56] genirq/irqdomain: Check pointer in irq_domain_alloc_irqs_hierarchy() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 40/56] blk-mq: Keep set->nr_hw_queues and set->map[].nr_queues in sync Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 41/56] block: Fix use-after-free issue accessing struct io_cq Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 42/56] block, zoned: fix integer overflow with BLKRESETZONE et al Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 43/56] media: mtk-vpu: avoid unaligned access to DTCM buffer Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 44/56] media: i2c: ov5695: Fix power on and off sequences Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47   ` Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 45/56] usb: dwc3: core: add support for disabling SS instances in park mode Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 46/56] irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 47/56] md: check arrays is suspended in mddev_detach before call quiesce operations Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 48/56] firmware: fix a double abort case with fw_load_sysfs_fallback Sasha Levin
2020-04-10  3:47 ` Sasha Levin [this message]
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 50/56] locking/lockdep: Avoid recursion in lockdep_count_{for,back}ward_deps() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 51/56] block, bfq: fix use-after-free in bfq_idle_slice_timer_body Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 52/56] btrfs: hold a ref on the root in btrfs_recover_relocation Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 53/56] btrfs: qgroup: ensure qgroup_rescan_running is only set when the worker is at least queued Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 54/56] btrfs: remove a BUG_ON() from merge_reloc_roots() Sasha Levin
2020-04-10  3:47 ` [PATCH AUTOSEL 5.5 55/56] btrfs: restart relocate_tree_blocks properly Sasha Levin
2020-04-10  3:48 ` [PATCH AUTOSEL 5.5 56/56] btrfs: track reloc roots based on their commit root bytenr Sasha Levin

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=20200410034800.8381-49-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=michael@walle.cc \
    --cc=stable@vger.kernel.org \
    --cc=vladimir.oltean@nxp.com \
    /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.