| From c7a8465db9172e278a9427e04ed69092a9351bd2 Mon Sep 17 00:00:00 2001 |
| From: Takatoshi Akiyama <takatoshi.akiyama.kj@ps.hitachi-solutions.com> |
| Date: Mon, 7 Nov 2016 16:56:50 +0100 |
| Subject: [PATCH 104/299] serial: sh-sci: Fix deadlock caused by serial output |
| request |
| |
| While spin is already locked, serial output request causes the deadlock, |
| because serial output process also tries to lock the spin. |
| This patch removes serial output with spin locked. |
| |
| Signed-off-by: Takatoshi Akiyama <takatoshi.akiyama.kj@ps.hitachi-solutions.com> |
| Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com> |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 6fc5a520429e29ae84cb9ce8e8c584166a54a1ee) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/tty/serial/sh-sci.c | 20 +++++--------------- |
| 1 file changed, 5 insertions(+), 15 deletions(-) |
| |
| --- a/drivers/tty/serial/sh-sci.c |
| +++ b/drivers/tty/serial/sh-sci.c |
| @@ -1143,11 +1143,8 @@ static int sci_dma_rx_push(struct sci_po |
| int copied; |
| |
| copied = tty_insert_flip_string(tport, buf, count); |
| - if (copied < count) { |
| - dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n", |
| - count - copied); |
| + if (copied < count) |
| port->icount.buf_overrun++; |
| - } |
| |
| port->icount.rx += copied; |
| |
| @@ -1162,8 +1159,6 @@ static int sci_dma_rx_find_active(struct |
| if (s->active_rx == s->cookie_rx[i]) |
| return i; |
| |
| - dev_err(s->port.dev, "%s: Rx cookie %d not found!\n", __func__, |
| - s->active_rx); |
| return -1; |
| } |
| |
| @@ -1224,9 +1219,9 @@ static void sci_dma_rx_complete(void *ar |
| |
| dma_async_issue_pending(chan); |
| |
| + spin_unlock_irqrestore(&port->lock, flags); |
| dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n", |
| __func__, s->cookie_rx[active], active, s->active_rx); |
| - spin_unlock_irqrestore(&port->lock, flags); |
| return; |
| |
| fail: |
| @@ -1274,8 +1269,6 @@ static void sci_submit_rx(struct sci_por |
| if (dma_submit_error(s->cookie_rx[i])) |
| goto fail; |
| |
| - dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__, |
| - s->cookie_rx[i], i); |
| } |
| |
| s->active_rx = s->cookie_rx[0]; |
| @@ -1289,7 +1282,6 @@ fail: |
| for (i = 0; i < 2; i++) |
| s->cookie_rx[i] = -EINVAL; |
| s->active_rx = -EINVAL; |
| - dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n"); |
| sci_rx_dma_release(s, true); |
| } |
| |
| @@ -1359,10 +1351,10 @@ static void rx_timer_fn(unsigned long ar |
| int active, count; |
| u16 scr; |
| |
| - spin_lock_irqsave(&port->lock, flags); |
| - |
| dev_dbg(port->dev, "DMA Rx timed out\n"); |
| |
| + spin_lock_irqsave(&port->lock, flags); |
| + |
| active = sci_dma_rx_find_active(s); |
| if (active < 0) { |
| spin_unlock_irqrestore(&port->lock, flags); |
| @@ -1371,9 +1363,9 @@ static void rx_timer_fn(unsigned long ar |
| |
| status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); |
| if (status == DMA_COMPLETE) { |
| + spin_unlock_irqrestore(&port->lock, flags); |
| dev_dbg(port->dev, "Cookie %d #%d has already completed\n", |
| s->active_rx, active); |
| - spin_unlock_irqrestore(&port->lock, flags); |
| |
| /* Let packet complete handler take care of the packet */ |
| return; |
| @@ -1397,8 +1389,6 @@ static void rx_timer_fn(unsigned long ar |
| /* Handle incomplete DMA receive */ |
| dmaengine_terminate_all(s->chan_rx); |
| read = sg_dma_len(&s->sg_rx[active]) - state.residue; |
| - dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read, |
| - s->active_rx); |
| |
| if (read) { |
| count = sci_dma_rx_push(s, s->rx_buf[active], read); |