From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932299AbdDGLJC (ORCPT ); Fri, 7 Apr 2017 07:09:02 -0400 Received: from lelnx193.ext.ti.com ([198.47.27.77]:56511 "EHLO lelnx193.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752867AbdDGLIs (ORCPT ); Fri, 7 Apr 2017 07:08:48 -0400 From: Vignesh R Subject: 8250: Possible race between console message vs DMA? CC: Peter Hurley , Greg Kroah-Hartman , "linux-omap@vger.kernel.org" , Andy Shevchenko , "linux-kernel@vger.kernel.org" To: "linux-serial@vger.kernel.org" Message-ID: <7c75614c-71cb-0a4e-222c-713f65a89f23@ti.com> Date: Fri, 7 Apr 2017 16:38:54 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi All, I seem to be hitting a race condition using 8250_dma (and 8250_omap specific dma) support: Kernel writes log messages to console via serial8250_console_write()->serial8250_console_putchar() which directly accesses UART_TX register with port->lock acquired. Now, if the same UART instance is being used by systemd/userspace, characters are written to UART_TX register by serial8250_tx_chars(). The concurrent access by serial8250_console_write() and serial8250_tx_chars() is serialized by the use of port->lock spinlock and hence there is no issue with` non DMA case. But when using DMA with 8250 UART, I see that port->lock is held before scheduling of DMA TX transfer and released as soon as the transfer is submitted. The lock is not held until the transfer actually completes See, uart_start() ->serial8250_start_tx()-> __start_tx() ->up->dma->tx_dma(up) Or __dma_tx_complete() in 8250_dma.c that acquires and releases port->lock once TX DMA transfer is submitted in serial8250_tx_dma() So, when the port->lock is released, it is quite possible that DMA is still transferring data to UART TX FIFO and UART FIFO might be almost full. I see that when DMA is writing to UART TX FIFO, serial8250_console_write() may also write kernel log messages to UART TX FIFO(as port->lock is now free to be acquired), which is leading to overflow and lose of data. serial8250_console_write() checks for UART_LSR_THRE to check if Transmit hold register is empty but that may not be enough as DMA might put data before CPU write. It seems that both DMA and CPU might simultaneously put data to UART FIFO and lead to potential loss of data. Is the expectation that UART instance used to print kernel log messages is not intended to use DMA? Or am I missing something? Any help appreciated! -- Regards Vignesh