All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Greg KH <gregkh@linuxfoundation.org>
Cc: Felipe Balbi <balbi@ti.com>, Alan Cox <alan@linux.intel.com>,
	Marcel Holtmann <marcel@holtmann.org>,
	Muralidharan Karicheri <m-karicheri2@ti.com>,
	linux-bluetooth@vger.kernel.org, linux-serial@vger.kernel.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Huang Shijie <b32955@freescale.com>
Subject: Re: hci_ldsic nested locking problem
Date: Thu, 20 Mar 2014 14:54:59 -0400	[thread overview]
Message-ID: <532B3983.6040706@hurleysoftware.com> (raw)
In-Reply-To: <20140320184544.GA1113@kroah.com>

On 03/20/2014 02:45 PM, Greg KH wrote:
> On Thu, Mar 20, 2014 at 12:35:18PM -0500, Felipe Balbi wrote:
>> On Thu, Mar 20, 2014 at 01:34:57PM -0400, Peter Hurley wrote:
>>> [ +cc Huang Shijie ]
>>>
>>> On 03/20/2014 01:29 PM, Felipe Balbi wrote:
>>>> then we need updates to Documentation:
>>>>
>>>> Documentation/serial/tty.txt::
>>>>
>>>> |  Driver Side Interfaces:
>>>> |
>>>> |  receive_buf()	-	Hand buffers of bytes from the driver to the ldisc
>>>> |  			for processing. Semantics currently rather
>>>> |  			mysterious 8(
>>>> |
>>>> |  write_wakeup()	-	May be called at any point between open and close.
>>>> |  			The TTY_DO_WRITE_WAKEUP flag indicates if a call
>>>> |  			is needed but always races versus calls. Thus the
>>>> |  			ldisc must be careful about setting order and to
>>>> |  			handle unexpected calls. Must not sleep.
>>>> |
>>>> |  			The driver is forbidden from calling this directly
>>>> |  			from the ->write call from the ldisc as the ldisc
>>>> |  			is permitted to call the driver write method from
>>>> |  			this function. In such a situation defer it.
>>>>
>>>> documentation says ldisc is allowed to call ->write() from
>>>> ->write_wakeup(). huh ?
>>>
>>> Patch submitted but never applied.
>>>
>>> http://www.spinics.net/lists/linux-serial/msg11144.html
>>
>> Thank you. For that patch:
>>
>> Acked-by: Felipe Balbi <balbi@ti.com>
>
> Can someone resend it, this is lost in my tree for some reason...

Apologies if my mailer mangles this.

--- >% ---
From: Huang Shijie <b32955@freescale.com>

In the uart_handle_cts_change(), uart_write_wakeup() is called after
we call @uart_port->ops->start_tx().

The Documentation/serial/driver tells us:
-----------------------------------------------
   start_tx(port)
	Start transmitting characters.

	Locking: port->lock taken.
	Interrupts: locally disabled.
-----------------------------------------------

So when the uart_write_wakeup() is called, the port->lock is taken by
the upper. See the following callstack:

	|_ uart_write_wakeup
	   |_ tty_wakeup
	      |_ ld->ops->write_wakeup

With the port->lock held, we call the @write_wakeup. Some implemetation of
the @write_wakeup does not notice that the port->lock is held, and it still
tries to send data with uart_write() which will try to grab the prot->lock.
A dead lock occurs, see the following log caught in the Bluetooth by uart:

--------------------------------------------------------------------
BUG: spinlock lockup suspected on CPU#0, swapper/0/0
  lock: 0xdc3f4410, .magic: dead4ead, .owner: swapper/0/0, .owner_cpu: 0
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W    3.10.17-16839-ge4a1bef #1320
[<80014cbc>] (unwind_backtrace+0x0/0x138) from [<8001251c>] (show_stack+0x10/0x14)
[<8001251c>] (show_stack+0x10/0x14) from [<802816ac>] (do_raw_spin_lock+0x108/0x184)
[<802816ac>] (do_raw_spin_lock+0x108/0x184) from [<806a22b0>] (_raw_spin_lock_irqsave+0x54/0x60)
[<806a22b0>] (_raw_spin_lock_irqsave+0x54/0x60) from [<802f5754>] (uart_write+0x38/0xe0)
[<802f5754>] (uart_write+0x38/0xe0) from [<80455270>] (hci_uart_tx_wakeup+0xa4/0x168)
[<80455270>] (hci_uart_tx_wakeup+0xa4/0x168) from [<802dab18>] (tty_wakeup+0x50/0x5c)
[<802dab18>] (tty_wakeup+0x50/0x5c) from [<802f81a4>] (imx_rtsint+0x50/0x80)
[<802f81a4>] (imx_rtsint+0x50/0x80) from [<802f88f4>] (imx_int+0x158/0x17c)
[<802f88f4>] (imx_int+0x158/0x17c) from [<8007abe0>] (handle_irq_event_percpu+0x50/0x194)
[<8007abe0>] (handle_irq_event_percpu+0x50/0x194) from [<8007ad60>] (handle_irq_event+0x3c/0x5c)
--------------------------------------------------------------------

This patch adds more limits to the @write_wakeup, the one who wants to
implemet the @write_wakeup should follow the limits which avoid the deadlock.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
  include/linux/tty_ldisc.h |    5 ++++-
  1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index f15c898..539ccc5 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -91,7 +91,10 @@
   *	This function is called by the low-level tty driver to signal
   *	that line discpline should try to send more characters to the
   *	low-level driver for transmission.  If the line discpline does
- *	not have any more data to send, it can just return.
+ *	not have any more data to send, it can just return. If the line
+ *	discipline does have some data to send, please arise a tasklet
+ *	or workqueue to do the real data transfer. Do not send data in
+ *	this hook, it may leads to a deadlock.
   *
   * int (*hangup)(struct tty_struct *)
   *
-- 1.7.2.rc3

  reply	other threads:[~2014-03-20 18:54 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-20 16:34 hci_ldsic nested locking problem Felipe Balbi
2014-03-20 16:34 ` Felipe Balbi
2014-03-20 16:42 ` Alan Cox
2014-03-20 16:42   ` Alan Cox
2014-03-20 17:06   ` Kodiak Furr
2014-03-20 17:16   ` Felipe Balbi
2014-03-20 17:16     ` Felipe Balbi
2014-03-20 17:29     ` Felipe Balbi
2014-03-20 17:29       ` Felipe Balbi
2014-03-20 17:34       ` Peter Hurley
2014-03-20 17:35         ` Felipe Balbi
2014-03-20 17:35           ` Felipe Balbi
2014-03-20 18:45           ` Greg KH
2014-03-20 18:45             ` Greg KH
2014-03-20 18:54             ` Peter Hurley [this message]
2014-03-20 17:31     ` Peter Hurley
2014-03-20 18:11       ` Felipe Balbi
2014-03-20 18:11         ` Felipe Balbi
2014-03-20 18:21         ` Peter Hurley
2014-03-20 18:25           ` Felipe Balbi
2014-03-20 18:25             ` Felipe Balbi
2014-03-20 19:01             ` Felipe Balbi
2014-03-20 19:01               ` Felipe Balbi
2014-03-20 19:03               ` Felipe Balbi
2014-03-20 19:03                 ` Felipe Balbi
2014-03-20 19:16             ` Peter Hurley
2014-03-20 19:25               ` Felipe Balbi
2014-03-20 19:25                 ` Felipe Balbi

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=532B3983.6040706@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=alan@linux.intel.com \
    --cc=b32955@freescale.com \
    --cc=balbi@ti.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=m-karicheri2@ti.com \
    --cc=marcel@holtmann.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.