public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Huang Shijie <b32955@freescale.com>,
	Brian Norris <computersforpeace@gmail.com>
Subject: [PATCH 3.4 24/60] mtd: gpmi: fix kernel BUG due to racing DMA operations
Date: Mon,  2 Dec 2013 11:06:05 -0800	[thread overview]
Message-ID: <20131202190335.579844926@linuxfoundation.org> (raw)
In-Reply-To: <20131202190330.152596462@linuxfoundation.org>

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

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

From: Huang Shijie <b32955@freescale.com>

commit 7b3d2fb92067bcb29f0f085a9fa9fa64920a6646 upstream.

[1] The gpmi uses the nand_command_lp to issue the commands to NAND chips.
    The gpmi issues a DMA operation with gpmi_cmd_ctrl when it handles
    a NAND_CMD_NONE control command. So when we read a page(NAND_CMD_READ0)
    from the NAND, we may send two DMA operations back-to-back.

    If we do not serialize the two DMA operations, we will meet a bug when

    1.1) we enable CONFIG_DMA_API_DEBUG, CONFIG_DMADEVICES_DEBUG,
         and CONFIG_DEBUG_SG.

    1.2) Use the following commands in an UART console and a SSH console:
         cmd 1: while true;do dd if=/dev/mtd0 of=/dev/null;done
         cmd 1: while true;do dd if=/dev/mmcblk0 of=/dev/null;done

    The kernel log shows below:
    -----------------------------------------------------------------
    kernel BUG at lib/scatterlist.c:28!
    Unable to handle kernel NULL pointer dereference at virtual address 00000000
      .........................
    [<80044a0c>] (__bug+0x18/0x24) from [<80249b74>] (sg_next+0x48/0x4c)
    [<80249b74>] (sg_next+0x48/0x4c) from [<80255398>] (debug_dma_unmap_sg+0x170/0x1a4)
    [<80255398>] (debug_dma_unmap_sg+0x170/0x1a4) from [<8004af58>] (dma_unmap_sg+0x14/0x6c)
    [<8004af58>] (dma_unmap_sg+0x14/0x6c) from [<8027e594>] (mxs_dma_tasklet+0x18/0x1c)
    [<8027e594>] (mxs_dma_tasklet+0x18/0x1c) from [<8007d444>] (tasklet_action+0x114/0x164)
    -----------------------------------------------------------------

    1.3) Assume the two DMA operations is X (first) and Y (second).

         The root cause of the bug:
	   Assume process P issues DMA X, and sleep on the completion
	 @this->dma_done. X's tasklet callback is dma_irq_callback. It firstly
	 wake up the process sleeping on the completion @this->dma_done,
	 and then trid to unmap the scatterlist S. The waked process P will
	 issue Y in another ARM core. Y initializes S->sg_magic to zero
	 with sg_init_one(), while dma_irq_callback is unmapping S at the same
	 time.

	 See the diagram:

                   ARM core 0              |         ARM core 1
	 -------------------------------------------------------------
         (P issues DMA X, then sleep)  --> |
                                           |
         (X's tasklet wakes P)         --> |
                                           |
                                           | <-- (P begin to issue DMA Y)
                                           |
         (X's tasklet unmap the            |
      scatterlist S with dma_unmap_sg) --> | <-- (Y calls sg_init_one() to init
                                           |      scatterlist S)
                                           |

[2] This patch serialize both the X and Y in the following way:
     Unmap the DMA scatterlist S firstly, and wake up the process at the end
     of the DMA callback, in such a way, Y will be executed after X.

     After this patch:

                   ARM core 0              |         ARM core 1
	 -------------------------------------------------------------
         (P issues DMA X, then sleep)  --> |
                                           |
         (X's tasklet unmap the            |
      scatterlist S with dma_unmap_sg) --> |
                                           |
         (X's tasklet wakes P)         --> |
                                           |
                                           | <-- (P begin to issue DMA Y)
                                           |
                                           | <-- (Y calls sg_init_one() to init
                                           |     scatterlist S)
                                           |

Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -227,8 +227,6 @@ static void dma_irq_callback(void *param
 	struct gpmi_nand_data *this = param;
 	struct completion *dma_c = &this->dma_done;
 
-	complete(dma_c);
-
 	switch (this->dma_type) {
 	case DMA_FOR_COMMAND:
 		dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE);
@@ -253,6 +251,8 @@ static void dma_irq_callback(void *param
 	default:
 		pr_err("in wrong DMA operation.\n");
 	}
+
+	complete(dma_c);
 }
 
 int start_dma_without_bch_irq(struct gpmi_nand_data *this,



  parent reply	other threads:[~2013-12-02 21:30 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-02 19:05 [PATCH 3.4 00/60] 3.4.72-stable review Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 01/60] ARM: sa11x0/assabet: ensure CS2 is configured appropriately Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 02/60] ARM: integrator_cp: Set LCD{0,1} enable lines when turning on CLCD Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 03/60] Staging: tidspbridge: disable driver Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 04/60] backlight: atmel-pwm-bl: fix reported brightness Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 05/60] ASoC: ak4642: prevent un-necessary changes to SG_SL1 Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 06/60] ASoC: wm8962: Turn on regcache_cache_only before disabling regulator Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 07/60] ASoC: blackfin: Fix missing break Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 08/60] alarmtimer: return EINVAL instead of ENOTSUPP if rtcdev doesnt exist Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 09/60] devpts: plug the memory leak in kill_sb Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 10/60] can: flexcan: fix flexcan_chip_start() on imx6 Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 11/60] libata: Fix display of sata speed Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 12/60] drivers/libata: Set max sector to 65535 for Slimtype DVD A DS8A9SH drive Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 13/60] vsprintf: check real user/group id for %pK Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 14/60] rtlwifi: rtl8192se: Fix wrong assignment Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 15/60] rtlwifi: rtl8192cu: Fix more pointer arithmetic errors Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 16/60] ahci: disabled FBS prior to issuing software reset Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 17/60] ahci: add Marvell 9230 to the AHCI PCI device list Greg Kroah-Hartman
2013-12-02 19:05 ` [PATCH 3.4 18/60] iscsi-target: fix extract_param to handle buffer length corner case Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 19/60] iscsi-target: chap auth shouldnt match username with trailing garbage Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 20/60] IB/ipath: Convert ipath_user_sdma_pin_pages() to use get_user_pages_fast() Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 21/60] loop: fix crash if blk_alloc_queue fails Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 22/60] mtd: nand: hack ONFI for non-power-of-2 dimensions Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 23/60] mtd: map: fixed bug in 64-bit systems Greg Kroah-Hartman
2013-12-02 19:06 ` Greg Kroah-Hartman [this message]
2013-12-02 19:06 ` [PATCH 3.4 25/60] ext4: avoid bh leak in retry path of ext4_expand_extra_isize_ea() Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 26/60] xen/blkback: fix reference counting Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 27/60] staging: vt6656: [BUG] Fix for TX USB resets from vendors driver Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 28/60] rtlwifi: rtl8192de: Fix incorrect signal strength for unassociated AP Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 29/60] rtlwifi: rtl8192se: " Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 30/60] rtlwifi: rtl8192cu: " Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 31/60] qeth: avoid buffer overflow in snmp ioctl Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 32/60] rt2400pci: fix RSSI read Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 33/60] dm: allocate buffer for messages with small number of arguments using GFP_NOIO Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 34/60] PM / hibernate: Avoid overflow in hibernate_preallocate_memory() Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 35/60] mwifiex: correct packet length for packets from SDIO interface Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 36/60] audit: printk USER_AVC messages when audit isnt enabled Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 37/60] audit: use nlmsg_len() to get message payload length Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 38/60] audit: fix info leak in AUDIT_GET requests Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 39/60] PCI: Remove duplicate pci_disable_device() from pcie_portdrv_remove() Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 40/60] selinux: correct locking in selinux_netlbl_socket_connect) Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 41/60] avr32: setup crt for early panic() Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 42/60] avr32: fix out-of-range jump in large kernels Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 43/60] prism54: set netdev type to "wlan" Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 44/60] drm/ttm: Handle in-memory region copies Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 45/60] drm/i915: flush cursors harder Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 46/60] drm/nouveau: when bailing out of a pushbuf ioctl, do not remove previous fence Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 47/60] drm/radeon/si: fix define for MC_SEQ_TRAIN_WAKEUP_CNTL Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 48/60] radeon: workaround pinning failure on low ram gpu Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 49/60] md: fix calculation of stacking limits on level change Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 50/60] powerpc/signals: Improved mark VSX not saved with small contexts fix Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 51/60] cpuset: Fix memory allocator deadlock Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 52/60] ALSA: hda/realtek - Set pcbeep amp for ALC668 Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 53/60] tracing: Allow events to have NULL strings Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 54/60] Input: i8042 - add PNP modaliases Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 55/60] KVM: perform an invalid memslot step for gpa base change Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 56/60] KVM: Fix iommu map/unmap to handle memory slot moves Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 57/60] ftrace: Fix function graph with loading of modules Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 58/60] media: lirc_zilog: Dont use dynamic static allocation Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 59/60] HID: roccat: fix Coverity CID 141438 Greg Kroah-Hartman
2013-12-02 19:06 ` [PATCH 3.4 60/60] HID: apple: option to swap the Option ("Alt") and Command ("Flag") keys Greg Kroah-Hartman
2013-12-03  2:50 ` [PATCH 3.4 00/60] 3.4.72-stable review Guenter Roeck
2013-12-03  3:04   ` Greg Kroah-Hartman
2013-12-03 21:56 ` Shuah Khan
2013-12-04 10:23 ` Satoru Takeuchi

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=20131202190335.579844926@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=b32955@freescale.com \
    --cc=computersforpeace@gmail.com \
    --cc=linux-kernel@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox