Message ID | 83753d21-f3c8-c8dd-75d7-741cb597d1a3@sorico.fr (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak | expand |
Le 27/11/2018 à 10:58, Alexandre Belloni a écrit : > Hello Richard, > > On 27/11/2018 10:51:13+0100, richard.genoud@gmail.com wrote: >> Hi all, >> >> I reproduced the memory leak on my board (at91sam9g35-cm) with a 4.20-rc3. >> >> It triggered an OOM after a couple of hours running a code like this: >> #include <sys/types.h> >> #include <sys/stat.h> >> #include <fcntl.h> >> #include <unistd.h> >> >> >> int main(int argc, char **argv) >> { >> int fd; >> do { >> fd = open("/dev/ttyS1", O_RDONLY); >> close(fd); >> } while (true); >> return 0; >> } >> >> As Mario pointed out, this only happens when atmel,use-dma-{r,t}x are >> used in the device-tree. >> >> Adding: >> CONFIG_DEBUG_SLAB=y >> CONFIG_DEBUG_SLAB_LEAK=y >> Doesn't show anything suspect in /proc/slab_allocators >> >> From what I found until now, it's something done in : >> dma_request_slave_channel(); >> that leaks kmalloc-32 >> Mabe I missed something, but it seems that everything DMA related is >> deallocated in atmel_release_{tx,rx}_dma(). >> >> Is this ringing a bell ? >> > > Yes, this is known issue and it has yet to be worked on. > After a talk on freenode, Alex found the problem. A patch is on its way. Thanks !
--- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1056,8 +1056,6 @@ static int atmel_prepare_tx_dma(struct uart_port *port) atmel_port->chan_tx = dma_request_slave_channel(mfd_dev, "tx"); if (atmel_port->chan_tx == NULL) goto chan_err; - dev_info(port->dev, "using %s for tx DMA transfers\n", - dma_chan_name(atmel_port->chan_tx)); spin_lock_init(&atmel_port->lock_tx); sg_init_table(&atmel_port->sg_tx, 1); @@ -1239,8 +1237,6 @@ static int atmel_prepare_rx_dma(struct uart_port *port) atmel_port->chan_rx = dma_request_slave_channel(mfd_dev, "rx"); if (atmel_port->chan_rx == NULL) goto chan_err; - dev_info(port->dev, "using %s for rx DMA transfers\n", - dma_chan_name(atmel_port->chan_rx)); spin_lock_init(&atmel_port->lock_rx); sg_init_table(&atmel_port->sg_rx, 1);