Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935731AbaBDWQ7 (ORCPT ); Tue, 4 Feb 2014 17:16:59 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:56658 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933868AbaBDVIh (ORCPT ); Tue, 4 Feb 2014 16:08:37 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marek Roszko , Nicolas Ferre Subject: [PATCH 3.12 058/133] tty/serial: at91: disable uart timer at start of shutdown Date: Tue, 4 Feb 2014 13:07:39 -0800 Message-Id: <20140204210738.671590494@linuxfoundation.org> X-Mailer: git-send-email 1.8.5.1.163.gd7aced9 In-Reply-To: <20140204210737.008598235@linuxfoundation.org> References: <20140204210737.008598235@linuxfoundation.org> User-Agent: quilt/0.61-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Marek Roszko commit 8bc661bfc0c2d221e209f4205bdaaf574d50100c upstream. The uart timer will schedule a tasklet when it fires. It is possible that it can fire inside _shutdown before it is killed in the dma and pdc cleanup routines. This causes a tasklet that exists after the port is shutdown, so when the kernel finally executes it, it panics as the tty port is NULL. This is a somewhat rare condition but its possible if a program keeps on opening/closing the port. It has been observed in particular with systemd boot messages that were causing a kernel panic because of this behavior. Moving the timer deletion to the beginning of the function stops a tasklet from being scheduled unexpectedly. Signed-off-by: Marek Roszko [nicolas.ferre@atmel.com: modify commit message, call setup_timer() in any case] Signed-off-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -824,9 +824,6 @@ static void atmel_release_rx_dma(struct atmel_port->desc_rx = NULL; atmel_port->chan_rx = NULL; atmel_port->cookie_rx = -EINVAL; - - if (!atmel_port->is_usart) - del_timer_sync(&atmel_port->uart_timer); } static void atmel_rx_from_dma(struct uart_port *port) @@ -1228,9 +1225,6 @@ static void atmel_release_rx_pdc(struct DMA_FROM_DEVICE); kfree(pdc->buf); } - - if (!atmel_port->is_usart) - del_timer_sync(&atmel_port->uart_timer); } static void atmel_rx_from_pdc(struct uart_port *port) @@ -1587,12 +1581,13 @@ static int atmel_startup(struct uart_por /* enable xmit & rcvr */ UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); + setup_timer(&atmel_port->uart_timer, + atmel_uart_timer_callback, + (unsigned long)port); + if (atmel_use_pdc_rx(port)) { /* set UART timeout */ if (!atmel_port->is_usart) { - setup_timer(&atmel_port->uart_timer, - atmel_uart_timer_callback, - (unsigned long)port); mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port)); /* set USART timeout */ @@ -1607,9 +1602,6 @@ static int atmel_startup(struct uart_por } else if (atmel_use_dma_rx(port)) { /* set UART timeout */ if (!atmel_port->is_usart) { - setup_timer(&atmel_port->uart_timer, - atmel_uart_timer_callback, - (unsigned long)port); mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port)); /* set USART timeout */ @@ -1635,6 +1627,12 @@ static void atmel_shutdown(struct uart_p struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); /* + * Prevent any tasklets being scheduled during + * cleanup + */ + del_timer_sync(&atmel_port->uart_timer); + + /* * Clear out any scheduled tasklets before * we destroy the buffers */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/