Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [PATCHv3] panic: avoid deadlocks in re-entrant console drivers
From: Petr Mladek @ 2018-11-22 13:12 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: linux-kernel, Steven Rostedt, Daniel Wang, Peter Zijlstra,
	Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, Alan Cox,
	Jiri Slaby, Peter Feiner, linux-serial, Sergey Senozhatsky
In-Reply-To: <20181101080808.n73lrlnjd65nk4qf@pathway.suse.cz>

On Thu 2018-11-01 09:08:08, Petr Mladek wrote:
> On Thu 2018-11-01 10:48:21, Sergey Senozhatsky wrote:
> > On (10/31/18 13:27), Petr Mladek wrote:
> > > > 
> > > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
> > > 
> > > The patch makes sense to me. The locks should stay busted also for
> > > console_flush_on_panic().
> > > 
> > > With the added #include <linux/vt_kern.h>:
> > > 
> > > Reviewed-by: Petr Mladek <pmladek@suse.com>
> > 
> > Thanks!
> > 
> > Since there are no objections - how shall we route it? Via printk tree?
> 
> Good question. OK, I am going to put it into printk.git unless I hear
> complains withing next couple of days.

I have pushed this into printk.git, branch for-4.21.

Best Regards,
Petr

^ permalink raw reply

* Re: [PATCH v2 01/10] mailbox: Support blocking transfers in atomic context
From: Jassi Brar @ 2018-11-22 16:07 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Devicetree List, Greg KH, mliljeberg, Mikko Perttunen, talho,
	linux-serial, jslaby, linux-tegra, ppessi, Jon Hunter,
	linux-arm-kernel
In-Reply-To: <20181122084712.GA5741@ulmo>

Hi Thierry,

On Thu, Nov 22, 2018 at 2:47 AM Thierry Reding <thierry.reding@gmail.com> wrote:
>
> On Wed, Nov 21, 2018 at 08:18:22PM -0600, Jassi Brar wrote:
> > On Wed, Nov 21, 2018 at 8:27 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> > >
> > > On Tue, Nov 20, 2018 at 04:29:07PM +0100, Thierry Reding wrote:
> > > > On Sat, Nov 17, 2018 at 11:27:17AM -0600, Jassi Brar wrote:
> > > > > On Mon, Nov 12, 2018 at 9:18 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > > > >
> > > > > > From: Thierry Reding <treding@nvidia.com>
> > > > > >
> > > > > > The mailbox framework supports blocking transfers via completions for
> > > > > > clients that can sleep. In order to support blocking transfers in cases
> > > > > > where the transmission is not permitted to sleep, add a new ->flush()
> > > > > > callback that controller drivers can implement to busy loop until the
> > > > > > transmission has been completed. This will automatically be called when
> > > > > > available and interrupts are disabled for clients that request blocking
> > > > > > transfers.
> > > > > >
> > > > > > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > > > > > ---
> > > > > >  drivers/mailbox/mailbox.c          | 8 ++++++++
> > > > > >  include/linux/mailbox_controller.h | 4 ++++
> > > > > >  2 files changed, 12 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> > > > > > index 674b35f402f5..0eaf21259874 100644
> > > > > > --- a/drivers/mailbox/mailbox.c
> > > > > > +++ b/drivers/mailbox/mailbox.c
> > > > > > @@ -267,6 +267,14 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
> > > > > >                 unsigned long wait;
> > > > > >                 int ret;
> > > > > >
> > > > > > +               if (irqs_disabled() && chan->mbox->ops->flush) {
> > > > > > +                       ret = chan->mbox->ops->flush(chan, chan->cl->tx_tout);
> > > > > > +                       if (ret < 0)
> > > > > > +                               tx_tick(chan, ret);
> > > > > > +
> > > > > > +                       return ret;
> > > > > > +               }
> > > > > > +
> > > > > This is hacky. I think we can do without busy waiting in atomic
> > > > > context. You could queue locally while in atomic context and then
> > > > > transfer in blocking mode. I don't think we should worry about the
> > > > > 'throughput' as there already is no h/w rate control even with
> > > > > busy-waiting.
> > > >
> > > > I actually tried to do that before I added this flushing mechanism. The
> > > > problem is, like you said, one of rate control. As mentioned in the
> > > > cover letter, the shared mailboxes implemented in tegra-hsp are used as
> > > > RX and TX channels for the TCU, which is like a virtual UART. The TTY
> > > > driver included as part of this series will use one of the mailboxes to
> > > > transmit data that is written to the console. The problem is that if
> > > > these transmissions are not rate-limited on the TTY driver side, the
> > > > console will just keep writing data and eventually overflow the buffer
> > > > that we have in the mailbox subsystem.
> > > >
> > > > The problem is that data comes in at a much higher rate than what we can
> > > > output. This is especially true at boot when the TCU console takes over
> > > > and the whole log buffer is dumped on it.
> > > >
> > > > So the only way to rate-limit is to either make mbox_send_message()
> > > > block, but that can only be done in non-atomic context. The console,
> > > > however, will always run in atomic context, so the only way to do rate-
> > > > limiting is by busy looping.
> > >
> > > What I also tried before was to implement busy looping within the
> > > ->send_data() callback of the driver so that we didn't have to put this
> > > into the core. Unfortunately, however, the ->send_data() callback is
> > > called under chan->lock, which means that from mbox_send_message() we
> > > don't have a way to mark the transfer as done. In order to do that we'd
> > > have to call mbox_chan_txdone(), but that ends up calling tx_tick() and
> > > that in turn also attempts to take the chan->lock, which would cause a
> > > deadlock.
> > >
> > > The explicit flushing is the best alternative that I could come up with.
> > > I think it's not all that hacky, because it's very explicit about what's
> > > going on and it has the nice side-effect that it will allow the mailbox
> > > to work in interrupt driven mode if possible and only resorting to the
> > > busy loop in atomic context.
> > >
> > > At this point I think I have explored all other options and I frankly
> > > can't find a more proper way to achieve what we need here. Perhaps you
> > > can think of additional ways to accomplish this?
> > >
> > Well, I would have a local ring buffer (array) of enough size to hold
> > the characters and then have a task consuming data from that ring
> > buffer by transmitting over mailbox.
>
> There's already such a ringbuffer in the printk code. To implement what
> you suggest would effectively be creating a copy of that buffer because
> we'd be allocating the buffer and the console code would just dump each
> and every character in the logbuf into that ring buffer without rate-
> limitation.
>
Well, the console assumes there exists an atomic path to put character
on the bus, But because there isn't in case of tcu, we have to emulate
that. Frankly I prefer the one-off driver jump some hoops, rather than
implement exceptions in the api.
BTW, there is already no rate-limitation because its all virtual -
data is consumed as fast as possible.

> To make matters worse, the ringbuffer would be empty most of the time
> after the initial dump of the logbuf, so we'd be wasting all that buffer
> space.
>
The idea is console and uart-ops both feed into this buffer and the
only consumer thread runs the mailbox.

> It just seems to me like we should be keeping the TCU driver as close as
> possible to other UART drivers which also busy loop in order to rate-
> limit what the console can write. Given the current mailbox framework it
> is not possible to do that (in interrupt context), so an extension seems
> like the most sensible option.
>
> Perhaps you'd be less concerned about such a change if it was perhaps
> more explicit? Just throwing ideas around, I think something that could
> also work is if we explicitly add a mbox_flush() function that would
> basically be calling ->flush(). That way users of the mailbox can make
> their requirement very explicit. I haven't actually tested that, but I
> think it would work. Does that sound more acceptable to you?
>
I am happy to see features and bugfixes added to the api. What I am
not eager about is supporting less than 100% legit and very platform
specific usecases, especially when there is a work around.

Thanks.

^ permalink raw reply

* Re: [PATCH v2 01/10] mailbox: Support blocking transfers in atomic context
From: Thierry Reding @ 2018-11-22 17:34 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Devicetree List, Greg KH, mliljeberg, Mikko Perttunen, talho,
	linux-serial, jslaby, linux-tegra, ppessi, Jon Hunter,
	linux-arm-kernel
In-Reply-To: <CABb+yY1Ez=tSyPq=bX7oE3s3Eu97kdOS6+PkfDg1HKtkYyWTpA@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 9640 bytes --]

On Thu, Nov 22, 2018 at 10:07:09AM -0600, Jassi Brar wrote:
> Hi Thierry,
> 
> On Thu, Nov 22, 2018 at 2:47 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> >
> > On Wed, Nov 21, 2018 at 08:18:22PM -0600, Jassi Brar wrote:
> > > On Wed, Nov 21, 2018 at 8:27 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > >
> > > > On Tue, Nov 20, 2018 at 04:29:07PM +0100, Thierry Reding wrote:
> > > > > On Sat, Nov 17, 2018 at 11:27:17AM -0600, Jassi Brar wrote:
> > > > > > On Mon, Nov 12, 2018 at 9:18 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > > > > >
> > > > > > > From: Thierry Reding <treding@nvidia.com>
> > > > > > >
> > > > > > > The mailbox framework supports blocking transfers via completions for
> > > > > > > clients that can sleep. In order to support blocking transfers in cases
> > > > > > > where the transmission is not permitted to sleep, add a new ->flush()
> > > > > > > callback that controller drivers can implement to busy loop until the
> > > > > > > transmission has been completed. This will automatically be called when
> > > > > > > available and interrupts are disabled for clients that request blocking
> > > > > > > transfers.
> > > > > > >
> > > > > > > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > > > > > > ---
> > > > > > >  drivers/mailbox/mailbox.c          | 8 ++++++++
> > > > > > >  include/linux/mailbox_controller.h | 4 ++++
> > > > > > >  2 files changed, 12 insertions(+)
> > > > > > >
> > > > > > > diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> > > > > > > index 674b35f402f5..0eaf21259874 100644
> > > > > > > --- a/drivers/mailbox/mailbox.c
> > > > > > > +++ b/drivers/mailbox/mailbox.c
> > > > > > > @@ -267,6 +267,14 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
> > > > > > >                 unsigned long wait;
> > > > > > >                 int ret;
> > > > > > >
> > > > > > > +               if (irqs_disabled() && chan->mbox->ops->flush) {
> > > > > > > +                       ret = chan->mbox->ops->flush(chan, chan->cl->tx_tout);
> > > > > > > +                       if (ret < 0)
> > > > > > > +                               tx_tick(chan, ret);
> > > > > > > +
> > > > > > > +                       return ret;
> > > > > > > +               }
> > > > > > > +
> > > > > > This is hacky. I think we can do without busy waiting in atomic
> > > > > > context. You could queue locally while in atomic context and then
> > > > > > transfer in blocking mode. I don't think we should worry about the
> > > > > > 'throughput' as there already is no h/w rate control even with
> > > > > > busy-waiting.
> > > > >
> > > > > I actually tried to do that before I added this flushing mechanism. The
> > > > > problem is, like you said, one of rate control. As mentioned in the
> > > > > cover letter, the shared mailboxes implemented in tegra-hsp are used as
> > > > > RX and TX channels for the TCU, which is like a virtual UART. The TTY
> > > > > driver included as part of this series will use one of the mailboxes to
> > > > > transmit data that is written to the console. The problem is that if
> > > > > these transmissions are not rate-limited on the TTY driver side, the
> > > > > console will just keep writing data and eventually overflow the buffer
> > > > > that we have in the mailbox subsystem.
> > > > >
> > > > > The problem is that data comes in at a much higher rate than what we can
> > > > > output. This is especially true at boot when the TCU console takes over
> > > > > and the whole log buffer is dumped on it.
> > > > >
> > > > > So the only way to rate-limit is to either make mbox_send_message()
> > > > > block, but that can only be done in non-atomic context. The console,
> > > > > however, will always run in atomic context, so the only way to do rate-
> > > > > limiting is by busy looping.
> > > >
> > > > What I also tried before was to implement busy looping within the
> > > > ->send_data() callback of the driver so that we didn't have to put this
> > > > into the core. Unfortunately, however, the ->send_data() callback is
> > > > called under chan->lock, which means that from mbox_send_message() we
> > > > don't have a way to mark the transfer as done. In order to do that we'd
> > > > have to call mbox_chan_txdone(), but that ends up calling tx_tick() and
> > > > that in turn also attempts to take the chan->lock, which would cause a
> > > > deadlock.
> > > >
> > > > The explicit flushing is the best alternative that I could come up with.
> > > > I think it's not all that hacky, because it's very explicit about what's
> > > > going on and it has the nice side-effect that it will allow the mailbox
> > > > to work in interrupt driven mode if possible and only resorting to the
> > > > busy loop in atomic context.
> > > >
> > > > At this point I think I have explored all other options and I frankly
> > > > can't find a more proper way to achieve what we need here. Perhaps you
> > > > can think of additional ways to accomplish this?
> > > >
> > > Well, I would have a local ring buffer (array) of enough size to hold
> > > the characters and then have a task consuming data from that ring
> > > buffer by transmitting over mailbox.
> >
> > There's already such a ringbuffer in the printk code. To implement what
> > you suggest would effectively be creating a copy of that buffer because
> > we'd be allocating the buffer and the console code would just dump each
> > and every character in the logbuf into that ring buffer without rate-
> > limitation.
> >
> Well, the console assumes there exists an atomic path to put character
> on the bus, But because there isn't in case of tcu, we have to emulate
> that. Frankly I prefer the one-off driver jump some hoops, rather than
> implement exceptions in the api.

I wouldn't have any objections to that if the hoops were reasonable
ones. What you're asking me to do is basically implement a second copy
of the logbuf. I don't call that a reasonable hoop to jump through. It
is also not guaranteed to work properly because we can always end up
with a situation where we produce more data than we can consume. Also,
by providing this additional buffer we make things worse because the
standard mechanisms of the logbuf are side-stepped. Typically the logbuf
code will warn if it overflows. In our case we provide a buffer that the
console can dump into, so instead of the logbuf overflowing and warning
about it, we'd now overflow the mailbox buffer and we'd have to add
extra code to warn about overflows.

The console really only works because it assumes that the output driver
will stall and thereby rate-limit.

> BTW, there is already no rate-limitation because its all virtual -
> data is consumed as fast as possible.

No, that's not true. On the receiving end of the TX mailbox is a micro-
processor that reads out the mailbox data. Once it has read the data it
needs to clear the FULL bit so that the TCU driver can write more data.
Even if the microprocessor on the receiving end did buffering (there is
no indication that it does) it would eventually run out of buffer space
and have to stall until it's clocked all the characters out of the
physical UART. At that point no amount of buffering is going to save us
and the only option is to stall, which, again, can currently only be
done from the mailbox, because it is the only one that knows when it is
busy. But it's also the one place where we can't because the framework
doesn't allow it.

> > To make matters worse, the ringbuffer would be empty most of the time
> > after the initial dump of the logbuf, so we'd be wasting all that buffer
> > space.
> >
> The idea is console and uart-ops both feed into this buffer and the
> only consumer thread runs the mailbox.
> 
> > It just seems to me like we should be keeping the TCU driver as close as
> > possible to other UART drivers which also busy loop in order to rate-
> > limit what the console can write. Given the current mailbox framework it
> > is not possible to do that (in interrupt context), so an extension seems
> > like the most sensible option.
> >
> > Perhaps you'd be less concerned about such a change if it was perhaps
> > more explicit? Just throwing ideas around, I think something that could
> > also work is if we explicitly add a mbox_flush() function that would
> > basically be calling ->flush(). That way users of the mailbox can make
> > their requirement very explicit. I haven't actually tested that, but I
> > think it would work. Does that sound more acceptable to you?
> >
> I am happy to see features and bugfixes added to the api. What I am
> not eager about is supporting less than 100% legit and very platform
> specific usecases, especially when there is a work around.

Look, I'd be willing to push this all into the driver, but the framework
doesn't allow me to do that. If it was possible to run the state machine
outside of mbox_send_message() then I'd be able to just move the busy
loop or flush into the driver. But the locking is such that I can't do
that because it will cause a deadlock.

The ringbuffer workaround would be very brittle and if at all only work
by accident, not to mention that it would require duplicating much of
the logbuf logic.

Also I don't consider usage in atomic context a very platform specific
use-case, and I don't understand why I should be required to resort to
some unreliable workaround rather than find a proper fix that guarantees
proper operation.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/3] serial: imx: fix error handling in console_setup
From: Uwe Kleine-König @ 2018-11-23  8:03 UTC (permalink / raw)
  To: Stefan Agner
  Cc: gregkh, jslaby, fabio.estevam, s.hauer, linux-serial,
	linux-kernel
In-Reply-To: <20181114174940.7865-1-stefan@agner.ch>

On Wed, Nov 14, 2018 at 06:49:38PM +0100, Stefan Agner wrote:
> The ipg clock only needs to be unprepared in case preparing
> per clock fails. The ipg clock has already disabled at the point.
> 
> Fixes: 1cf93e0d5488 ("serial: imx: remove the uart_console() check")
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/tty/serial/imx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 0f67197a3783..313c3b1900a8 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -2068,7 +2068,7 @@ imx_uart_console_setup(struct console *co, char *options)
>  
>  	retval = clk_prepare(sport->clk_per);
>  	if (retval)
> -		clk_disable_unprepare(sport->clk_ipg);
> +		clk_unprepare(sport->clk_ipg);

good catch,

Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* Re: [PATCH 2/3] serial: imx: unprepare console clocks on remove
From: Uwe Kleine-König @ 2018-11-23  8:08 UTC (permalink / raw)
  To: Stefan Agner
  Cc: gregkh, jslaby, fabio.estevam, s.hauer, linux-serial,
	linux-kernel
In-Reply-To: <20181114174940.7865-2-stefan@agner.ch>

On Wed, Nov 14, 2018 at 06:49:39PM +0100, Stefan Agner wrote:
> Currently imx_uart_console_setup() prepares clocks which do not
> get unprepared anywhere. Check whether the console has been used
> by testing if index is set and unprepare clocks in this case.
> 
> This makes sure that clocks are properly unprepared after the
> console device has been unbound.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/tty/serial/imx.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 313c3b1900a8..757c91e5105a 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -2085,7 +2085,7 @@ static struct console imx_uart_console = {
>  	.data		= &imx_uart_uart_driver,
>  };
>  
> -#define IMX_CONSOLE	&imx_uart_console
> +#define IMX_CONSOLE	(&imx_uart_console)
>  
>  #ifdef CONFIG_OF
>  static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
> @@ -2378,8 +2378,17 @@ static int imx_uart_probe(struct platform_device *pdev)
>  static int imx_uart_remove(struct platform_device *pdev)
>  {
>  	struct imx_port *sport = platform_get_drvdata(pdev);
> +	int ret;
> +
> +	ret = uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
> +
> +	if (IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) && IMX_CONSOLE->index >= 0) {
> +		clk_unprepare(sport->clk_ipg);
> +		clk_unprepare(sport->clk_per);
> +		IMX_CONSOLE->index = -1;
> +	}
>  
> -	return uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
> +	return ret;

I doubt this is right. imx_uart_console_setup is called once, and
if the console is on (say) ttymxc0 you don't want to unprepare the
clocks if ttymxc3 gets unbound.

So I think this cleanup must go into imx_uart_exit().

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* Re: [PATCH v2 01/10] mailbox: Support blocking transfers in atomic context
From: Thierry Reding @ 2018-11-23 11:17 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Devicetree List, Greg KH, mliljeberg, Mikko Perttunen, talho,
	linux-serial, jslaby, linux-tegra, ppessi, Jon Hunter,
	linux-arm-kernel
In-Reply-To: <20181122084712.GA5741@ulmo>


[-- Attachment #1.1: Type: text/plain, Size: 4941 bytes --]

On Thu, Nov 22, 2018 at 09:47:12AM +0100, Thierry Reding wrote:
[...]
> Perhaps you'd be less concerned about such a change if it was perhaps
> more explicit? Just throwing ideas around, I think something that could
> also work is if we explicitly add a mbox_flush() function that would
> basically be calling ->flush(). That way users of the mailbox can make
> their requirement very explicit. I haven't actually tested that, but I
> think it would work. Does that sound more acceptable to you?

I tried implementing the explicit flushing on top of this series and it
would look roughly like the below. What do you think?

Thierry

--->8---
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 3e7e2c4358aa..fbdcc82a61ae 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -267,14 +267,6 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
 		unsigned long wait;
 		int ret;
 
-		if (irqs_disabled() && chan->mbox->ops->flush) {
-			ret = chan->mbox->ops->flush(chan, chan->cl->tx_tout);
-			if (ret < 0)
-				tx_tick(chan, ret);
-
-			return ret;
-		}
-
 		if (!chan->cl->tx_tout) /* wait forever */
 			wait = msecs_to_jiffies(3600000);
 		else
@@ -291,6 +283,34 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
 }
 EXPORT_SYMBOL_GPL(mbox_send_message);
 
+/**
+ * mbox_flush - flush a mailbox channel
+ * @chan: mailbox channel to flush
+ * @timeout: time, in milliseconds, to allow the flush operation to succeed
+ *
+ * Mailbox controllers that need to work in atomic context can implement the
+ * ->flush() callback to busy loop until a transmission has been completed.
+ * The implementation must call mbox_chan_txdone() upon success. Clients can
+ * call the mbox_flush() function at any time after mbox_send_message() to
+ * flush the transmission. After the function returns success, the mailbox
+ * transmission is guaranteed to have completed.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int mbox_flush(struct mbox_chan *chan, unsigned long timeout)
+{
+	int ret;
+
+	if (!chan->mbox->ops->flush)
+		return -ENOTSUPP;
+
+	ret = chan->mbox->ops->flush(chan, timeout);
+	if (ret < 0)
+		tx_tick(chan, ret);
+
+	return ret;
+}
+
 /**
  * mbox_request_channel - Request a mailbox channel.
  * @cl: Identity of the client requesting the channel.
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
index f99c406cb3cc..e443f6a2ec4b 100644
--- a/drivers/mailbox/tegra-hsp.c
+++ b/drivers/mailbox/tegra-hsp.c
@@ -387,15 +387,13 @@ static int tegra_hsp_mailbox_send_data(struct mbox_chan *chan, void *data)
 
 	tegra_hsp_channel_writel(&mb->channel, value, HSP_SM_SHRD_MBOX);
 
-	if (!irqs_disabled()) {
-		/* enable EMPTY interrupt for the shared mailbox */
-		spin_lock_irqsave(&hsp->lock, flags);
+	/* enable EMPTY interrupt for the shared mailbox */
+	spin_lock_irqsave(&hsp->lock, flags);
 
-		hsp->mask |= BIT(HSP_INT_EMPTY_SHIFT + mb->index);
-		tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));
+	hsp->mask |= BIT(HSP_INT_EMPTY_SHIFT + mb->index);
+	tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));
 
-		spin_unlock_irqrestore(&hsp->lock, flags);
-	}
+	spin_unlock_irqrestore(&hsp->lock, flags);
 
 	return 0;
 }
diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c
index 1d360cd03b18..59eaa13e169e 100644
--- a/drivers/tty/serial/tegra-tcu.c
+++ b/drivers/tty/serial/tegra-tcu.c
@@ -57,6 +57,7 @@ static void tegra_tcu_write_one(struct tegra_tcu *tcu, u32 value,
 	value |= TCU_MBOX_NUM_BYTES(count);
 	msg = (void *)(unsigned long)value;
 	mbox_send_message(tcu->tx, msg);
+	mbox_flush(tcu->tx, 1000);
 }
 
 static void tegra_tcu_write(struct tegra_tcu *tcu, const char *s,
@@ -184,9 +185,6 @@ static int tegra_tcu_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	tcu->tx_client.dev = &pdev->dev;
-	tcu->tx_client.tx_block = true;
-	tcu->tx_client.tx_tout = 10000;
-	tcu->rx_client.dev = &pdev->dev;
 	tcu->rx_client.rx_callback = tegra_tcu_receive;
 
 	tcu->tx = mbox_request_channel_byname(&tcu->tx_client, "tx");
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 44348710953f..faa7da3c9c8b 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -44,6 +44,7 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
 					      const char *name);
 struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
 int mbox_send_message(struct mbox_chan *chan, void *mssg);
+int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
 void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
 bool mbox_client_peek_data(struct mbox_chan *chan); /* atomic */
 void mbox_free_channel(struct mbox_chan *chan); /* may sleep */

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v2 01/10] mailbox: Support blocking transfers in atomic context
From: Thierry Reding @ 2018-11-23 11:56 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Devicetree List, Greg KH, mliljeberg, Mikko Perttunen, talho,
	linux-serial, jslaby, linux-tegra, ppessi, Jon Hunter,
	linux-arm-kernel
In-Reply-To: <20181123111700.GA31881@ulmo>


[-- Attachment #1.1: Type: text/plain, Size: 1241 bytes --]

On Fri, Nov 23, 2018 at 12:17:00PM +0100, Thierry Reding wrote:
> On Thu, Nov 22, 2018 at 09:47:12AM +0100, Thierry Reding wrote:
> [...]
> > Perhaps you'd be less concerned about such a change if it was perhaps
> > more explicit? Just throwing ideas around, I think something that could
> > also work is if we explicitly add a mbox_flush() function that would
> > basically be calling ->flush(). That way users of the mailbox can make
> > their requirement very explicit. I haven't actually tested that, but I
> > think it would work. Does that sound more acceptable to you?
> 
> I tried implementing the explicit flushing on top of this series and it
> would look roughly like the below. What do you think?
> 
> Thierry
> 
> --->8---
> diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
[...]
> @@ -184,9 +185,6 @@ static int tegra_tcu_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  
>  	tcu->tx_client.dev = &pdev->dev;
> -	tcu->tx_client.tx_block = true;
> -	tcu->tx_client.tx_tout = 10000;
> -	tcu->rx_client.dev = &pdev->dev;

Somehow this line ended up being removed in the diff, but it's actually
required. Only tx_block and tx_tout should be removed in this hunk.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 1/2] serial: mvebu-uart: clarify the baud rate derivation
From: Miquel Raynal @ 2018-11-23 15:45 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Thomas Petazzoni, Nadav Haklai, Antoine Tenart, Maxime Chevallier,
	Gregory Clement, linux-serial, linux-kernel, Russell King,
	Marc Zyngier, Miquel Raynal

The current comment in ->set_baud_rate() is rather incomplete as it
fails to describe what are the actual stages for the baudrate
derivation. Replace this comment with something more explicit and
close to the functional specification. Also adapt the variable names
to it.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/tty/serial/mvebu-uart.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 170e446a2f62..df6e4d8cdbd6 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -72,6 +72,7 @@
 #define  BRDV_BAUD_MASK         0x3FF
 
 #define UART_OSAMP		0x14
+#define  OSAMP_DEFAULT_DIVISOR	16
 
 #define MVEBU_NR_UARTS		2
 
@@ -444,23 +445,28 @@ static void mvebu_uart_shutdown(struct uart_port *port)
 static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 {
 	struct mvebu_uart *mvuart = to_mvuart(port);
-	unsigned int baud_rate_div;
+	unsigned int d_divisor, m_divisor;
 	u32 brdv;
 
 	if (IS_ERR(mvuart->clk))
 		return -PTR_ERR(mvuart->clk);
 
 	/*
-	 * The UART clock is divided by the value of the divisor to generate
-	 * UCLK_OUT clock, which is 16 times faster than the baudrate.
-	 * This prescaler can achieve all standard baudrates until 230400.
-	 * Higher baudrates could be achieved for the extended UART by using the
-	 * programmable oversampling stack (also called fractional divisor).
+	 * The baudrate is derived from the UART clock thanks to two divisors:
+	 *   > D ("baud generator"): can divide the clock from 2 to 2^10 - 1.
+	 *   > M ("fractional divisor"): allows a better accuracy for
+	 *     baudrates higher than 230400.
+	 *
+	 * As the derivation of M is rather complicated, the code sticks to its
+	 * default value (x16) when all the prescalers are zeroed, and only
+	 * makes use of D to configure the desired baudrate.
 	 */
-	baud_rate_div = DIV_ROUND_UP(port->uartclk, baud * 16);
+	m_divisor = OSAMP_DEFAULT_DIVISOR;
+	d_divisor = DIV_ROUND_UP(port->uartclk, baud * m_divisor);
+
 	brdv = readl(port->membase + UART_BRDV);
 	brdv &= ~BRDV_BAUD_MASK;
-	brdv |= baud_rate_div;
+	brdv |= d_divisor;
 	writel(brdv, port->membase + UART_BRDV);
 
 	return 0;
-- 
2.19.1

^ permalink raw reply related

* [PATCH 2/2] serial: mvebu-uart: initialize over sampling stack register
From: Miquel Raynal @ 2018-11-23 15:45 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Thomas Petazzoni, Nadav Haklai, Antoine Tenart, Maxime Chevallier,
	Gregory Clement, linux-serial, linux-kernel, Russell King,
	Marc Zyngier, Miquel Raynal
In-Reply-To: <20181123154530.8022-1-miquel.raynal@bootlin.com>

The baudrate derivation relies on the state of the programmable over
sampling stack (OSAMP register) being empty, while never initializing
it.

Set all the fields of this register to 0 (except reserved areas) to
ensure a x16 divisor, as assumed by the driver.

The suspend/resume callbacks are untouched because they already
save/restore correctly this register.

Suggested-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/tty/serial/mvebu-uart.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index df6e4d8cdbd6..231f751d1ef4 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -73,6 +73,7 @@
 
 #define UART_OSAMP		0x14
 #define  OSAMP_DEFAULT_DIVISOR	16
+#define  OSAMP_DIVISORS_MASK	0x3F3F3F3F
 
 #define MVEBU_NR_UARTS		2
 
@@ -446,7 +447,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 {
 	struct mvebu_uart *mvuart = to_mvuart(port);
 	unsigned int d_divisor, m_divisor;
-	u32 brdv;
+	u32 brdv, osamp;
 
 	if (IS_ERR(mvuart->clk))
 		return -PTR_ERR(mvuart->clk);
@@ -469,6 +470,10 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 	brdv |= d_divisor;
 	writel(brdv, port->membase + UART_BRDV);
 
+	osamp = readl(port->membase + UART_OSAMP);
+	osamp &= ~OSAMP_DIVISORS_MASK;
+	writel(osamp, port->membase + UART_OSAMP);
+
 	return 0;
 }
 
-- 
2.19.1

^ permalink raw reply related

* Re: [PATCH v2 15/15] MAINTAINERS: Add entry for RDA Micro SoC architecture
From: kbuild test robot @ 2018-11-24  8:30 UTC (permalink / raw)
  Cc: kbuild-all, olof, arnd, robh+dt, tglx, jason, marc.zyngier,
	daniel.lezcano, gregkh, jslaby, afaerber, linux-arm-kernel,
	linux-kernel, devicetree, linux-serial, amit.kucheria,
	linus.walleij, zhao_steven, overseas.sales, Manivannan Sadhasivam
In-Reply-To: <20181121033652.12247-16-manivannan.sadhasivam@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 3785 bytes --]

Hi Manivannan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.20-rc3 next-20181123]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Manivannan-Sadhasivam/Add-initial-RDA8810PL-SoC-and-Orange-Pi-boards-support/20181123-125507
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

>> drivers/tty/serial/rda-uart.c:619:28: warning: context imbalance in 'rda_uart_port_write' - unexpected unlock

vim +/rda_uart_port_write +619 drivers/tty/serial/rda-uart.c

efb19753 Manivannan Sadhasivam 2018-11-21  588  
efb19753 Manivannan Sadhasivam 2018-11-21  589  static void rda_uart_port_write(struct uart_port *port, const char *s,
efb19753 Manivannan Sadhasivam 2018-11-21  590  				u_int count)
efb19753 Manivannan Sadhasivam 2018-11-21  591  {
efb19753 Manivannan Sadhasivam 2018-11-21  592  	u32 old_irq_mask;
efb19753 Manivannan Sadhasivam 2018-11-21  593  	unsigned long flags;
efb19753 Manivannan Sadhasivam 2018-11-21  594  	int locked;
efb19753 Manivannan Sadhasivam 2018-11-21  595  
efb19753 Manivannan Sadhasivam 2018-11-21  596  	local_irq_save(flags);
efb19753 Manivannan Sadhasivam 2018-11-21  597  
efb19753 Manivannan Sadhasivam 2018-11-21  598  	if (port->sysrq) {
efb19753 Manivannan Sadhasivam 2018-11-21  599  		locked = 0;
efb19753 Manivannan Sadhasivam 2018-11-21  600  	} else if (oops_in_progress) {
efb19753 Manivannan Sadhasivam 2018-11-21  601  		locked = spin_trylock(&port->lock);
efb19753 Manivannan Sadhasivam 2018-11-21  602  	} else {
efb19753 Manivannan Sadhasivam 2018-11-21  603  		spin_lock(&port->lock);
efb19753 Manivannan Sadhasivam 2018-11-21  604  		locked = 1;
efb19753 Manivannan Sadhasivam 2018-11-21  605  	}
efb19753 Manivannan Sadhasivam 2018-11-21  606  
efb19753 Manivannan Sadhasivam 2018-11-21  607  	old_irq_mask = rda_uart_read(port, RDA_UART_IRQ_MASK);
efb19753 Manivannan Sadhasivam 2018-11-21  608  	rda_uart_write(port, 0, RDA_UART_IRQ_MASK);
efb19753 Manivannan Sadhasivam 2018-11-21  609  
efb19753 Manivannan Sadhasivam 2018-11-21  610  	uart_console_write(port, s, count, rda_console_putchar);
efb19753 Manivannan Sadhasivam 2018-11-21  611  
efb19753 Manivannan Sadhasivam 2018-11-21  612  	/* wait until all contents have been sent out */
efb19753 Manivannan Sadhasivam 2018-11-21  613  	while (!(rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK))
efb19753 Manivannan Sadhasivam 2018-11-21  614  		cpu_relax();
efb19753 Manivannan Sadhasivam 2018-11-21  615  
efb19753 Manivannan Sadhasivam 2018-11-21  616  	rda_uart_write(port, old_irq_mask, RDA_UART_IRQ_MASK);
efb19753 Manivannan Sadhasivam 2018-11-21  617  
efb19753 Manivannan Sadhasivam 2018-11-21  618  	if (locked)
efb19753 Manivannan Sadhasivam 2018-11-21 @619  		spin_unlock(&port->lock);
efb19753 Manivannan Sadhasivam 2018-11-21  620  
efb19753 Manivannan Sadhasivam 2018-11-21  621  	local_irq_restore(flags);
efb19753 Manivannan Sadhasivam 2018-11-21  622  }
efb19753 Manivannan Sadhasivam 2018-11-21  623  

:::::: The code at line 619 was first introduced by commit
:::::: efb197538a7e148635e096850a818e3b29b1c4b2 tty: serial: Add RDA8810PL UART driver

:::::: TO: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 66615 bytes --]

^ permalink raw reply

* imx6sx uart failing loopback tests with sdma firmware (ROM works)
From: Leonard Crestez @ 2018-11-26 11:53 UTC (permalink / raw)
  To: l.stach@pengutronix.de, u.kleine-koenig@pengutronix.de, Andy Duan
  Cc: linux-serial@vger.kernel.org, Robin Gong,
	linux-kernel@vger.kernel.org, dl-linux-imx, kernel@pengutronix.de

Hello,

On a build farm at NXP we found that linux-next now fails on simple
loopback tests on imx6sx-sdb (but not other SOCs AFAICT). I tracked
this down to commit 30fdd51be161
("ARM: imx_v6_v7_defconfig: add CONFIG_FW_LOADER_USER_HELPER")

All that does is enable loading SDMA firmware from rootfs, in theory
this config was always supported so it would not be a new bug.

This doesn't happen with the NXP vendor tree but there is quite a large
delta in uart dma code. In particular upstream dropped IDDMAEN claiming
that this works with both ROM and FW scripts, see commit 905c0decad28
("serial: imx: don't use idle condition detect for DMA transfers")

This doesn't seem to work on 6sx though and I don't know why :(

The issue can be worked-around by forcing RX script from ROM:

diff --git drivers/dma/imx-sdma.c drivers/dma/imx-sdma.c
@@ -894,9 +894,11 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
                break;
        case IMX_DMATYPE_UART:
-               per_2_emi = sdma->script_addrs->uart_2_mcu_addr;
+               //per_2_emi = sdma->script_addrs->uart_2_mcu_addr;
+               per_2_emi = 817;
                emi_2_per = sdma->script_addrs->mcu_2_app_addr;
                break;
        case IMX_DMATYPE_UART_SP:

The above doesn't look like a good fix. I tried to revert 905c0decad28
and resolve conflicts and that also seems to work, pushed here:
https://github.com/cdleonard/linux/commit/0a1757f467e6dc96037ec2e3ea7c88c5a4eb2ceb

You can find test code here (not very interesting):
https://source.codeaurora.org/external/imx/imx-test/tree/test/mxc_uart_test/mxc_uart_test.c?h=imx_4.14.62_1.0.0_beta

Any idea on how to fix this?

--
Regards,
Leonard

^ permalink raw reply

* Re: imx6sx uart failing loopback tests with sdma firmware (ROM works)
From: Lucas Stach @ 2018-11-26 12:01 UTC (permalink / raw)
  To: Leonard Crestez, u.kleine-koenig@pengutronix.de, Andy Duan
  Cc: linux-serial@vger.kernel.org, Robin Gong,
	linux-kernel@vger.kernel.org, dl-linux-imx, kernel@pengutronix.de
In-Reply-To: <6d8280df85c6e5b2ddba635780cd2912d9c5d425.camel@nxp.com>

Am Montag, den 26.11.2018, 11:53 +0000 schrieb Leonard Crestez:
> Hello,
> 
> On a build farm at NXP we found that linux-next now fails on simple
> loopback tests on imx6sx-sdb (but not other SOCs AFAICT). I tracked
> this down to commit 30fdd51be161
> ("ARM: imx_v6_v7_defconfig: add CONFIG_FW_LOADER_USER_HELPER")
> 
> All that does is enable loading SDMA firmware from rootfs, in theory
> this config was always supported so it would not be a new bug.
> 
> This doesn't happen with the NXP vendor tree but there is quite a large
> delta in uart dma code. In particular upstream dropped IDDMAEN claiming
> that this works with both ROM and FW scripts, see commit 905c0decad28
> ("serial: imx: don't use idle condition detect for DMA transfers")
> 
> This doesn't seem to work on 6sx though and I don't know why :(
> 
> The issue can be worked-around by forcing RX script from ROM:
> 
> diff --git drivers/dma/imx-sdma.c drivers/dma/imx-sdma.c
> @@ -894,9 +894,11 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
>                 break;
>         case IMX_DMATYPE_UART:
> -               per_2_emi = sdma->script_addrs->uart_2_mcu_addr;
> +               //per_2_emi = sdma->script_addrs->uart_2_mcu_addr;
> +               per_2_emi = 817;
>                 emi_2_per = sdma->script_addrs->mcu_2_app_addr;
>                 break;
>         case IMX_DMATYPE_UART_SP:
> 
> The above doesn't look like a good fix. I tried to revert 905c0decad28
> and resolve conflicts and that also seems to work, pushed here:
> https://github.com/cdleonard/linux/commit/0a1757f467e6dc96037ec2e3ea7c88c5a4eb2ceb
> 
> You can find test code here (not very interesting):
> https://source.codeaurora.org/external/imx/imx-test/tree/test/mxc_uart_test/mxc_uart_test.c?h=imx_4.14.62_1.0.0_beta
> 
> Any idea on how to fix this?

The RAM script is probably busted, as it doesn't provide the same
interface as the ROM script. The assumption of 905c0decad28 was that
the RAM script is an extension to the ROM script, but it seems like
this is not the case and the RAM script actually dropped some crucial
functionality.

See also https://lkml.org/lkml/2018/9/20/522

Please see if you can follow up internally and get a fixed SDMA
firmware pushed out. Fixed probably only means that the UART script
needs to be dropped, as the ROM script is totally fine when doing the
correct setup in the UART driver and the sole purpose of the RAM script
was to work with the broken UART driver.

Regards,
Lucas

^ permalink raw reply

* [PATCH] tty: serial: qcom_geni_serial: Fix softlock
From: Ryan Case @ 2018-11-27  2:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial, Ryan Case

Transfers were being divided into device FIFO sized (64 byte max)
operations which would poll for completion within a spin_lock_irqsave /
spin_unlock_irqrestore block. This both made things slow by waiting for
the FIFO to completely drain before adding further data and would also
result in softlocks on large transmissions.

This patch allows larger transfers with continuous FIFO additions as
space becomes available and removes polling from the interrupt handler.

Signed-off-by: Ryan Case <ryandcase@chromium.org>
Version: 1
---

 drivers/tty/serial/qcom_geni_serial.c | 58 ++++++++++++++++++---------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 7ded51081add..835a184e0b7d 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -117,6 +117,8 @@ struct qcom_geni_serial_port {
 	u32 *rx_fifo;
 	u32 loopback;
 	bool brk;
+
+	u32 cur_tx_remaining;
 };
 
 static const struct uart_ops qcom_geni_console_pops;
@@ -439,6 +441,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 	struct qcom_geni_serial_port *port;
 	bool locked = true;
 	unsigned long flags;
+	unsigned int geni_status;
 
 	WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
 
@@ -452,6 +455,8 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 	else
 		spin_lock_irqsave(&uport->lock, flags);
 
+	geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+
 	/* Cancel the current write to log the fault */
 	if (!locked) {
 		geni_se_cancel_m_cmd(&port->se);
@@ -465,9 +470,17 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
 		}
 		writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
 							SE_GENI_M_IRQ_CLEAR);
-	}
+	} else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining)
+		/* It seems we can interrupt existing transfers unless all data
+		 * has been sent, in which case we need to look for done first.
+		 */
+		qcom_geni_serial_poll_tx_done(uport);
 
 	__qcom_geni_serial_console_write(uport, s, count);
+
+	if (port->cur_tx_remaining)
+		qcom_geni_serial_setup_tx(uport, port->cur_tx_remaining);
+
 	if (locked)
 		spin_unlock_irqrestore(&uport->lock, flags);
 }
@@ -701,40 +714,47 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
 	port->handle_rx(uport, total_bytes, drop);
 }
 
-static void qcom_geni_serial_handle_tx(struct uart_port *uport)
+static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+		bool active)
 {
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 	struct circ_buf *xmit = &uport->state->xmit;
 	size_t avail;
 	size_t remaining;
+	size_t pending;
 	int i;
 	u32 status;
 	unsigned int chunk;
 	int tail;
-	u32 irq_en;
 
-	chunk = uart_circ_chars_pending(xmit);
 	status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
-	/* Both FIFO and framework buffer are drained */
-	if (!chunk && !status) {
+
+	/* Complete the current tx command before taking newly added data */
+	if (active)
+		pending = port->cur_tx_remaining;
+	else
+		pending = uart_circ_chars_pending(xmit);
+
+	/* All data has been transmitted and acknowledged as received */
+	if (!pending && !status && done) {
 		qcom_geni_serial_stop_tx(uport);
 		goto out_write_wakeup;
 	}
 
-	if (!uart_console(uport)) {
-		irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
-		irq_en &= ~(M_TX_FIFO_WATERMARK_EN);
-		writel_relaxed(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
-		writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
-	}
+	avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
+	avail *= port->tx_bytes_pw;
+	if (avail < 0)
+		avail = 0;
 
-	avail = (port->tx_fifo_depth - port->tx_wm) * port->tx_bytes_pw;
 	tail = xmit->tail;
-	chunk = min3((size_t)chunk, (size_t)(UART_XMIT_SIZE - tail), avail);
+	chunk = min3((size_t)pending, (size_t)(UART_XMIT_SIZE - tail), avail);
 	if (!chunk)
 		goto out_write_wakeup;
 
-	qcom_geni_serial_setup_tx(uport, chunk);
+	if (!port->cur_tx_remaining) {
+		qcom_geni_serial_setup_tx(uport, pending);
+		port->cur_tx_remaining = pending;
+	}
 
 	remaining = chunk;
 	for (i = 0; i < chunk; ) {
@@ -753,11 +773,10 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport)
 		tail += tx_bytes;
 		uport->icount.tx += tx_bytes;
 		remaining -= tx_bytes;
+		port->cur_tx_remaining -= tx_bytes;
 	}
 
 	xmit->tail = tail & (UART_XMIT_SIZE - 1);
-	if (uart_console(uport))
-		qcom_geni_serial_poll_tx_done(uport);
 out_write_wakeup:
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(uport);
@@ -767,6 +786,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 {
 	unsigned int m_irq_status;
 	unsigned int s_irq_status;
+	unsigned int geni_status;
 	struct uart_port *uport = dev;
 	unsigned long flags;
 	unsigned int m_irq_en;
@@ -780,6 +800,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 	spin_lock_irqsave(&uport->lock, flags);
 	m_irq_status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
 	s_irq_status = readl_relaxed(uport->membase + SE_GENI_S_IRQ_STATUS);
+	geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
 	m_irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
 	writel_relaxed(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
 	writel_relaxed(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
@@ -794,7 +815,8 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 
 	if (m_irq_status & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN) &&
 	    m_irq_en & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
-		qcom_geni_serial_handle_tx(uport);
+		qcom_geni_serial_handle_tx(uport, m_irq_status & M_CMD_DONE_EN,
+					geni_status & M_GENI_CMD_ACTIVE);
 
 	if (s_irq_status & S_GP_IRQ_0_EN || s_irq_status & S_GP_IRQ_1_EN) {
 		if (s_irq_status & S_GP_IRQ_0_EN)
-- 
2.20.0.rc0.387.gc7a69e6b6c-goog

^ permalink raw reply related

* [PATCH] tty: serial: 8250_mtk: always resume the device in probe.
From: Peter Shih @ 2018-11-27  4:49 UTC (permalink / raw)
  Cc: pihsun, Greg Kroah-Hartman, Jiri Slaby, Matthias Brugger,
	linux-serial, linux-arm-kernel, linux-mediatek, linux-kernel

serial8250_register_8250_port calls uart_config_port, which calls
config_port on the port before it tries to power on the port. So we need
the port to be on before calling serial8250_register_8250_port. Change
the code to always do a runtime resume in probe before registering port,
and always do a runtime suspend in remove.

This basically reverts the change in commit 68e5fc4a255a ("tty: serial:
8250_mtk: use pm_runtime callbacks for enabling"), but still use
pm_runtime callbacks.

Fixes: 68e5fc4a255a ("tty: serial: 8250_mtk: use pm_runtime callbacks for enabling")
Signed-off-by: Peter Shih <pihsun@chromium.org>
---
 drivers/tty/serial/8250/8250_mtk.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index dd5e1cede2b58..c3f933d10295e 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -213,17 +213,17 @@ static int mtk8250_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	pm_runtime_enable(&pdev->dev);
-	if (!pm_runtime_enabled(&pdev->dev)) {
-		err = mtk8250_runtime_resume(&pdev->dev);
-		if (err)
-			return err;
-	}
+	err = mtk8250_runtime_resume(&pdev->dev);
+	if (err)
+		return err;
 
 	data->line = serial8250_register_8250_port(&uart);
 	if (data->line < 0)
 		return data->line;
 
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
 	return 0;
 }
 
@@ -234,13 +234,11 @@ static int mtk8250_remove(struct platform_device *pdev)
 	pm_runtime_get_sync(&pdev->dev);
 
 	serial8250_unregister_port(data->line);
+	mtk8250_runtime_suspend(&pdev->dev);
 
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_put_noidle(&pdev->dev);
 
-	if (!pm_runtime_status_suspended(&pdev->dev))
-		mtk8250_runtime_suspend(&pdev->dev);
-
 	return 0;
 }
 
-- 
2.20.0.rc0.387.gc7a69e6b6c-goog

^ permalink raw reply related

* Re: [PATCH] tty: serial: qcom_geni_serial: Fix softlock
From: Julia Lawall @ 2018-11-27  8:48 UTC (permalink / raw)
  To: Ryan Case
  Cc: Greg Kroah-Hartman, Jiri Slaby, Evan Green, Doug Anderson,
	linux-kernel, linux-serial

Hello,

Since size_t is unsigned, avail will not be less than 0 on line 742.
Perhaps just reorganize the computation on line 740.

julia

---------- Forwarded message ----------
Date: Tue, 27 Nov 2018 16:13:53 +0800
From: kbuild test robot <lkp@intel.com>
To: kbuild@01.org
Cc: Julia Lawall <julia.lawall@lip6.fr>
Subject: Re: [PATCH] tty: serial: qcom_geni_serial: Fix softlock

CC: kbuild-all@01.org
In-Reply-To: <20181127022536.104663-1-ryandcase@chromium.org>
References: <20181127022536.104663-1-ryandcase@chromium.org>
TO: Ryan Case <ryandcase@chromium.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jiri Slaby <jslaby@suse.com>, Evan Green <evgreen@chromium.org>, Doug Anderson <dianders@chromium.org>, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, Ryan Case <ryandcase@chromium.org>
CC: Evan Green <evgreen@chromium.org>, Doug Anderson <dianders@chromium.org>, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, Ryan Case <ryandcase@chromium.org>

Hi Ryan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tty/tty-testing]
[also build test WARNING on v4.20-rc4 next-20181126]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Ryan-Case/tty-serial-qcom_geni_serial-Fix-softlock/20181127-102810
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
:::::: branch date: 6 hours ago
:::::: commit date: 6 hours ago

>> drivers/tty/serial/qcom_geni_serial.c:742:5-10: WARNING: Unsigned expression compared with zero: avail < 0

# https://github.com/0day-ci/linux/commit/407559b41ed61fd8c95ebe39539677bc577c7c66
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 407559b41ed61fd8c95ebe39539677bc577c7c66
vim +742 drivers/tty/serial/qcom_geni_serial.c

c4f528795 Karthikeyan Ramasubramanian 2018-03-14  712
407559b41 Ryan Case                   2018-11-26  713  static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
407559b41 Ryan Case                   2018-11-26  714  		bool active)
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  715  {
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  716  	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  717  	struct circ_buf *xmit = &uport->state->xmit;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  718  	size_t avail;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  719  	size_t remaining;
407559b41 Ryan Case                   2018-11-26  720  	size_t pending;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  721  	int i;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  722  	u32 status;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  723  	unsigned int chunk;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  724  	int tail;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  725
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  726  	status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
407559b41 Ryan Case                   2018-11-26  727
407559b41 Ryan Case                   2018-11-26  728  	/* Complete the current tx command before taking newly added data */
407559b41 Ryan Case                   2018-11-26  729  	if (active)
407559b41 Ryan Case                   2018-11-26  730  		pending = port->cur_tx_remaining;
407559b41 Ryan Case                   2018-11-26  731  	else
407559b41 Ryan Case                   2018-11-26  732  		pending = uart_circ_chars_pending(xmit);
407559b41 Ryan Case                   2018-11-26  733
407559b41 Ryan Case                   2018-11-26  734  	/* All data has been transmitted and acknowledged as received */
407559b41 Ryan Case                   2018-11-26  735  	if (!pending && !status && done) {
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  736  		qcom_geni_serial_stop_tx(uport);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  737  		goto out_write_wakeup;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  738  	}
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  739
407559b41 Ryan Case                   2018-11-26  740  	avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
407559b41 Ryan Case                   2018-11-26  741  	avail *= port->tx_bytes_pw;
407559b41 Ryan Case                   2018-11-26 @742  	if (avail < 0)
407559b41 Ryan Case                   2018-11-26  743  		avail = 0;
8a8a66a1a Girish Mahadevan            2018-07-13  744
638a6f4eb Evan Green                  2018-05-09  745  	tail = xmit->tail;
407559b41 Ryan Case                   2018-11-26  746  	chunk = min3((size_t)pending, (size_t)(UART_XMIT_SIZE - tail), avail);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  747  	if (!chunk)
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  748  		goto out_write_wakeup;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  749
407559b41 Ryan Case                   2018-11-26  750  	if (!port->cur_tx_remaining) {
407559b41 Ryan Case                   2018-11-26  751  		qcom_geni_serial_setup_tx(uport, pending);
407559b41 Ryan Case                   2018-11-26  752  		port->cur_tx_remaining = pending;
407559b41 Ryan Case                   2018-11-26  753  	}
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  754
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  755  	remaining = chunk;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  756  	for (i = 0; i < chunk; ) {
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  757  		unsigned int tx_bytes;
69736b57d Karthikeyan Ramasubramanian 2018-05-03  758  		u8 buf[sizeof(u32)];
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  759  		int c;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  760
69736b57d Karthikeyan Ramasubramanian 2018-05-03  761  		memset(buf, 0, ARRAY_SIZE(buf));
6a10635e9 Karthikeyan Ramasubramanian 2018-05-03  762  		tx_bytes = min_t(size_t, remaining, port->tx_bytes_pw);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  763  		for (c = 0; c < tx_bytes ; c++)
69736b57d Karthikeyan Ramasubramanian 2018-05-03  764  			buf[c] = xmit->buf[tail + c];
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  765
69736b57d Karthikeyan Ramasubramanian 2018-05-03  766  		iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  767
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  768  		i += tx_bytes;
638a6f4eb Evan Green                  2018-05-09  769  		tail += tx_bytes;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  770  		uport->icount.tx += tx_bytes;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  771  		remaining -= tx_bytes;
407559b41 Ryan Case                   2018-11-26  772  		port->cur_tx_remaining -= tx_bytes;
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  773  	}
638a6f4eb Evan Green                  2018-05-09  774
638a6f4eb Evan Green                  2018-05-09  775  	xmit->tail = tail & (UART_XMIT_SIZE - 1);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  776  out_write_wakeup:
638a6f4eb Evan Green                  2018-05-09  777  	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  778  		uart_write_wakeup(uport);
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  779  }
c4f528795 Karthikeyan Ramasubramanian 2018-03-14  780

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak
From: richard.genoud @ 2018-11-27  9:51 UTC (permalink / raw)
  To: Ludovic Desroches, Nicolas Ferre, Maxime Ripard, Vinod Koul,
	Alexandre Belloni
  Cc: linux-arm-kernel@lists.infradead.org, dmaengine, Linux Kernel,
	linux-serial@vger.kernel.org, Mario Forner
In-Reply-To: <22061488.b0eNpyQjWt@linux-7rm0>

[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used)    : 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)      : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used)     : 57 / 76 (75.0%)
>  Active / Total Size (% used)       : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%    0.03K  21571      124     86284K kmalloc-32
>   7200   7104  98%    0.08K    144       50       576K kernfs_node_cache
>   6930   5370  77%    0.13K    231       30       924K dentry     
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown         
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
>     try:
>         with serial.Serial(port = '/dev/ttyS4'):
>             pass
>     except Exception as e:
>         print e
>     finally:
>         time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils                2.25
> Util-linux              2.25.2
> Mount                   2.25.2
> Module-init-tools       18
> E2fsprogs               1.42.12
> Linux C Library         2.19
> Dynamic linker (ldd)    2.19
> Linux C++ Library       6.0.20
> Procps                  3.3.9
> Net-tools               1.60
> Sh-utils                8.23
> Udev                    215
> Modules Loaded          iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor       : 0
> model name      : ARM926EJ-S rev 5 (v5l)
> BogoMIPS        : 198.76
> Features        : swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant     : 0x0
> CPU part        : 0x926
> CPU revision    : 5
> 
> Hardware        : Atmel AT91SAM9
> Revision        : 0000
> Serial          : 0000000000000000  
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf000000
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 00300000-00307fff : 300000.sram
> 00600000-006fffff : /ahb/ohci@00600000
> 00700000-007fffff : /ahb/ehci@00700000
> 20000000-2fffffff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f0000000-f00000ff : /ahb/apb/spi@f0000000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f8010000-f80100ff : /ahb/apb/i2c@f8010000
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f8020000-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ffffec00-ffffedff : at_hdmac
> ffffee00-ffffefff : at_hdmac
> fffff200-fffff3ff : atmel_serial
> fffff400-fffff5ff : /ahb/apb/pinctrl@fffff400/gpio@fffff400
> fffff600-fffff7ff : /ahb/apb/pinctrl@fffff400/gpio@fffff600
> fffff800-fffff9ff : /ahb/apb/pinctrl@fffff400/gpio@fffff800
> fffffa00-fffffbff : /ahb/apb/pinctrl@fffff400/gpio@fffffa00
> fffffe10-fffffe1f : /ahb/apb/shdwc@fffffe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
>     status = "okay";
>     compatible = "atmel,at91sam9260-usart";
>     reg = <0xf8028000 0x200>;
>     interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
>     pinctrl-names = "default";
>     atmel,use-dma-tx;
>     atmel,use-dma-rx;
>     pinctrl-0 = <&pinctrl_usart3
>     &pinctrl_usart3_rts~
>     &pinctrl_usart3_cts>;
>     linux,rs485-enabled-at-boot-time;
>     rs485-rts-delay = <0 0>;
> };
> 
> Other notes:
> I tried the SLUB allocator with slub_debug=U but opening serial device then
> resulted in a Kernel-Oops:
>     at BUGON(ents < 0);
>     in function: dma_map_sg_attrs
>     in file: /include/asm-generic/dma-mapping-common.h
> So I could not gather information that way. I don't know if this is related.
> SLUB works if User Tracking is disabled.
> 
> Enabling kmemleak did not detect any leaks.
> 
> I also tried kernel version 4.19.1 and it exhibits the same behaviour, but I
> could not configure it to run reliably on the target system yet. 
> 

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 ?



The oom-killer, slabinfo, meminfo and slab_allocator traces follow.

NB: the -dirty flag is there beacause I removed some log from atmel-serial:
--- 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);



OOM-killer trace :
[ 5220.560000] test_open invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), nodemask=(null), order=0, oom_score_adj=0
[ 5220.580000] CPU: 0 PID: 1062 Comm: test_open Not tainted 4.20.0-rc3-dirty #31
[ 5220.580000] Hardware name: Atmel AT91SAM9
[ 5220.590000] Backtrace: 
[ 5220.590000] [<c000e020>] (dump_backtrace) from [<c000e2b8>] (show_stack+0x20/0x24)
[ 5220.600000]  r6:00000009 r5:c0649bb5 r4:c72a1e18 r3:02b88502
[ 5220.600000] [<c000e298>] (show_stack) from [<c0521114>] (dump_stack+0x20/0x28)
[ 5220.610000] [<c05210f4>] (dump_stack) from [<c0097280>] (dump_header+0x6c/0x1c4)
[ 5220.620000] [<c0097214>] (dump_header) from [<c0096454>] (oom_kill_process+0x6c/0x3cc)
[ 5220.620000]  r10:00000001 r8:c070e788 r7:c72a1e18 r6:00000009 r5:c0649bb5 r4:c7b64ea0
[ 5220.630000] [<c00963e8>] (oom_kill_process) from [<c009712c>] (out_of_memory+0x388/0x41c)
[ 5220.640000]  r10:00000001 r9:00000000 r8:c070e788 r7:0000000b r6:c070e8e4 r5:c070e788
[ 5220.650000]  r4:c72a1e18
[ 5220.650000] [<c0096da4>] (out_of_memory) from [<c009b1d8>] (__alloc_pages_nodemask+0x8b4/0xc48)
[ 5220.660000]  r8:00000011 r7:00000000 r6:00000000 r5:00000000 r4:006200ca
[ 5220.670000] [<c009a924>] (__alloc_pages_nodemask) from [<c0092bd4>] (filemap_fault+0x384/0x54c)
[ 5220.680000]  r10:c609b480 r9:00000000 r8:00000004 r7:00000000 r6:c72a1ed0 r5:c77dbb5c
[ 5220.680000]  r4:006200ca
[ 5220.690000] [<c0092850>] (filemap_fault) from [<c00babe8>] (__do_fault+0x28/0x9c)
[ 5220.690000]  r10:c7375a20 r9:c7375a58 r8:80000005 r7:000000b1 r6:b6efe000 r5:c72a1ed0
[ 5220.700000]  r4:00000000
[ 5220.700000] [<c00babc0>] (__do_fault) from [<c00bd9b0>] (handle_mm_fault+0x3e4/0x97c)
[ 5220.710000]  r5:000000c0 r4:00000000
[ 5220.720000] [<c00bd5cc>] (handle_mm_fault) from [<c000f774>] (do_page_fault+0x138/0x2ac)
[ 5220.720000]  r7:00000054 r6:b6efef9c r5:c72a1fb0 r4:c7a300e0
[ 5220.730000] [<c000f63c>] (do_page_fault) from [<c000f99c>] (do_translation_fault+0x2c/0xb4)
[ 5220.740000]  r10:b6f9e000 r9:00000000 r8:00053177 r7:80000005 r6:b6efef9c r5:c070f91c
[ 5220.750000]  r4:00000005
[ 5220.750000] [<c000f970>] (do_translation_fault) from [<c000fb38>] (do_PrefetchAbort+0x44/0x94)
[ 5220.760000]  r7:c72a1fb0 r6:b6efef9c r5:c070f91c r4:00000005
[ 5220.760000] [<c000faf4>] (do_PrefetchAbort) from [<c0009f08>] (ret_from_exception+0x0/0x18)
[ 5220.770000] Exception stack(0xc72a1fb0 to 0xc72a1ff8)
[ 5220.780000] 1fa0:                                     00000000 00000000 beb25d54 beb25e71
[ 5220.780000] 1fc0: 00000000 00000000 000082f4 00000006 00000000 00000000 b6f9e000 beb25bf4
[ 5220.790000] 1fe0: 00000000 beb25bdc 0000847c b6efef9c 40000010 ffffffff
[ 5220.800000]  r7:0005317f r6:ffffffff r5:40000010 r4:b6efef9c
[ 5220.800000] Mem-Info:
[ 5220.810000] active_anon:1659 inactive_anon:47 isolated_anon:0
[ 5220.810000]  active_file:2 inactive_file:4 isolated_file:0
[ 5220.810000]  unevictable:0 dirty:0 writeback:0 unstable:0
[ 5220.810000]  slab_reclaimable:1098 slab_unreclaimable:26200
[ 5220.810000]  mapped:3 shmem:60 pagetables:125 bounce:0
[ 5220.810000]  free:344 free_pcp:45 free_cma:0
[ 5220.840000] Node 0 active_anon:6636kB inactive_anon:188kB active_file:8kB inactive_file:16kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:12kB dirty:0kB writeback:0kB shmem:240kB writeback_tmp:0kB unstable:0kB all_unreclaimable? yes
[ 5220.860000] Normal free:1376kB min:1396kB low:1744kB high:2092kB active_anon:6636kB inactive_anon:188kB active_file:8kB inactive_file:16kB unevictable:0kB writepending:0kB present:131072kB managed:122316kB mlocked:0kB kernel_stack:448kB pagetables:500kB bounce:0kB free_pcp:180kB local_pcp:180kB free_cma:0kB
[ 5220.890000] lowmem_reserve[]: 0 0
[ 5220.890000] Normal: 0*4kB 54*8kB (U) 29*16kB (U) 11*32kB (U) 2*64kB (U) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 1376kB
[ 5220.900000] 66 total pagecache pages
[ 5220.910000] 32768 pages RAM
[ 5220.910000] 0 pages HighMem/MovableOnly
[ 5220.910000] 2189 pages reserved
[ 5220.920000] Unreclaimable slab info:
[ 5220.920000] Name                      Used          Total
[ 5220.930000] ubi_wl_entry_slab         92KB         93KB
[ 5220.930000] bridge_fdb_cache           0KB          3KB
[ 5220.940000] fib6_nodes                 0KB          3KB
[ 5220.940000] ip6_dst_cache              0KB          3KB
[ 5220.950000] RAWv6                      4KB          7KB
[ 5220.950000] UDPv6                      1KB          7KB
[ 5220.960000] TCPv6                      3KB          6KB
[ 5220.960000] sd_ext_cdb                 0KB          3KB
[ 5220.970000] sgpool-128                 4KB          4KB
[ 5220.970000] sgpool-64                  2KB          4KB
[ 5220.980000] sgpool-32                  1KB          4KB
[ 5220.980000] sgpool-16                  0KB          4KB
[ 5220.990000] sgpool-8                   0KB          4KB
[ 5220.990000] nfs_commit_data            1KB          3KB
[ 5221.000000] nfs_write_data            18KB         19KB
[ 5221.000000] bio-1                      0KB          3KB
[ 5221.010000] rpc_buffers               16KB         16KB
[ 5221.010000] rpc_tasks                  1KB          4KB
[ 5221.020000] UNIX                      14KB         15KB
[ 5221.030000] tcp_bind_bucket            0KB          3KB
[ 5221.030000] ip_fib_trie                0KB          3KB
[ 5221.040000] ip_fib_alias               0KB          3KB
[ 5221.040000] ip_dst_cache               1KB          4KB
[ 5221.050000] RAW                        1KB          3KB
[ 5221.050000] UDP                        2KB          7KB
[ 5221.060000] TCP                        6KB          6KB
[ 5221.060000] eventpoll_pwq              0KB          3KB
[ 5221.070000] eventpoll_epi              1KB          3KB
[ 5221.070000] inotify_inode_mark          1KB          3KB
[ 5221.080000] request_queue             18KB         22KB
[ 5221.080000] blkdev_ioc                 0KB          3KB
[ 5221.090000] bio-0                      4KB          7KB
[ 5221.090000] biovec-max                90KB         90KB
[ 5221.100000] uid_cache                  0KB          3KB
[ 5221.100000] dmaengine-unmap-2          0KB          3KB
[ 5221.110000] skbuff_head_cache          5KB          7KB
[ 5221.110000] configfs_dir_cache          0KB          3KB
[ 5221.120000] file_lock_ctx              0KB          3KB
[ 5221.130000] fsnotify_mark_connector          0KB          3KB
[ 5221.130000] shmem_inode_cache        205KB        210KB
[ 5221.140000] proc_dir_entry            30KB         30KB
[ 5221.140000] pde_opener                 0KB          3KB
[ 5221.150000] seq_file                   0KB          3KB
[ 5221.150000] kernfs_node_cache        672KB        673KB
[ 5221.160000] mnt_cache                  5KB          7KB
[ 5221.160000] filp                      52KB         58KB
[ 5221.170000] names_cache               24KB         24KB
[ 5221.170000] key_jar                    0KB          4KB
[ 5221.180000] nsproxy                    0KB          3KB
[ 5221.180000] vm_area_struct            92KB        103KB
[ 5221.190000] mm_struct                 12KB         14KB
[ 5221.190000] fs_cache                   0KB          3KB
[ 5221.200000] files_cache                5KB         11KB
[ 5221.200000] signal_cache              33KB         46KB
[ 5221.210000] sighand_cache             71KB         80KB
[ 5221.210000] task_struct               57KB         86KB
[ 5221.220000] cred_jar                  13KB         20KB
[ 5221.220000] anon_vma_chain            32KB         46KB
[ 5221.230000] anon_vma                  29KB         39KB
[ 5221.240000] pid                        4KB          7KB
[ 5221.240000] debug_objects_cache         48KB         50KB
[ 5221.250000] trace_event_file          85KB         86KB
[ 5221.250000] ftrace_event_field        161KB        163KB
[ 5221.260000] pool_workqueue             1KB          4KB
[ 5221.260000] kmalloc-256k             256KB        256KB
[ 5221.270000] kmalloc-64k               64KB         64KB
[ 5221.270000] kmalloc-32k               32KB         32KB
[ 5221.280000] kmalloc-16k               32KB         32KB
[ 5221.280000] kmalloc-8k               128KB        128KB
[ 5221.290000] kmalloc-4k               104KB        104KB
[ 5221.290000] kmalloc-2k               102KB        108KB
[ 5221.300000] kmalloc-1k               191KB        192KB
[ 5221.300000] kmalloc-512              154KB        168KB
[ 5221.310000] kmalloc-256               64KB         80KB
[ 5221.310000] kmalloc-192               78KB         78KB
[ 5221.320000] kmalloc-128               22KB         24KB
[ 5221.320000] kmalloc-96                60KB         98KB
[ 5221.330000] kmalloc-32             97766KB      97770KB
[ 5221.340000] kmalloc-64               173KB        176KB
[ 5221.340000] kmem_cache                31KB         35KB
[ 5221.350000] Tasks state (memory values in pages):
[ 5221.350000] [  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
[ 5221.360000] [    617]     0   617      458       30     8192        0             0 bootlogd
[ 5221.370000] [    653]     0   653      776       11     8192        0             0 syslogd
[ 5221.380000] [    656]     0   656      776       12     6144        0             0 klogd
[ 5221.380000] [    676]     0   676     1578      299    10240        0             0 conf-manager
[ 5221.390000] [    679]     0   679      484       27     6144        0             0 conf-dispatcher
[ 5221.400000] [    688]     0   688      432       17     8192        0             0 keypad
[ 5221.410000] [    700]     0   700      904       79     8192        0         -1000 udevd
[ 5221.420000] [    717]    81   717     1074       49     8192        0             0 dbus-daemon
[ 5221.430000] [    747]     0   747      776       11     8192        0             0 respawn.sh
[ 5221.440000] [    749]     0   749     1493       69    10240        0             0 connmand
[ 5221.440000] [    751]    99   751      581       27     6144        0             0 dnsmasq
[ 5221.450000] [    755]     0   755      572       21     6144        0             0 dropbear
[ 5221.460000] [    759]     0   759     1083       75    10240        0             0 lighttpd
[ 5221.470000] [    761]     0   761     4393      291    20480        0             0 php-cgi
[ 5221.480000] [    763]     0   763     4393      291    22528        0             0 php-cgi
[ 5221.490000] [    768]     0   768      777       39     6144        0             0 lns_networking.
[ 5221.500000] [    839]     0   839      455       23     6144        0             0 inotifywait
[ 5221.500000] [    897]     0   897      776        9     6144        0             0 ntpd
[ 5221.510000] [    905]     0   905     1404       22     8192        0             0 crond
[ 5221.520000] [    922]     0   922      484       21     8192        0             0 event-monitor
[ 5221.530000] [    941]     0   941     1011       29     8192        0             0 sh
[ 5221.540000] [   1062]     0  1062      383       11     6144        0             0 test_open
[ 5221.550000] [   1063]     0  1063      592       31     8192        0             0 dropbear
[ 5221.550000] [   1064]     0  1064     1011       30     8192        0             0 sh
[ 5221.560000] [   5315]     0  5315      776       15     6144        0             0 check_online.sh
[ 5221.570000] [   5316]     0  5316      776       15     4096        0             0 check_online.sh
[ 5221.580000] [   5317]     0  5317     1159       53    10240        0             0 socat
[ 5221.590000] [   5318]     0  5318     1016       37    10240        0             0 xsltproc
[ 5221.600000] [   5319]     0  5319      777        9     8192        0             0 uniq
[ 5221.610000] Out of memory: Kill process 676 (conf-manager) score 9 or sacrifice child
[ 5221.610000] Killed process 676 (conf-manager) total-vm:6312kB, anon-rss:1196kB, file-rss:0kB, shmem-rss:0kB


full stabinfo:
slabinfo - version: 2.1 (statistics)
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow> : cpustat <allochit> <allocmiss> <freehit> <freemiss>
ubi_wl_entry_slab   1964   1992     48   83    1 : tunables   32   16    0 : slabdata     24     24      0 : globalstat    1973   1973    24    0    0    0    0    0    0 : cpustat   1822    142      0      0
ubifs_inode_slab      66    189    432    9    1 : tunables   32   16    0 : slabdata     21     21      0 : globalstat   92965    477    53    0    0    0    0    0    0 : cpustat 354826   5836 355569   5041
bridge_fdb_cache       2     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      48     17     1    0    0    0    0    0    0 : cpustat      1      3      2      0
nf-frags               0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm6_tunnel_spi       0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ip6-frags              0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fib6_nodes             6     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     17     1    0    0    0    0    0    0 : cpustat      4      2      0      0
ip6_dst_cache          3     25    160   25    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat     640     19     1    0    0    0    0    0    0 : cpustat     32     40     69      0
PINGv6                 0      0    832    9    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
RAWv6                  5      9    832    9    2 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      13      9     1    0    0    0    0    0    0 : cpustat      4      2      1      0
UDPLITEv6              0      0    832    9    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
UDPv6                  1      9    832    9    2 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      17      9     1    0    0    0    0    0    0 : cpustat      4      2      5      0
tw_sock_TCPv6          0      0    200   20    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_sock_TCPv6      0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
TCPv6                  1      4   1760    4    2 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       4      4     1    0    0    0    0    0    0 : cpustat      1      1      1      0
nf_conntrack_expect      0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nf_conntrack           0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
sd_ext_cdb             2     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-128             2      2   2048    2    1 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       2      2     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-64              2      4   1024    4    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       4      4     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-32              2      8    512    8    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       8      8     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-16              2     16    256   16    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-8               2     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
nfs_direct_cache       0      0    208   19    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_commit_data        4      9    448    9    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       9      9     1    0    0    0    0    0    0 : cpustat      3      1      0      0
nfs_write_data        32     35    576    7    1 : tunables   32   16    0 : slabdata      5      5      0 : globalstat      35     35     5    0    0    0    0    0    0 : cpustat     27      5      0      0
nfs_read_data          0      0    576    7    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_inode_cache        0      0    608    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_page               0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fat_inode_cache        0      0    424    9    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fat_cache              0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_transaction_s      0      0    160   25    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_inode             0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_journal_handle      0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_journal_head      0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_revoke_table_s      0      0     40   99    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_revoke_record_s      0      0     32  124    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_inode_cache       0      0    624    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_free_data         0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_allocation_context      0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_prealloc_space      0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_system_zone       0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_io_end            0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_pending_reservation      0      0     40   99    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_extent_status      0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
mbcache                0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kioctx                 0      0    224   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
aio_kiocb              0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fanotify_event_info      0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fsnotify_mark          0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dnotify_mark           0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dnotify_struct         0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dio                    0      0    360   11    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
bio-1                  4     25    160   25    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      3      1      0      0
fasync_cache           0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
posix_timers_cache      0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
rpc_inode_cache        0      0    352   11    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
rpc_buffers            8      8   2048    2    1 : tunables   24   12    0 : slabdata      4      4      0 : globalstat       8      8     4    0    0    0    0    0    0 : cpustat      4      4      0      0
rpc_tasks              8     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      7      1      0      0
UNIX                   7     28    576    7    1 : tunables   32   16    0 : slabdata      4      4      0 : globalstat   65532     35    88   84    0    0    0    0    0 : cpustat  20071   4224  24288      0
ip4-frags              0      0    160   25    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
UDP-Lite               0      0    704   11    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
tcp_bind_bucket        1     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      4      1      4      0
inet_peer_cache        0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
secpath_cache          0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm_dst_cache         0      0    224   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm_state             0      0    576    7    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ip_fib_trie           12     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     19     1    0    0    0    0    0    0 : cpustat     11      2      1      0
ip_fib_alias          15     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     20     1    0    0    0    0    0    0 : cpustat     14      2      1      0
ip_dst_cache          10     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1824     24     1    0    0    0    0    0    0 : cpustat    116    114    222      0
PING                   0      0    672    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
RAW                    2      6    672    6    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      10      6     1    0    0    0    0    0    0 : cpustat     12      2     12      0
UDP                    0      0    704   11    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat     994     11     2    2    0    0    0    0    0 : cpustat    580    123    703      0
tw_sock_TCP            0      0    200   20    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_sock_TCP       0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      0      1      1      0
TCP                    1      4   1664    4    2 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       5      4     1    0    0    0    0    0    0 : cpustat     11      2     12      0
eventpoll_pwq          5     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1392     48     1    0    0    0    0    0    0 : cpustat     61     87    142      1
eventpoll_epi          5     42     96   42    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1386     42     1    0    0    0    0    0    0 : cpustat     61     87    143      0
inotify_inode_mark     15     56     72   56    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      48     39     1    0    0    0    0    0    0 : cpustat     21      3      9      0
scsi_data_buffer       0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_queue         12     15   1536    5    2 : tunables   24   12    0 : slabdata      3      3      0 : globalstat      15     15     3    0    0    0    0    0    0 : cpustat      9      3      0      0
blkdev_requests        0      0    216   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
blkdev_ioc             1     51     80   51    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
bio-0                 26     50    160   25    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      41     41     2    0    0    0    0    0    0 : cpustat     27      3      4      0
biovec-max            30     30   3072    2    2 : tunables   24   12    0 : slabdata     15     15      0 : globalstat      30     30    15    0    0    0    0    0    0 : cpustat     15     15      0      0
biovec-128             0      0   1536    5    2 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
biovec-64              0      0    768    5    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
biovec-16              0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
uid_cache              0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      1      1      2      0
dmaengine-unmap-2      1    124     32  124    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
sock_inode_cache      26     66    352   11    1 : tunables   32   16    0 : slabdata      6      6      0 : globalstat   55763     77     7    0    0    0    0    0    0 : cpustat   7743   3489  11206      0
skbuff_fclone_cache      0      0    384   10    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat    5630     10   552  552    0    0    0    0    0 : cpustat    122    563    685      0
skbuff_head_cache     12     42    192   21    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   56541    121     6    1    0    0    0    0    0 : cpustat  24027   3924  27932      9
configfs_dir_cache      1     51     80   51    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
file_lock_cache        0      0    144   28    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat    1696     18   103  103    0    0    0    0    0 : cpustat   1338    106   1444      0
file_lock_ctx          1     83     48   83    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
fsnotify_mark_connector     15     99     40   99    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     32     1    0    0    0    0    0    0 : cpustat     20      2      7      0
shmem_inode_cache    545    560    384   10    1 : tunables   32   16    0 : slabdata     56     56      0 : globalstat     573    560    56    0    0    0    0    0    0 : cpustat    533     58     46      0
proc_dir_entry       203    208    152   26    1 : tunables   32   16    0 : slabdata      8      8      0 : globalstat     232    208     8    0    0    0    0    0    0 : cpustat 1655734     19 1655550      0
pde_opener            16     83     48   83    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    3392     16   208  207    0    0    0    0    0 : cpustat    379    212    590      0
proc_inode_cache      19     20    384   10    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   65673    330    58   24    0    2    0    0    0 : cpustat  17629   9256  26850     29
seq_file              16     39    104   39    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    3440     19     4    3    0    0    0    0    0 : cpustat   1822    215   2036      0
sigqueue               0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat     496     25    28   28    0    0    0    0    0 : cpustat     22     31     53      0
bdev_cache            13     18    448    9    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      26     18     2    0    0    0    0    0    0 : cpustat     14      3      4      0
kernfs_node_cache   6152   6156    112   36    1 : tunables   32   16    0 : slabdata    171    171      0 : globalstat    6164   6152   171    0    0    0    0    0    0 : cpustat   6046    512    406      0
mnt_cache             23     36    224   18    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      34     34     2    0    0    0    0    0    0 : cpustat     20      3      0      0
filp                  94    325    160   25    1 : tunables   32   16    0 : slabdata     13     13      0 : globalstat   56563    366    16    1    0    1    0    0    0 : cpustat 2140672   3542 2141060   3073
inode_cache         7258   7260    344   11    1 : tunables   32   16    0 : slabdata    660    660      0 : globalstat    9668   8316   828   77    0    0    0    0    0 : cpustat   9994    928   3600     64
dentry              7885   8800    160   25    1 : tunables   32   16    0 : slabdata    352    352      0 : globalstat  209061   9941   398    0    0    1    0    0    0 : cpustat 579132  13240 572829  11669
names_cache            1      1   4096    1    1 : tunables   24   12    0 : slabdata      1      1      0 : globalstat    1216     11   965  964    0    0    0    0    0 : cpustat 2313916   1211 2315127      0
key_jar                3     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      2      1      0      0
buffer_head            0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      3      1      4      0
nsproxy                1     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
vm_area_struct       196    646    120   34    1 : tunables   32   16    0 : slabdata     19     19      0 : globalstat  493665   1326    41    1    0    1    0    0    0 : cpustat 1030662  30889 1031088  30293
mm_struct             25     36    416    9    1 : tunables   32   16    0 : slabdata      4      4      0 : globalstat   19979     45     5    1    0    0    0    0    0 : cpustat  44416   1297  45703      0
fs_cache              18    124     32  124    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1904    112     1    0    0    0    0    0    0 : cpustat  23929    119  24029      9
files_cache           18     63    192   21    1 : tunables   32   16    0 : slabdata      3      3      0 : globalstat    1913    105     5    0    0    0    0    0    0 : cpustat  23925    123  24028     10
signal_cache          45     72    608    6    1 : tunables   32   16    0 : slabdata     12     12      0 : globalstat   15230    120    20    1    0    0    0    0    0 : cpustat  23152    965  24070     10
sighand_cache         43     57   1312    3    1 : tunables   24   12    0 : slabdata     19     19      0 : globalstat    1401    117    48    8    0    6    0    0    0 : cpustat  23947    170  24066     14
task_struct           43     84   1056    7    2 : tunables   24   12    0 : slabdata     12     12      0 : globalstat   11531    119    18    0    0    1    0    0    0 : cpustat  23150    969  24064     18
cred_jar              70    160    128   32    1 : tunables   32   16    0 : slabdata      5      5      0 : globalstat   20529    144     5    0    0    0    0    0    0 : cpustat  56391   1284  57604     15
anon_vma_chain       161    781     56   71    1 : tunables   32   16    0 : slabdata     11     11      0 : globalstat  139671   1381    21    1    0    1    0    0    0 : cpustat 472282   8741 473000   7891
anon_vma             125    567     64   63    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat   68139    741    12    0    0    0    0    0    0 : cpustat 329676   4260 330198   3626
pid                   50    126     64   63    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   15054    126     2    0    0    0    0    0    0 : cpustat  23178    941  24066     11
debug_objects_cache   1024   1079     48   83    1 : tunables   32   16    0 : slabdata     13     13      0 : globalstat    1028   1028    13    0    0    0    0    0    0 : cpustat    950     74      0      0
trace_event_file    1219   1232     72   56    1 : tunables   32   16    0 : slabdata     22     22      0 : globalstat    1219   1219    22    0    0    0    0    0    0 : cpustat      0   1219      0      0
ftrace_event_field   2953   2982     56   71    1 : tunables   32   16    0 : slabdata     42     42      0 : globalstat    2959   2959    42    0    0    0    0    0    0 : cpustat   2745    208      0      0
pool_workqueue         4     16    256   16    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      2      2      0      0
radix_tree_node      193    300    328   12    1 : tunables   32   16    0 : slabdata     25     25      0 : globalstat   60882    396    33    0    0    0    0    0    0 : cpustat 234553   3841 234990   3211
kmalloc-rcl-4M         0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-2M         0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-1M         0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-512k       0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-256k       0      0 262144    1   64 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-128k       0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-64k        0      0  65536    1   16 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-32k        0      0  32768    1    8 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-16k        0      0  16384    1    4 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-8k         0      0   8192    1    2 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-4k         0      0   4096    1    1 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-2k         0      0   2048    2    1 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-1k         0      0   1024    4    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-512        0      0    512    8    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-256        0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-192        0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-128        0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-96         0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-64         1     64     64   64    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-rcl-32         0      0     32  124    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-4M             0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-2M             0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-1M             0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-512k           0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-256k           1      1 262144    1   64 : tunables    1    1    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-128k           0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-64k            1      1  65536    1   16 : tunables    8    4    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-32k            1      1  32768    1    8 : tunables    8    4    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-16k            2      2  16384    1    4 : tunables    8    4    0 : slabdata      2      2      0 : globalstat     222      4   212  210    0    0    0    0    0 : cpustat   7107    220   7325      0
kmalloc-8k             9      9   8192    1    2 : tunables    8    4    0 : slabdata      9      9      0 : globalstat     503     20   155  146    0    4    0    0    0 : cpustat 22043876    253 22044039     82
kmalloc-4k            27     27   4096    1    1 : tunables   24   12    0 : slabdata     27     27      0 : globalstat     504    135   399  255    0   25    0    0    0 : cpustat   3415    419   3789     18
kmalloc-2k            54     54   2048    2    1 : tunables   24   12    0 : slabdata     27     27      0 : globalstat    2022     68    36    9    0    0    0    0    0 : cpustat    858    667   1474      0
kmalloc-1k           151    172   1024    4    1 : tunables   32   16    0 : slabdata     43     43      0 : globalstat    1056    196    54   11    0    3    0    0    0 : cpustat    453    153    453      2
kmalloc-512          302    320    512    8    1 : tunables   32   16    0 : slabdata     40     40      0 : globalstat    7933    400    51    3    0    2    0    0    0 : cpustat 2220216    547 2220469      8
kmalloc-256          293    304    256   16    1 : tunables   32   16    0 : slabdata     19     19      0 : globalstat 12361098   1616 53263  284    0    2    0    0    0 : cpustat 19771823 772713 19771803 772442
kmalloc-192          410    420    192   21    1 : tunables   32   16    0 : slabdata     20     20      0 : globalstat    3763    417    20    0    0    0    0    0    0 : cpustat 20526116    416 20526138      0
kmalloc-128          288    288    128   32    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat   11689    288    13    4    0    0    0    0    0 : cpustat  21015   1676  22409      0
kmalloc-96           666    966     96   42    1 : tunables   32   16    0 : slabdata     23     23      0 : globalstat  138190   1241    30    0    0    0    0    0    0 : cpustat 264861   8696 269873   3026
kmalloc-32        3317614 3317620     32  124    1 : tunables   32   16    0 : slabdata  26755  26755      0 : globalstat 3329656 3317661 26779   17    0    1    0    0    0 : cpustat 11621275 215178 8518750    104
kmalloc-64          3094   3136     64   64    1 : tunables   32   16    0 : slabdata     49     49      0 : globalstat 1643930   3440 20618    0    0    1    0    0    0 : cpustat 46206626 102866 46203878 102535
kmem_cache           169    189    192   21    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat     184    184     9    0    0    0    0    0    0 : cpustat    114     57      2      0

# cat /proc/meminfo
MemTotal:         122316 kB
MemFree:            1804 kB
MemAvailable:       2468 kB
Buffers:               0 kB
Cached:              716 kB
SwapCached:            0 kB
Active:             1148 kB
Inactive:            404 kB
Active(anon):        932 kB
Inactive(anon):      188 kB
Active(file):        216 kB
Inactive(file):      216 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           884 kB
Mapped:              472 kB
Shmem:               236 kB
KReclaimable:       4284 kB
Slab:             115048 kB
SReclaimable:       4284 kB
SUnreclaim:       110764 kB
KernelStack:         296 kB
PageTables:          136 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       61156 kB
Committed_AS:       5640 kB
VmallocTotal:     901120 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
Percpu:               64 kB

# cat /proc/slab_allocators 
ubi_wl_entry_slab: 3 erase_aeb+0x34/0xe0
ubi_wl_entry_slab: 805 ubi_wl_init+0x148/0x4e4
ubi_wl_entry_slab: 1155 ubi_wl_init+0x218/0x4e4
ubi_wl_entry_slab: 1 ubi_scan_fastmap+0x6f8/0x8fc
ubifs_inode_slab: 50 ubifs_alloc_inode+0x24/0x60
sd_ext_cdb: 2 mempool_alloc_slab+0x24/0x28
ip_fib_trie: 12 fib_insert_alias+0x40/0x298
ip_fib_alias: 15 fib_table_insert+0x33c/0x49c
eventpoll_pwq: 5 ep_ptable_queue_proc+0x38/0xb4
inotify_inode_mark: 15 sys_inotify_add_watch+0x12c/0x2bc
request_queue: 12 blk_alloc_queue_node+0x34/0x280
blkdev_ioc: 1 create_task_io_context+0x28/0xe0
configfs_dir_cache: 1 configfs_new_dirent+0x30/0xb4
file_lock_ctx: 1 locks_get_lock_context+0x48/0x10c
fsnotify_mark_connector: 15 fsnotify_add_mark_locked+0xbc/0x2b0
shmem_inode_cache: 545 shmem_alloc_inode+0x24/0x38
proc_dir_entry: 202 __proc_create+0x160/0x22c
proc_dir_entry: 1 proc_net_ns_init+0x28/0xd0
pde_opener: 1 proc_reg_open+0x7c/0x140
proc_inode_cache: 6 proc_alloc_inode+0x24/0x5c
seq_file: 1 seq_open+0x44/0xa4
kernfs_node_cache: 6152 __kernfs_new_node+0x48/0x174
inode_cache: 7258 alloc_inode+0x40/0xa8
dentry: 7872 __d_alloc+0x2c/0x1b4
nsproxy: 1 create_new_namespaces+0x34/0x144
vm_area_struct: 70 vm_area_alloc+0x28/0x68
vm_area_struct: 100 vm_area_dup+0x28/0x58
anon_vma_chain: 41 __anon_vma_prepare+0x28/0x124
anon_vma_chain: 51 anon_vma_clone+0x3c/0x168
anon_vma_chain: 40 anon_vma_fork+0x88/0x144
anon_vma: 72 __anon_vma_prepare+0x50/0x124
anon_vma: 40 anon_vma_fork+0x60/0x144
debug_objects_cache: 1024 debug_objects_mem_init+0x8c/0x248
trace_event_file: 1219 trace_create_new_event+0x24/0x6c
ftrace_event_field: 2953 __trace_define_field+0x30/0x98
radix_tree_node: 11 __radix_tree_preload.constprop.4+0x28/0x80
radix_tree_node: 125 radix_tree_node_alloc.constprop.5+0x54/0xd8
radix_tree_node: 11 radix_tree_node_alloc.constprop.5+0x8c/0xd8
radix_tree_node: 45 xas_alloc+0x40/0xb0

^ permalink raw reply

* DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak
From: richard.genoud @ 2018-11-27  9:55 UTC (permalink / raw)
  To: Ludovic Desroches, Nicolas Ferre, Maxime Ripard, Vinod Koul,
	Alexandre Belloni
  Cc: linux-arm-kernel@lists.infradead.org, dmaengine, Linux Kernel,
	linux-serial@vger.kernel.org, Mario Forner
In-Reply-To: <22061488.b0eNpyQjWt@linux-7rm0>

[re-sending with Vinod's correct email address. Sorry for the noise. ]

[re-sending the bug report to the lists]
Le 16/11/2018 à 17:04, Mario Forner a écrit :
> Problem:
> When I open and close the serial device /dev/ttyS4 in a loop
> the amount of kmalloc-32 slabs increases slowly but steadily without limit.
> 
> The serial device is configured in acme-aria.dts to use DMA.
> 
> If DMA is disabled, the amount of kmalloc32-slabs remains constant
> over several hours, just fluctuating slightly.
> 
> The serial device is accessed by atmel_serial.c which is evident from
> the drivers kernel log output.
> 
> The bug was noticed on a device which had been running over several weeks and
> has accumulated ~86MB of unrelaimable kmalloc-32 slabs by now. Example:
> 
> root@master1083:~# slabtop -o | head -10
>  Active / Total Objects (% used)    : 2704880 / 2716124 (99.6%)
>  Active / Total Slabs (% used)      : 23150 / 23150 (100.0%)
>  Active / Total Caches (% used)     : 57 / 76 (75.0%)
>  Active / Total Size (% used)       : 88893.62K / 89964.32K (98.8%)
>  Minimum / Average / Maximum Object : 0.02K / 0.03K / 4096.00K
> 
>   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
> 2674804 2673840  99%    0.03K  21571      124     86284K kmalloc-32
>   7200   7104  98%    0.08K    144       50       576K kernfs_node_cache
>   6930   5370  77%    0.13K    231       30       924K dentry     
> 
> root@master1083:~# uptime
>  15:12:55 up 93 days, 16:54,  1 user,  load average: 1.59, 2.31, 2.42 
> 
> Keywords:  atmel, serial, kernel, leak, memory, dma, slab, kmalloc
> 
> Kernel information:
> 
> Kernel version:
> Linux version 4.2.6 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) #115 Fri Nov 16 11:05:22 CET 2018
> Linux version 4.9.124 (mario@linux-7rm0) (gcc version 4.9.3 (crosstool-NG ) ) #16 Fri Nov 16 13:54:25 CET 2018   
> 
> Most recent Kernel version which did not have the bug:  unknown         
> 
> How to reproduce the bug:
> 
> The kmalloc-32 slab count should be monitored every few minutes with "slabtop -o".
> The leak can be triggered by running the following script, given DMA has
> been enabled for ttyS4:
> 
> #!/usr/bin/env python
> import serial
> import time
> 
> while True:
>     try:
>         with serial.Serial(port = '/dev/ttyS4'):
>             pass
>     except Exception as e:
>         print e
>     finally:
>         time.sleep(0.5)
> # end script
> 
> Environment:
> Software:
> Linux master 4.2.6 #114 Fri Nov 16 10:14:30 CET 2018 armv5tejl GNU/Linux
> 
> Binutils                2.25
> Util-linux              2.25.2
> Mount                   2.25.2
> Module-init-tools       18
> E2fsprogs               1.42.12
> Linux C Library         2.19
> Dynamic linker (ldd)    2.19
> Linux C++ Library       6.0.20
> Procps                  3.3.9
> Net-tools               1.60
> Sh-utils                8.23
> Udev                    215
> Modules Loaded          iptable_nat option usb_wwan usbserial  
> 
> Processor information:
> # cat /proc/cpuinfo
> processor       : 0
> model name      : ARM926EJ-S rev 5 (v5l)
> BogoMIPS        : 198.76
> Features        : swp half thumb fastmult edsp java
> CPU implementer : 0x41
> CPU architecture: 5TEJ
> CPU variant     : 0x0
> CPU part        : 0x926
> CPU revision    : 5
> 
> Hardware        : Atmel AT91SAM9
> Revision        : 0000
> Serial          : 0000000000000000  
> 
> Module information:
> # cat /proc/modules
> iptable_nat 1720 0 - Live 0xbf0a5000
> option 28780 0 - Live 0xbf03c000
> usb_wwan 6876 1 option, Live 0xbf024000
> usbserial 23392 2 option,usb_wwan, Live 0xbf000000
> 
> Loaded drivers:
> # cat /proc/ioports
> # cat /proc/iomem
> 00300000-00307fff : 300000.sram
> 00600000-006fffff : /ahb/ohci@00600000
> 00700000-007fffff : /ahb/ehci@00700000
> 20000000-2fffffff : System RAM
>   20008000-20577287 : Kernel code
>   205a8000-205f02b7 : Kernel data
> f0000000-f00000ff : /ahb/apb/spi@f0000000
> f8008000-f80080ff : /ahb/apb/timer@f8008000
> f800c000-f800c0ff : /ahb/apb/timer@f800c000
> f8010000-f80100ff : /ahb/apb/i2c@f8010000
> f8014000-f80140ff : /ahb/apb/i2c@f8014000
> f801c000-f801c1ff : atmel_serial
> f8020000-f80201ff : atmel_serial
> f8024000-f80241ff : atmel_serial
> f8028000-f80281ff : atmel_serial
> f802c000-f802c0ff : /ahb/apb/ethernet@f802c000
> f8034000-f80342ff : /ahb/apb/pwm@f8034000
> f804c000-f804c0ff : /ahb/apb/adc@f804c000
> ffffec00-ffffedff : at_hdmac
> ffffee00-ffffefff : at_hdmac
> fffff200-fffff3ff : atmel_serial
> fffff400-fffff5ff : /ahb/apb/pinctrl@fffff400/gpio@fffff400
> fffff600-fffff7ff : /ahb/apb/pinctrl@fffff400/gpio@fffff600
> fffff800-fffff9ff : /ahb/apb/pinctrl@fffff400/gpio@fffff800
> fffffa00-fffffbff : /ahb/apb/pinctrl@fffff400/gpio@fffffa00
> fffffe10-fffffe1f : /ahb/apb/shdwc@fffffe10
> 
> Other Information:
> The serial device ttyS4 is configuered inside .dts file by
> 
> usart3: serial@f8028000 {
>     status = "okay";
>     compatible = "atmel,at91sam9260-usart";
>     reg = <0xf8028000 0x200>;
>     interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
>     pinctrl-names = "default";
>     atmel,use-dma-tx;
>     atmel,use-dma-rx;
>     pinctrl-0 = <&pinctrl_usart3
>     &pinctrl_usart3_rts~
>     &pinctrl_usart3_cts>;
>     linux,rs485-enabled-at-boot-time;
>     rs485-rts-delay = <0 0>;
> };
> 
> Other notes:
> I tried the SLUB allocator with slub_debug=U but opening serial device then
> resulted in a Kernel-Oops:
>     at BUGON(ents < 0);
>     in function: dma_map_sg_attrs
>     in file: /include/asm-generic/dma-mapping-common.h
> So I could not gather information that way. I don't know if this is related.
> SLUB works if User Tracking is disabled.
> 
> Enabling kmemleak did not detect any leaks.
> 
> I also tried kernel version 4.19.1 and it exhibits the same behaviour, but I
> could not configure it to run reliably on the target system yet. 
> 

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 ?



The oom-killer, slabinfo, meminfo and slab_allocator traces follow.

NB: the -dirty flag is there beacause I removed some log from atmel-serial:
--- 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);



OOM-killer trace :
[ 5220.560000] test_open invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), nodemask=(null), order=0, oom_score_adj=0
[ 5220.580000] CPU: 0 PID: 1062 Comm: test_open Not tainted 4.20.0-rc3-dirty #31
[ 5220.580000] Hardware name: Atmel AT91SAM9
[ 5220.590000] Backtrace: [ 5220.590000] [<c000e020>] (dump_backtrace) from [<c000e2b8>] (show_stack+0x20/0x24)
[ 5220.600000]  r6:00000009 r5:c0649bb5 r4:c72a1e18 r3:02b88502
[ 5220.600000] [<c000e298>] (show_stack) from [<c0521114>] (dump_stack+0x20/0x28)
[ 5220.610000] [<c05210f4>] (dump_stack) from [<c0097280>] (dump_header+0x6c/0x1c4)
[ 5220.620000] [<c0097214>] (dump_header) from [<c0096454>] (oom_kill_process+0x6c/0x3cc)
[ 5220.620000]  r10:00000001 r8:c070e788 r7:c72a1e18 r6:00000009 r5:c0649bb5 r4:c7b64ea0
[ 5220.630000] [<c00963e8>] (oom_kill_process) from [<c009712c>] (out_of_memory+0x388/0x41c)
[ 5220.640000]  r10:00000001 r9:00000000 r8:c070e788 r7:0000000b r6:c070e8e4 r5:c070e788
[ 5220.650000]  r4:c72a1e18
[ 5220.650000] [<c0096da4>] (out_of_memory) from [<c009b1d8>] (__alloc_pages_nodemask+0x8b4/0xc48)
[ 5220.660000]  r8:00000011 r7:00000000 r6:00000000 r5:00000000 r4:006200ca
[ 5220.670000] [<c009a924>] (__alloc_pages_nodemask) from [<c0092bd4>] (filemap_fault+0x384/0x54c)
[ 5220.680000]  r10:c609b480 r9:00000000 r8:00000004 r7:00000000 r6:c72a1ed0 r5:c77dbb5c
[ 5220.680000]  r4:006200ca
[ 5220.690000] [<c0092850>] (filemap_fault) from [<c00babe8>] (__do_fault+0x28/0x9c)
[ 5220.690000]  r10:c7375a20 r9:c7375a58 r8:80000005 r7:000000b1 r6:b6efe000 r5:c72a1ed0
[ 5220.700000]  r4:00000000
[ 5220.700000] [<c00babc0>] (__do_fault) from [<c00bd9b0>] (handle_mm_fault+0x3e4/0x97c)
[ 5220.710000]  r5:000000c0 r4:00000000
[ 5220.720000] [<c00bd5cc>] (handle_mm_fault) from [<c000f774>] (do_page_fault+0x138/0x2ac)
[ 5220.720000]  r7:00000054 r6:b6efef9c r5:c72a1fb0 r4:c7a300e0
[ 5220.730000] [<c000f63c>] (do_page_fault) from [<c000f99c>] (do_translation_fault+0x2c/0xb4)
[ 5220.740000]  r10:b6f9e000 r9:00000000 r8:00053177 r7:80000005 r6:b6efef9c r5:c070f91c
[ 5220.750000]  r4:00000005
[ 5220.750000] [<c000f970>] (do_translation_fault) from [<c000fb38>] (do_PrefetchAbort+0x44/0x94)
[ 5220.760000]  r7:c72a1fb0 r6:b6efef9c r5:c070f91c r4:00000005
[ 5220.760000] [<c000faf4>] (do_PrefetchAbort) from [<c0009f08>] (ret_from_exception+0x0/0x18)
[ 5220.770000] Exception stack(0xc72a1fb0 to 0xc72a1ff8)
[ 5220.780000] 1fa0:                                     00000000 00000000 beb25d54 beb25e71
[ 5220.780000] 1fc0: 00000000 00000000 000082f4 00000006 00000000 00000000 b6f9e000 beb25bf4
[ 5220.790000] 1fe0: 00000000 beb25bdc 0000847c b6efef9c 40000010 ffffffff
[ 5220.800000]  r7:0005317f r6:ffffffff r5:40000010 r4:b6efef9c
[ 5220.800000] Mem-Info:
[ 5220.810000] active_anon:1659 inactive_anon:47 isolated_anon:0
[ 5220.810000]  active_file:2 inactive_file:4 isolated_file:0
[ 5220.810000]  unevictable:0 dirty:0 writeback:0 unstable:0
[ 5220.810000]  slab_reclaimable:1098 slab_unreclaimable:26200
[ 5220.810000]  mapped:3 shmem:60 pagetables:125 bounce:0
[ 5220.810000]  free:344 free_pcp:45 free_cma:0
[ 5220.840000] Node 0 active_anon:6636kB inactive_anon:188kB active_file:8kB inactive_file:16kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:12kB dirty:0kB writeback:0kB shmem:240kB writeback_tmp:0kB unstable:0kB all_unreclaimable? yes
[ 5220.860000] Normal free:1376kB min:1396kB low:1744kB high:2092kB active_anon:6636kB inactive_anon:188kB active_file:8kB inactive_file:16kB unevictable:0kB writepending:0kB present:131072kB managed:122316kB mlocked:0kB kernel_stack:448kB pagetables:500kB bounce:0kB free_pcp:180kB local_pcp:180kB free_cma:0kB
[ 5220.890000] lowmem_reserve[]: 0 0
[ 5220.890000] Normal: 0*4kB 54*8kB (U) 29*16kB (U) 11*32kB (U) 2*64kB (U) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 1376kB
[ 5220.900000] 66 total pagecache pages
[ 5220.910000] 32768 pages RAM
[ 5220.910000] 0 pages HighMem/MovableOnly
[ 5220.910000] 2189 pages reserved
[ 5220.920000] Unreclaimable slab info:
[ 5220.920000] Name                      Used          Total
[ 5220.930000] ubi_wl_entry_slab         92KB         93KB
[ 5220.930000] bridge_fdb_cache           0KB          3KB
[ 5220.940000] fib6_nodes                 0KB          3KB
[ 5220.940000] ip6_dst_cache              0KB          3KB
[ 5220.950000] RAWv6                      4KB          7KB
[ 5220.950000] UDPv6                      1KB          7KB
[ 5220.960000] TCPv6                      3KB          6KB
[ 5220.960000] sd_ext_cdb                 0KB          3KB
[ 5220.970000] sgpool-128                 4KB          4KB
[ 5220.970000] sgpool-64                  2KB          4KB
[ 5220.980000] sgpool-32                  1KB          4KB
[ 5220.980000] sgpool-16                  0KB          4KB
[ 5220.990000] sgpool-8                   0KB          4KB
[ 5220.990000] nfs_commit_data            1KB          3KB
[ 5221.000000] nfs_write_data            18KB         19KB
[ 5221.000000] bio-1                      0KB          3KB
[ 5221.010000] rpc_buffers               16KB         16KB
[ 5221.010000] rpc_tasks                  1KB          4KB
[ 5221.020000] UNIX                      14KB         15KB
[ 5221.030000] tcp_bind_bucket            0KB          3KB
[ 5221.030000] ip_fib_trie                0KB          3KB
[ 5221.040000] ip_fib_alias               0KB          3KB
[ 5221.040000] ip_dst_cache               1KB          4KB
[ 5221.050000] RAW                        1KB          3KB
[ 5221.050000] UDP                        2KB          7KB
[ 5221.060000] TCP                        6KB          6KB
[ 5221.060000] eventpoll_pwq              0KB          3KB
[ 5221.070000] eventpoll_epi              1KB          3KB
[ 5221.070000] inotify_inode_mark          1KB          3KB
[ 5221.080000] request_queue             18KB         22KB
[ 5221.080000] blkdev_ioc                 0KB          3KB
[ 5221.090000] bio-0                      4KB          7KB
[ 5221.090000] biovec-max                90KB         90KB
[ 5221.100000] uid_cache                  0KB          3KB
[ 5221.100000] dmaengine-unmap-2          0KB          3KB
[ 5221.110000] skbuff_head_cache          5KB          7KB
[ 5221.110000] configfs_dir_cache          0KB          3KB
[ 5221.120000] file_lock_ctx              0KB          3KB
[ 5221.130000] fsnotify_mark_connector          0KB          3KB
[ 5221.130000] shmem_inode_cache        205KB        210KB
[ 5221.140000] proc_dir_entry            30KB         30KB
[ 5221.140000] pde_opener                 0KB          3KB
[ 5221.150000] seq_file                   0KB          3KB
[ 5221.150000] kernfs_node_cache        672KB        673KB
[ 5221.160000] mnt_cache                  5KB          7KB
[ 5221.160000] filp                      52KB         58KB
[ 5221.170000] names_cache               24KB         24KB
[ 5221.170000] key_jar                    0KB          4KB
[ 5221.180000] nsproxy                    0KB          3KB
[ 5221.180000] vm_area_struct            92KB        103KB
[ 5221.190000] mm_struct                 12KB         14KB
[ 5221.190000] fs_cache                   0KB          3KB
[ 5221.200000] files_cache                5KB         11KB
[ 5221.200000] signal_cache              33KB         46KB
[ 5221.210000] sighand_cache             71KB         80KB
[ 5221.210000] task_struct               57KB         86KB
[ 5221.220000] cred_jar                  13KB         20KB
[ 5221.220000] anon_vma_chain            32KB         46KB
[ 5221.230000] anon_vma                  29KB         39KB
[ 5221.240000] pid                        4KB          7KB
[ 5221.240000] debug_objects_cache         48KB         50KB
[ 5221.250000] trace_event_file          85KB         86KB
[ 5221.250000] ftrace_event_field        161KB        163KB
[ 5221.260000] pool_workqueue             1KB          4KB
[ 5221.260000] kmalloc-256k             256KB        256KB
[ 5221.270000] kmalloc-64k               64KB         64KB
[ 5221.270000] kmalloc-32k               32KB         32KB
[ 5221.280000] kmalloc-16k               32KB         32KB
[ 5221.280000] kmalloc-8k               128KB        128KB
[ 5221.290000] kmalloc-4k               104KB        104KB
[ 5221.290000] kmalloc-2k               102KB        108KB
[ 5221.300000] kmalloc-1k               191KB        192KB
[ 5221.300000] kmalloc-512              154KB        168KB
[ 5221.310000] kmalloc-256               64KB         80KB
[ 5221.310000] kmalloc-192               78KB         78KB
[ 5221.320000] kmalloc-128               22KB         24KB
[ 5221.320000] kmalloc-96                60KB         98KB
[ 5221.330000] kmalloc-32             97766KB      97770KB
[ 5221.340000] kmalloc-64               173KB        176KB
[ 5221.340000] kmem_cache                31KB         35KB
[ 5221.350000] Tasks state (memory values in pages):
[ 5221.350000] [  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
[ 5221.360000] [    617]     0   617      458       30     8192        0             0 bootlogd
[ 5221.370000] [    653]     0   653      776       11     8192        0             0 syslogd
[ 5221.380000] [    656]     0   656      776       12     6144        0             0 klogd
[ 5221.380000] [    676]     0   676     1578      299    10240        0             0 conf-manager
[ 5221.390000] [    679]     0   679      484       27     6144        0             0 conf-dispatcher
[ 5221.400000] [    688]     0   688      432       17     8192        0             0 keypad
[ 5221.410000] [    700]     0   700      904       79     8192        0         -1000 udevd
[ 5221.420000] [    717]    81   717     1074       49     8192        0             0 dbus-daemon
[ 5221.430000] [    747]     0   747      776       11     8192        0             0 respawn.sh
[ 5221.440000] [    749]     0   749     1493       69    10240        0             0 connmand
[ 5221.440000] [    751]    99   751      581       27     6144        0             0 dnsmasq
[ 5221.450000] [    755]     0   755      572       21     6144        0             0 dropbear
[ 5221.460000] [    759]     0   759     1083       75    10240        0             0 lighttpd
[ 5221.470000] [    761]     0   761     4393      291    20480        0             0 php-cgi
[ 5221.480000] [    763]     0   763     4393      291    22528        0             0 php-cgi
[ 5221.490000] [    768]     0   768      777       39     6144        0             0 lns_networking.
[ 5221.500000] [    839]     0   839      455       23     6144        0             0 inotifywait
[ 5221.500000] [    897]     0   897      776        9     6144        0             0 ntpd
[ 5221.510000] [    905]     0   905     1404       22     8192        0             0 crond
[ 5221.520000] [    922]     0   922      484       21     8192        0             0 event-monitor
[ 5221.530000] [    941]     0   941     1011       29     8192        0             0 sh
[ 5221.540000] [   1062]     0  1062      383       11     6144        0             0 test_open
[ 5221.550000] [   1063]     0  1063      592       31     8192        0             0 dropbear
[ 5221.550000] [   1064]     0  1064     1011       30     8192        0             0 sh
[ 5221.560000] [   5315]     0  5315      776       15     6144        0             0 check_online.sh
[ 5221.570000] [   5316]     0  5316      776       15     4096        0             0 check_online.sh
[ 5221.580000] [   5317]     0  5317     1159       53    10240        0             0 socat
[ 5221.590000] [   5318]     0  5318     1016       37    10240        0             0 xsltproc
[ 5221.600000] [   5319]     0  5319      777        9     8192        0             0 uniq
[ 5221.610000] Out of memory: Kill process 676 (conf-manager) score 9 or sacrifice child
[ 5221.610000] Killed process 676 (conf-manager) total-vm:6312kB, anon-rss:1196kB, file-rss:0kB, shmem-rss:0kB


full stabinfo:
slabinfo - version: 2.1 (statistics)
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow> : cpustat <allochit> <allocmiss> <freehit> <freemiss>
ubi_wl_entry_slab   1964   1992     48   83    1 : tunables   32   16    0 : slabdata     24     24      0 : globalstat    1973   1973    24    0    0    0    0    0    0 : cpustat   1822    142      0      0
ubifs_inode_slab      66    189    432    9    1 : tunables   32   16    0 : slabdata     21     21      0 : globalstat   92965    477    53    0    0    0    0    0    0 : cpustat 354826   5836 355569   5041
bridge_fdb_cache       2     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      48     17     1    0    0    0    0    0    0 : cpustat      1      3      2      0
nf-frags               0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm6_tunnel_spi       0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ip6-frags              0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fib6_nodes             6     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     17     1    0    0    0    0    0    0 : cpustat      4      2      0      0
ip6_dst_cache          3     25    160   25    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat     640     19     1    0    0    0    0    0    0 : cpustat     32     40     69      0
PINGv6                 0      0    832    9    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
RAWv6                  5      9    832    9    2 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      13      9     1    0    0    0    0    0    0 : cpustat      4      2      1      0
UDPLITEv6              0      0    832    9    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
UDPv6                  1      9    832    9    2 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      17      9     1    0    0    0    0    0    0 : cpustat      4      2      5      0
tw_sock_TCPv6          0      0    200   20    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_sock_TCPv6      0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
TCPv6                  1      4   1760    4    2 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       4      4     1    0    0    0    0    0    0 : cpustat      1      1      1      0
nf_conntrack_expect      0      0    152   26    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nf_conntrack           0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
sd_ext_cdb             2     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-128             2      2   2048    2    1 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       2      2     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-64              2      4   1024    4    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       4      4     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-32              2      8    512    8    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       8      8     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-16              2     16    256   16    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
sgpool-8               2     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      1      1      0      0
nfs_direct_cache       0      0    208   19    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_commit_data        4      9    448    9    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat       9      9     1    0    0    0    0    0    0 : cpustat      3      1      0      0
nfs_write_data        32     35    576    7    1 : tunables   32   16    0 : slabdata      5      5      0 : globalstat      35     35     5    0    0    0    0    0    0 : cpustat     27      5      0      0
nfs_read_data          0      0    576    7    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_inode_cache        0      0    608    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
nfs_page               0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fat_inode_cache        0      0    424    9    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fat_cache              0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_transaction_s      0      0    160   25    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_inode             0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_journal_handle      0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_journal_head      0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_revoke_table_s      0      0     40   99    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
jbd2_revoke_record_s      0      0     32  124    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_inode_cache       0      0    624    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_free_data         0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_allocation_context      0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_prealloc_space      0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_system_zone       0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_io_end            0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_pending_reservation      0      0     40   99    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ext4_extent_status      0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
mbcache                0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kioctx                 0      0    224   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
aio_kiocb              0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fanotify_event_info      0      0     56   71    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
fsnotify_mark          0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dnotify_mark           0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dnotify_struct         0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
dio                    0      0    360   11    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
bio-1                  4     25    160   25    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      3      1      0      0
fasync_cache           0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
posix_timers_cache      0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
rpc_inode_cache        0      0    352   11    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
rpc_buffers            8      8   2048    2    1 : tunables   24   12    0 : slabdata      4      4      0 : globalstat       8      8     4    0    0    0    0    0    0 : cpustat      4      4      0      0
rpc_tasks              8     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      7      1      0      0
UNIX                   7     28    576    7    1 : tunables   32   16    0 : slabdata      4      4      0 : globalstat   65532     35    88   84    0    0    0    0    0 : cpustat  20071   4224  24288      0
ip4-frags              0      0    160   25    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
UDP-Lite               0      0    704   11    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
tcp_bind_bucket        1     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      4      1      4      0
inet_peer_cache        0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
secpath_cache          0      0     64   63    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm_dst_cache         0      0    224   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
xfrm_state             0      0    576    7    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
ip_fib_trie           12     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     19     1    0    0    0    0    0    0 : cpustat     11      2      1      0
ip_fib_alias          15     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     20     1    0    0    0    0    0    0 : cpustat     14      2      1      0
ip_dst_cache          10     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1824     24     1    0    0    0    0    0    0 : cpustat    116    114    222      0
PING                   0      0    672    6    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
RAW                    2      6    672    6    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      10      6     1    0    0    0    0    0    0 : cpustat     12      2     12      0
UDP                    0      0    704   11    2 : tunables   32   16    0 : slabdata      0      0      0 : globalstat     994     11     2    2    0    0    0    0    0 : cpustat    580    123    703      0
tw_sock_TCP            0      0    200   20    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_sock_TCP       0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      0      1      1      0
TCP                    1      4   1664    4    2 : tunables   24   12    0 : slabdata      1      1      0 : globalstat       5      4     1    0    0    0    0    0    0 : cpustat     11      2     12      0
eventpoll_pwq          5     63     64   63    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1392     48     1    0    0    0    0    0    0 : cpustat     61     87    142      1
eventpoll_epi          5     42     96   42    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1386     42     1    0    0    0    0    0    0 : cpustat     61     87    143      0
inotify_inode_mark     15     56     72   56    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      48     39     1    0    0    0    0    0    0 : cpustat     21      3      9      0
scsi_data_buffer       0      0     48   83    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
request_queue         12     15   1536    5    2 : tunables   24   12    0 : slabdata      3      3      0 : globalstat      15     15     3    0    0    0    0    0    0 : cpustat      9      3      0      0
blkdev_requests        0      0    216   18    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
blkdev_ioc             1     51     80   51    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
bio-0                 26     50    160   25    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      41     41     2    0    0    0    0    0    0 : cpustat     27      3      4      0
biovec-max            30     30   3072    2    2 : tunables   24   12    0 : slabdata     15     15      0 : globalstat      30     30    15    0    0    0    0    0    0 : cpustat     15     15      0      0
biovec-128             0      0   1536    5    2 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
biovec-64              0      0    768    5    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
biovec-16              0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
uid_cache              0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      1      1      2      0
dmaengine-unmap-2      1    124     32  124    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
sock_inode_cache      26     66    352   11    1 : tunables   32   16    0 : slabdata      6      6      0 : globalstat   55763     77     7    0    0    0    0    0    0 : cpustat   7743   3489  11206      0
skbuff_fclone_cache      0      0    384   10    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat    5630     10   552  552    0    0    0    0    0 : cpustat    122    563    685      0
skbuff_head_cache     12     42    192   21    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   56541    121     6    1    0    0    0    0    0 : cpustat  24027   3924  27932      9
configfs_dir_cache      1     51     80   51    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
file_lock_cache        0      0    144   28    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat    1696     18   103  103    0    0    0    0    0 : cpustat   1338    106   1444      0
file_lock_ctx          1     83     48   83    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
fsnotify_mark_connector     15     99     40   99    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      32     32     1    0    0    0    0    0    0 : cpustat     20      2      7      0
shmem_inode_cache    545    560    384   10    1 : tunables   32   16    0 : slabdata     56     56      0 : globalstat     573    560    56    0    0    0    0    0    0 : cpustat    533     58     46      0
proc_dir_entry       203    208    152   26    1 : tunables   32   16    0 : slabdata      8      8      0 : globalstat     232    208     8    0    0    0    0    0    0 : cpustat 1655734     19 1655550      0
pde_opener            16     83     48   83    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    3392     16   208  207    0    0    0    0    0 : cpustat    379    212    590      0
proc_inode_cache      19     20    384   10    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   65673    330    58   24    0    2    0    0    0 : cpustat  17629   9256  26850     29
seq_file              16     39    104   39    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    3440     19     4    3    0    0    0    0    0 : cpustat   1822    215   2036      0
sigqueue               0      0     72   56    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat     496     25    28   28    0    0    0    0    0 : cpustat     22     31     53      0
bdev_cache            13     18    448    9    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      26     18     2    0    0    0    0    0    0 : cpustat     14      3      4      0
kernfs_node_cache   6152   6156    112   36    1 : tunables   32   16    0 : slabdata    171    171      0 : globalstat    6164   6152   171    0    0    0    0    0    0 : cpustat   6046    512    406      0
mnt_cache             23     36    224   18    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat      34     34     2    0    0    0    0    0    0 : cpustat     20      3      0      0
filp                  94    325    160   25    1 : tunables   32   16    0 : slabdata     13     13      0 : globalstat   56563    366    16    1    0    1    0    0    0 : cpustat 2140672   3542 2141060   3073
inode_cache         7258   7260    344   11    1 : tunables   32   16    0 : slabdata    660    660      0 : globalstat    9668   8316   828   77    0    0    0    0    0 : cpustat   9994    928   3600     64
dentry              7885   8800    160   25    1 : tunables   32   16    0 : slabdata    352    352      0 : globalstat  209061   9941   398    0    0    1    0    0    0 : cpustat 579132  13240 572829  11669
names_cache            1      1   4096    1    1 : tunables   24   12    0 : slabdata      1      1      0 : globalstat    1216     11   965  964    0    0    0    0    0 : cpustat 2313916   1211 2315127      0
key_jar                3     32    128   32    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      2      1      0      0
buffer_head            0      0     88   46    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat      16     16     1    1    0    0    0    0    0 : cpustat      3      1      4      0
nsproxy                1     71     56   71    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
vm_area_struct       196    646    120   34    1 : tunables   32   16    0 : slabdata     19     19      0 : globalstat  493665   1326    41    1    0    1    0    0    0 : cpustat 1030662  30889 1031088  30293
mm_struct             25     36    416    9    1 : tunables   32   16    0 : slabdata      4      4      0 : globalstat   19979     45     5    1    0    0    0    0    0 : cpustat  44416   1297  45703      0
fs_cache              18    124     32  124    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat    1904    112     1    0    0    0    0    0    0 : cpustat  23929    119  24029      9
files_cache           18     63    192   21    1 : tunables   32   16    0 : slabdata      3      3      0 : globalstat    1913    105     5    0    0    0    0    0    0 : cpustat  23925    123  24028     10
signal_cache          45     72    608    6    1 : tunables   32   16    0 : slabdata     12     12      0 : globalstat   15230    120    20    1    0    0    0    0    0 : cpustat  23152    965  24070     10
sighand_cache         43     57   1312    3    1 : tunables   24   12    0 : slabdata     19     19      0 : globalstat    1401    117    48    8    0    6    0    0    0 : cpustat  23947    170  24066     14
task_struct           43     84   1056    7    2 : tunables   24   12    0 : slabdata     12     12      0 : globalstat   11531    119    18    0    0    1    0    0    0 : cpustat  23150    969  24064     18
cred_jar              70    160    128   32    1 : tunables   32   16    0 : slabdata      5      5      0 : globalstat   20529    144     5    0    0    0    0    0    0 : cpustat  56391   1284  57604     15
anon_vma_chain       161    781     56   71    1 : tunables   32   16    0 : slabdata     11     11      0 : globalstat  139671   1381    21    1    0    1    0    0    0 : cpustat 472282   8741 473000   7891
anon_vma             125    567     64   63    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat   68139    741    12    0    0    0    0    0    0 : cpustat 329676   4260 330198   3626
pid                   50    126     64   63    1 : tunables   32   16    0 : slabdata      2      2      0 : globalstat   15054    126     2    0    0    0    0    0    0 : cpustat  23178    941  24066     11
debug_objects_cache   1024   1079     48   83    1 : tunables   32   16    0 : slabdata     13     13      0 : globalstat    1028   1028    13    0    0    0    0    0    0 : cpustat    950     74      0      0
trace_event_file    1219   1232     72   56    1 : tunables   32   16    0 : slabdata     22     22      0 : globalstat    1219   1219    22    0    0    0    0    0    0 : cpustat      0   1219      0      0
ftrace_event_field   2953   2982     56   71    1 : tunables   32   16    0 : slabdata     42     42      0 : globalstat    2959   2959    42    0    0    0    0    0    0 : cpustat   2745    208      0      0
pool_workqueue         4     16    256   16    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      2      2      0      0
radix_tree_node      193    300    328   12    1 : tunables   32   16    0 : slabdata     25     25      0 : globalstat   60882    396    33    0    0    0    0    0    0 : cpustat 234553   3841 234990   3211
kmalloc-rcl-4M         0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-2M         0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-1M         0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-512k       0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-256k       0      0 262144    1   64 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-128k       0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-64k        0      0  65536    1   16 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-32k        0      0  32768    1    8 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-16k        0      0  16384    1    4 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-8k         0      0   8192    1    2 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-4k         0      0   4096    1    1 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-2k         0      0   2048    2    1 : tunables   24   12    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-1k         0      0   1024    4    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-512        0      0    512    8    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-256        0      0    256   16    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-192        0      0    192   21    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-128        0      0    128   32    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-96         0      0     96   42    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-rcl-64         1     64     64   64    1 : tunables   32   16    0 : slabdata      1      1      0 : globalstat      16     16     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-rcl-32         0      0     32  124    1 : tunables   32   16    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-4M             0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-2M             0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-1M             0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-512k           0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-256k           1      1 262144    1   64 : tunables    1    1    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-128k           0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 : globalstat       0      0     0    0    0    0    0    0    0 : cpustat      0      0      0      0
kmalloc-64k            1      1  65536    1   16 : tunables    8    4    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-32k            1      1  32768    1    8 : tunables    8    4    0 : slabdata      1      1      0 : globalstat       1      1     1    0    0    0    0    0    0 : cpustat      0      1      0      0
kmalloc-16k            2      2  16384    1    4 : tunables    8    4    0 : slabdata      2      2      0 : globalstat     222      4   212  210    0    0    0    0    0 : cpustat   7107    220   7325      0
kmalloc-8k             9      9   8192    1    2 : tunables    8    4    0 : slabdata      9      9      0 : globalstat     503     20   155  146    0    4    0    0    0 : cpustat 22043876    253 22044039     82
kmalloc-4k            27     27   4096    1    1 : tunables   24   12    0 : slabdata     27     27      0 : globalstat     504    135   399  255    0   25    0    0    0 : cpustat   3415    419   3789     18
kmalloc-2k            54     54   2048    2    1 : tunables   24   12    0 : slabdata     27     27      0 : globalstat    2022     68    36    9    0    0    0    0    0 : cpustat    858    667   1474      0
kmalloc-1k           151    172   1024    4    1 : tunables   32   16    0 : slabdata     43     43      0 : globalstat    1056    196    54   11    0    3    0    0    0 : cpustat    453    153    453      2
kmalloc-512          302    320    512    8    1 : tunables   32   16    0 : slabdata     40     40      0 : globalstat    7933    400    51    3    0    2    0    0    0 : cpustat 2220216    547 2220469      8
kmalloc-256          293    304    256   16    1 : tunables   32   16    0 : slabdata     19     19      0 : globalstat 12361098   1616 53263  284    0    2    0    0    0 : cpustat 19771823 772713 19771803 772442
kmalloc-192          410    420    192   21    1 : tunables   32   16    0 : slabdata     20     20      0 : globalstat    3763    417    20    0    0    0    0    0    0 : cpustat 20526116    416 20526138      0
kmalloc-128          288    288    128   32    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat   11689    288    13    4    0    0    0    0    0 : cpustat  21015   1676  22409      0
kmalloc-96           666    966     96   42    1 : tunables   32   16    0 : slabdata     23     23      0 : globalstat  138190   1241    30    0    0    0    0    0    0 : cpustat 264861   8696 269873   3026
kmalloc-32        3317614 3317620     32  124    1 : tunables   32   16    0 : slabdata  26755  26755      0 : globalstat 3329656 3317661 26779   17    0    1    0    0    0 : cpustat 11621275 215178 8518750    104
kmalloc-64          3094   3136     64   64    1 : tunables   32   16    0 : slabdata     49     49      0 : globalstat 1643930   3440 20618    0    0    1    0    0    0 : cpustat 46206626 102866 46203878 102535
kmem_cache           169    189    192   21    1 : tunables   32   16    0 : slabdata      9      9      0 : globalstat     184    184     9    0    0    0    0    0    0 : cpustat    114     57      2      0

# cat /proc/meminfo
MemTotal:         122316 kB
MemFree:            1804 kB
MemAvailable:       2468 kB
Buffers:               0 kB
Cached:              716 kB
SwapCached:            0 kB
Active:             1148 kB
Inactive:            404 kB
Active(anon):        932 kB
Inactive(anon):      188 kB
Active(file):        216 kB
Inactive(file):      216 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           884 kB
Mapped:              472 kB
Shmem:               236 kB
KReclaimable:       4284 kB
Slab:             115048 kB
SReclaimable:       4284 kB
SUnreclaim:       110764 kB
KernelStack:         296 kB
PageTables:          136 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       61156 kB
Committed_AS:       5640 kB
VmallocTotal:     901120 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
Percpu:               64 kB

# cat /proc/slab_allocators ubi_wl_entry_slab: 3 erase_aeb+0x34/0xe0
ubi_wl_entry_slab: 805 ubi_wl_init+0x148/0x4e4
ubi_wl_entry_slab: 1155 ubi_wl_init+0x218/0x4e4
ubi_wl_entry_slab: 1 ubi_scan_fastmap+0x6f8/0x8fc
ubifs_inode_slab: 50 ubifs_alloc_inode+0x24/0x60
sd_ext_cdb: 2 mempool_alloc_slab+0x24/0x28
ip_fib_trie: 12 fib_insert_alias+0x40/0x298
ip_fib_alias: 15 fib_table_insert+0x33c/0x49c
eventpoll_pwq: 5 ep_ptable_queue_proc+0x38/0xb4
inotify_inode_mark: 15 sys_inotify_add_watch+0x12c/0x2bc
request_queue: 12 blk_alloc_queue_node+0x34/0x280
blkdev_ioc: 1 create_task_io_context+0x28/0xe0
configfs_dir_cache: 1 configfs_new_dirent+0x30/0xb4
file_lock_ctx: 1 locks_get_lock_context+0x48/0x10c
fsnotify_mark_connector: 15 fsnotify_add_mark_locked+0xbc/0x2b0
shmem_inode_cache: 545 shmem_alloc_inode+0x24/0x38
proc_dir_entry: 202 __proc_create+0x160/0x22c
proc_dir_entry: 1 proc_net_ns_init+0x28/0xd0
pde_opener: 1 proc_reg_open+0x7c/0x140
proc_inode_cache: 6 proc_alloc_inode+0x24/0x5c
seq_file: 1 seq_open+0x44/0xa4
kernfs_node_cache: 6152 __kernfs_new_node+0x48/0x174
inode_cache: 7258 alloc_inode+0x40/0xa8
dentry: 7872 __d_alloc+0x2c/0x1b4
nsproxy: 1 create_new_namespaces+0x34/0x144
vm_area_struct: 70 vm_area_alloc+0x28/0x68
vm_area_struct: 100 vm_area_dup+0x28/0x58
anon_vma_chain: 41 __anon_vma_prepare+0x28/0x124
anon_vma_chain: 51 anon_vma_clone+0x3c/0x168
anon_vma_chain: 40 anon_vma_fork+0x88/0x144
anon_vma: 72 __anon_vma_prepare+0x50/0x124
anon_vma: 40 anon_vma_fork+0x60/0x144
debug_objects_cache: 1024 debug_objects_mem_init+0x8c/0x248
trace_event_file: 1219 trace_create_new_event+0x24/0x6c
ftrace_event_field: 2953 __trace_define_field+0x30/0x98
radix_tree_node: 11 __radix_tree_preload.constprop.4+0x28/0x80
radix_tree_node: 125 radix_tree_node_alloc.constprop.5+0x54/0xd8
radix_tree_node: 11 radix_tree_node_alloc.constprop.5+0x8c/0xd8
radix_tree_node: 45 xas_alloc+0x40/0xb0

^ permalink raw reply

* Re: DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak
From: Alexandre Belloni @ 2018-11-27  9:58 UTC (permalink / raw)
  To: richard.genoud
  Cc: Ludovic Desroches, Nicolas Ferre, Maxime Ripard, Vinod Koul,
	linux-arm-kernel@lists.infradead.org, dmaengine, Linux Kernel,
	linux-serial@vger.kernel.org, Mario Forner
In-Reply-To: <83753d21-f3c8-c8dd-75d7-741cb597d1a3@sorico.fr>

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.

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: DMA: atmel_serial: Opening and closing the serial device repeatedly causes kmalloc-32 slab leak
From: Richard Genoud @ 2018-11-27 10:46 UTC (permalink / raw)
  To: Alexandre Belloni, richard.genoud
  Cc: Ludovic Desroches, Nicolas Ferre, Maxime Ripard,
	linux-arm-kernel@lists.infradead.org, dmaengine, Linux Kernel,
	linux-serial@vger.kernel.org, Mario Forner, Vinod Koul
In-Reply-To: <20181127095843.GF19871@piout.net>

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 !

^ permalink raw reply

* [PATCH] dmaengine: at_hdmac: fix memory leak in at_dma_xlate()
From: Richard Genoud @ 2018-11-27 16:06 UTC (permalink / raw)
  To: Ludovic Desroches, Dan Williams, Vinod Koul
  Cc: Alexandre Belloni, Nicolas Ferre, Maxime Ripard, Mario Forner,
	linux-arm-kernel, dmaengine, linux-kernel, linux-serial,
	Richard Genoud, stable

The leak was found when opening/closing a serial port a great number of
time, increasing kmalloc-32 in slabinfo.

Each time the port was opened, dma_request_slave_channel() was called.
Then, in at_dma_xlate(), atslave was allocated with devm_kzalloc() and
never freed. (Well, it was free at module unload, but that's not what we
want).
So, here, kzalloc is more suited for the job since it has to be freed in
atc_free_chan_resources().

Cc: stable@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Reported-by: Mario Forner <m.forner@be4energy.com>
Suggested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/dma/at_hdmac.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 7cbac6e8c113..1b7f0ca0d5cd 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1641,6 +1641,12 @@ static void atc_free_chan_resources(struct dma_chan *chan)
 	atchan->descs_allocated = 0;
 	atchan->status = 0;
 
+	/*
+	 * Free atslave allocated in at_dma_xlate()
+	 */
+	kfree(chan->private);
+	chan->private = NULL;
+
 	dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
 }
 
@@ -1675,7 +1681,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL);
+	atslave = kzalloc(sizeof(*atslave), GFP_KERNEL);
 	if (!atslave)
 		return NULL;
 

^ permalink raw reply related

* [PATCH] dmaengine: at_hdmac: fix module unloading
From: Richard Genoud @ 2018-11-27 16:06 UTC (permalink / raw)
  To: Ludovic Desroches, Dan Williams, Vinod Koul
  Cc: Alexandre Belloni, Nicolas Ferre, Maxime Ripard, Mario Forner,
	linux-arm-kernel, dmaengine, linux-kernel, linux-serial,
	Richard Genoud, stable
In-Reply-To: <20181127160635.11836-1-richard.genoud@gmail.com>

of_dma_controller_free() was not called on module onloading.
This lead to a soft lockup:
watchdog: BUG: soft lockup - CPU#0 stuck for 23s!
Modules linked in: at_hdmac [last unloaded: at_hdmac]
when of_dma_request_slave_channel() tried to call ofdma->of_dma_xlate().

Cc: stable@vger.kernel.org
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
 drivers/dma/at_hdmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 1b7f0ca0d5cd..01d936c9fe89 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -2006,6 +2006,8 @@ static int at_dma_remove(struct platform_device *pdev)
 	struct resource		*io;
 
 	at_dma_off(atdma);
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
 	dma_async_device_unregister(&atdma->dma_common);
 
 	dma_pool_destroy(atdma->memset_pool);

^ permalink raw reply related

* Re: [PATCH] tty: serial: qcom_geni_serial: Fix softlock
From: Stephen Boyd @ 2018-11-28  0:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Evan Green, Doug Anderson, linux-kernel, linux-serial, Ryan Case
In-Reply-To: <20181127022536.104663-1-ryandcase@chromium.org>

Quoting Ryan Case (2018-11-26 18:25:36)
> Transfers were being divided into device FIFO sized (64 byte max)
> operations which would poll for completion within a spin_lock_irqsave /
> spin_unlock_irqrestore block. This both made things slow by waiting for
> the FIFO to completely drain before adding further data and would also
> result in softlocks on large transmissions.
> 
> This patch allows larger transfers with continuous FIFO additions as
> space becomes available and removes polling from the interrupt handler.
> 
> Signed-off-by: Ryan Case <ryandcase@chromium.org>
> Version: 1

I've never seen a Version tag before. Did you manually add this?

> diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
> index 7ded51081add..835a184e0b7d 100644
> --- a/drivers/tty/serial/qcom_geni_serial.c
> +++ b/drivers/tty/serial/qcom_geni_serial.c
> @@ -117,6 +117,8 @@ struct qcom_geni_serial_port {
>         u32 *rx_fifo;
>         u32 loopback;
>         bool brk;
> +
> +       u32 cur_tx_remaining;

Nitpick: Can it just be tx_remaining? And why u32? Why not unsigned int?

>  };
>  
>  static const struct uart_ops qcom_geni_console_pops;
> @@ -439,6 +441,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
>         struct qcom_geni_serial_port *port;
>         bool locked = true;
>         unsigned long flags;
> +       unsigned int geni_status;

Nitpick: Use u32 for register reads.

>  
>         WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
>  
> @@ -465,9 +470,17 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
>                 }
>                 writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
>                                                         SE_GENI_M_IRQ_CLEAR);
> -       }
> +       } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining)
> +               /* It seems we can interrupt existing transfers unless all data

Nitpick: Have /* on a line by itself

Is this comment supposed to say "we can't interrupt existing transfers"?

> +                * has been sent, in which case we need to look for done first.
> +                */
> +               qcom_geni_serial_poll_tx_done(uport);

Another nitpick: Please put braces around multi-line if branches for
greater code clarity.

>  
>         __qcom_geni_serial_console_write(uport, s, count);
> +
> +       if (port->cur_tx_remaining)
> +               qcom_geni_serial_setup_tx(uport, port->cur_tx_remaining);

Does this happen? Is the console being used as a tty at the same time?

> +
>         if (locked)
>                 spin_unlock_irqrestore(&uport->lock, flags);
>  }
> @@ -701,40 +714,47 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
>         port->handle_rx(uport, total_bytes, drop);
>  }
>  
> -static void qcom_geni_serial_handle_tx(struct uart_port *uport)
> +static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
> +               bool active)
>  {
>         struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
>         struct circ_buf *xmit = &uport->state->xmit;
>         size_t avail;
>         size_t remaining;
> +       size_t pending;
>         int i;
>         u32 status;
>         unsigned int chunk;
>         int tail;
> -       u32 irq_en;
>  
> -       chunk = uart_circ_chars_pending(xmit);
>         status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
> -       /* Both FIFO and framework buffer are drained */
> -       if (!chunk && !status) {
> +
> +       /* Complete the current tx command before taking newly added data */
> +       if (active)
> +               pending = port->cur_tx_remaining;
> +       else
> +               pending = uart_circ_chars_pending(xmit);
> +
> +       /* All data has been transmitted and acknowledged as received */
> +       if (!pending && !status && done) {

Nitpick: status is a poor variable name to test here. I don't understand
what this line is doing. Maybe it would help to have another local
variable like 'needs_attention'?

>                 qcom_geni_serial_stop_tx(uport);
>                 goto out_write_wakeup;
>         }
>  
> -       if (!uart_console(uport)) {
> -               irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
> -               irq_en &= ~(M_TX_FIFO_WATERMARK_EN);
> -               writel_relaxed(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
> -               writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
> -       }
> +       avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
> +       avail *= port->tx_bytes_pw;
> +       if (avail < 0)
> +               avail = 0;

How can 'avail' be less than 0? It's size_t which is unsigned? If
underflow is happening from that subtraction or overflow from the
multiply that could be bad but I hope that is impossible.

>  
> -       avail = (port->tx_fifo_depth - port->tx_wm) * port->tx_bytes_pw;
>         tail = xmit->tail;
> -       chunk = min3((size_t)chunk, (size_t)(UART_XMIT_SIZE - tail), avail);
> +       chunk = min3((size_t)pending, (size_t)(UART_XMIT_SIZE - tail), avail);

Nitpick: If we made 'avail' unsigned int would we be able to drop the
casts on this min3() call? This line is quite hard to read.

>         if (!chunk)
>                 goto out_write_wakeup;
>  
> -       qcom_geni_serial_setup_tx(uport, chunk);
> +       if (!port->cur_tx_remaining) {
> +               qcom_geni_serial_setup_tx(uport, pending);
> +               port->cur_tx_remaining = pending;
> +       }
>  
>         remaining = chunk;
>         for (i = 0; i < chunk; ) {
> @@ -767,6 +786,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
>  {
>         unsigned int m_irq_status;
>         unsigned int s_irq_status;
> +       unsigned int geni_status;

Nitpick: I guess this driver isn't using u32 for registers already.
Would be nice to mop this up in another patch.

>         struct uart_port *uport = dev;
>         unsigned long flags;
>         unsigned int m_irq_en;
> 

^ permalink raw reply

* Re: [PATCH] tty: serial: qcom_geni_serial: Fix softlock
From: Ryan Case @ 2018-11-28  1:24 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Greg Kroah-Hartman, Jiri Slaby, Evan Green, Doug Anderson,
	linux-kernel, linux-serial
In-Reply-To: <154336440880.88331.11610393939844825622@swboyd.mtv.corp.google.com>

On Tue, Nov 27, 2018 at 4:20 PM Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Ryan Case (2018-11-26 18:25:36)
> > Transfers were being divided into device FIFO sized (64 byte max)
> > operations which would poll for completion within a spin_lock_irqsave /
> > spin_unlock_irqrestore block. This both made things slow by waiting for
> > the FIFO to completely drain before adding further data and would also
> > result in softlocks on large transmissions.
> >
> > This patch allows larger transfers with continuous FIFO additions as
> > space becomes available and removes polling from the interrupt handler.
> >
> > Signed-off-by: Ryan Case <ryandcase@chromium.org>
> > Version: 1
>
> I've never seen a Version tag before. Did you manually add this?

I submitted with patman, this should have been Series-version:

>
> > diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
> > index 7ded51081add..835a184e0b7d 100644
> > --- a/drivers/tty/serial/qcom_geni_serial.c
> > +++ b/drivers/tty/serial/qcom_geni_serial.c
> > @@ -117,6 +117,8 @@ struct qcom_geni_serial_port {
> >         u32 *rx_fifo;
> >         u32 loopback;
> >         bool brk;
> > +
> > +       u32 cur_tx_remaining;
>
> Nitpick: Can it just be tx_remaining? And why u32? Why not unsigned int?

Sure, and unsigned int is fine.

>
> >  };
> >
> >  static const struct uart_ops qcom_geni_console_pops;
> > @@ -439,6 +441,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
> >         struct qcom_geni_serial_port *port;
> >         bool locked = true;
> >         unsigned long flags;
> > +       unsigned int geni_status;
>
> Nitpick: Use u32 for register reads.

will do.

>
> >
> >         WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
> >
> > @@ -465,9 +470,17 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
> >                 }
> >                 writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
> >                                                         SE_GENI_M_IRQ_CLEAR);
> > -       }
> > +       } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining)
> > +               /* It seems we can interrupt existing transfers unless all data
>
> Nitpick: Have /* on a line by itself
>
> Is this comment supposed to say "we can't interrupt existing transfers"?

Nope, comment is correct as is.

>
> > +                * has been sent, in which case we need to look for done first.
> > +                */
> > +               qcom_geni_serial_poll_tx_done(uport);
>
> Another nitpick: Please put braces around multi-line if branches for
> greater code clarity.

will do.

>
> >
> >         __qcom_geni_serial_console_write(uport, s, count);
> > +
> > +       if (port->cur_tx_remaining)
> > +               qcom_geni_serial_setup_tx(uport, port->cur_tx_remaining);
>
> Does this happen? Is the console being used as a tty at the same time?

Yup, happens quite a bit.

>
> > +
> >         if (locked)
> >                 spin_unlock_irqrestore(&uport->lock, flags);
> >  }
> > @@ -701,40 +714,47 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
> >         port->handle_rx(uport, total_bytes, drop);
> >  }
> >
> > -static void qcom_geni_serial_handle_tx(struct uart_port *uport)
> > +static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
> > +               bool active)
> >  {
> >         struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
> >         struct circ_buf *xmit = &uport->state->xmit;
> >         size_t avail;
> >         size_t remaining;
> > +       size_t pending;
> >         int i;
> >         u32 status;
> >         unsigned int chunk;
> >         int tail;
> > -       u32 irq_en;
> >
> > -       chunk = uart_circ_chars_pending(xmit);
> >         status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
> > -       /* Both FIFO and framework buffer are drained */
> > -       if (!chunk && !status) {
> > +
> > +       /* Complete the current tx command before taking newly added data */
> > +       if (active)
> > +               pending = port->cur_tx_remaining;
> > +       else
> > +               pending = uart_circ_chars_pending(xmit);
> > +
> > +       /* All data has been transmitted and acknowledged as received */
> > +       if (!pending && !status && done) {
>
> Nitpick: status is a poor variable name to test here. I don't understand
> what this line is doing. Maybe it would help to have another local
> variable like 'needs_attention'?

It could be renamed but since this isn't a general file cleanup patch
I was avoiding non-functional changes. It is the TX_FIFO_STATUS
register, if non-zero there is still data in the FIFO or related
activity ongoing.

>
> >                 qcom_geni_serial_stop_tx(uport);
> >                 goto out_write_wakeup;
> >         }
> >
> > -       if (!uart_console(uport)) {
> > -               irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
> > -               irq_en &= ~(M_TX_FIFO_WATERMARK_EN);
> > -               writel_relaxed(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
> > -               writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
> > -       }
> > +       avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
> > +       avail *= port->tx_bytes_pw;
> > +       if (avail < 0)
> > +               avail = 0;
>
> How can 'avail' be less than 0? It's size_t which is unsigned? If
> underflow is happening from that subtraction or overflow from the
> multiply that could be bad but I hope that is impossible.

I hope underflow is impossible as well. However, if the hardware did
wind up in a strange state I wanted to err on the side of not throwing
away data and being able to resume later if things recovered. I can
remove the defensive checks if that's the custom, otherwise I'll
update the comparison logic accordingly.

>
> >
> > -       avail = (port->tx_fifo_depth - port->tx_wm) * port->tx_bytes_pw;
> >         tail = xmit->tail;
> > -       chunk = min3((size_t)chunk, (size_t)(UART_XMIT_SIZE - tail), avail);
> > +       chunk = min3((size_t)pending, (size_t)(UART_XMIT_SIZE - tail), avail);
>
> Nitpick: If we made 'avail' unsigned int would we be able to drop the
> casts on this min3() call? This line is quite hard to read.

Seems they can go away without any changes.

>
> >         if (!chunk)
> >                 goto out_write_wakeup;
> >
> > -       qcom_geni_serial_setup_tx(uport, chunk);
> > +       if (!port->cur_tx_remaining) {
> > +               qcom_geni_serial_setup_tx(uport, pending);
> > +               port->cur_tx_remaining = pending;
> > +       }
> >
> >         remaining = chunk;
> >         for (i = 0; i < chunk; ) {
> > @@ -767,6 +786,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
> >  {
> >         unsigned int m_irq_status;
> >         unsigned int s_irq_status;
> > +       unsigned int geni_status;
>
> Nitpick: I guess this driver isn't using u32 for registers already.
> Would be nice to mop this up in another patch.
>
> >         struct uart_port *uport = dev;
> >         unsigned long flags;
> >         unsigned int m_irq_en;
> >

^ permalink raw reply

* Re: [PATCH 02/14] dt-bindings: soc: milbeaut: Add Milbeaut trampoline description
From: Stephen Boyd @ 2018-11-28  2:01 UTC (permalink / raw)
  To: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-serial
  Cc: Michael Turquette, Rob Herring, Mark Rutland, Greg Kroah-Hartman,
	Daniel Lezcano, Thomas Gleixner, Russell King, Jiri Slaby,
	Masami Hiramatsu, Jassi Brar, Sugaya Taichi
In-Reply-To: <1542589274-13878-3-git-send-email-sugaya.taichi@socionext.com>

Quoting Sugaya Taichi (2018-11-18 17:01:07)
> Add DT bindings document for Milbeaut trampoline.
> 
> Signed-off-by: Sugaya Taichi <sugaya.taichi@socionext.com>
> ---
>  .../devicetree/bindings/soc/socionext/socionext,m10v.txt     | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt
> 
> diff --git a/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt b/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt
> new file mode 100644
> index 0000000..f5d906c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt
> @@ -0,0 +1,12 @@
> +Socionext M10V SMP trampoline driver binding
> +
> +This is a driver to wait for sub-cores while boot process.
> +
> +- compatible: should be "socionext,smp-trampoline"
> +- reg: should be <0x4C000100 0x100>
> +
> +EXAMPLE
> +       trampoline: trampoline@0x4C000100 {

Drop the 0x part of unit addresses.

> +               compatible = "socionext,smp-trampoline";
> +               reg = <0x4C000100 0x100>;

Looks like a software construct, which we wouldn't want to put into DT
this way. DT doesn't describe drivers.

^ permalink raw reply

* Re: [PATCH] tty: serial: qcom_geni_serial: Fix softlock
From: Stephen Boyd @ 2018-11-28  2:04 UTC (permalink / raw)
  To: Ryan Case
  Cc: Greg Kroah-Hartman, Jiri Slaby, Evan Green, Doug Anderson,
	linux-kernel, linux-serial
In-Reply-To: <CACjz--n6eXtT6-CDhVEStSD_59yJ-fdmfHzo9SH_da5ZzL_mDw@mail.gmail.com>

Quoting Ryan Case (2018-11-27 17:24:44)
> On Tue, Nov 27, 2018 at 4:20 PM Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > Quoting Ryan Case (2018-11-26 18:25:36)
> > > Transfers were being divided into device FIFO sized (64 byte max)
> > > operations which would poll for completion within a spin_lock_irqsave /
> > > spin_unlock_irqrestore block. This both made things slow by waiting for
> > > the FIFO to completely drain before adding further data and would also
> > > result in softlocks on large transmissions.
> > >
> > > This patch allows larger transfers with continuous FIFO additions as
> > > space becomes available and removes polling from the interrupt handler.
> > >
> > > Signed-off-by: Ryan Case <ryandcase@chromium.org>
> > > Version: 1
> >
> > I've never seen a Version tag before. Did you manually add this?
> 
> I submitted with patman, this should have been Series-version:

Hmm ok. I'm not aware of this being a kernel idiom so I would remove
this tag before sending.

> 
> >
> > >
> > >         WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
> > >
> > > @@ -465,9 +470,17 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
> > >                 }
> > >                 writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
> > >                                                         SE_GENI_M_IRQ_CLEAR);
> > > -       }
> > > +       } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining)
> > > +               /* It seems we can interrupt existing transfers unless all data
> >
> > Nitpick: Have /* on a line by itself
> >
> > Is this comment supposed to say "we can't interrupt existing transfers"?
> 
> Nope, comment is correct as is.

Ok. I fail at parsing it then. Perhaps

"It seems we can interrupt existing transfers except for when all data
has been sent"

would make it easier for me to read.

> 
> >
> > >
> > >         __qcom_geni_serial_console_write(uport, s, count);
> > > +
> > > +       if (port->cur_tx_remaining)
> > > +               qcom_geni_serial_setup_tx(uport, port->cur_tx_remaining);
> >
> > Does this happen? Is the console being used as a tty at the same time?
> 
> Yup, happens quite a bit.

So its being used in both modes at the same time?

> 
> >
> > > +
> > >         if (locked)
> > >                 spin_unlock_irqrestore(&uport->lock, flags);
> > >  }
> > > @@ -701,40 +714,47 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
> > >         port->handle_rx(uport, total_bytes, drop);
> > >  }
> > >
> > > -static void qcom_geni_serial_handle_tx(struct uart_port *uport)
> > > +static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
> > > +               bool active)
> > >  {
> > >         struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
> > >         struct circ_buf *xmit = &uport->state->xmit;
> > >         size_t avail;
> > >         size_t remaining;
> > > +       size_t pending;
> > >         int i;
> > >         u32 status;
> > >         unsigned int chunk;
> > >         int tail;
> > > -       u32 irq_en;
> > >
> > > -       chunk = uart_circ_chars_pending(xmit);
> > >         status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
> > > -       /* Both FIFO and framework buffer are drained */
> > > -       if (!chunk && !status) {
> > > +
> > > +       /* Complete the current tx command before taking newly added data */
> > > +       if (active)
> > > +               pending = port->cur_tx_remaining;
> > > +       else
> > > +               pending = uart_circ_chars_pending(xmit);
> > > +
> > > +       /* All data has been transmitted and acknowledged as received */
> > > +       if (!pending && !status && done) {
> >
> > Nitpick: status is a poor variable name to test here. I don't understand
> > what this line is doing. Maybe it would help to have another local
> > variable like 'needs_attention'?
> 
> It could be renamed but since this isn't a general file cleanup patch
> I was avoiding non-functional changes. It is the TX_FIFO_STATUS
> register, if non-zero there is still data in the FIFO or related
> activity ongoing.

Ok.

> 
> >
> > >                 qcom_geni_serial_stop_tx(uport);
> > >                 goto out_write_wakeup;
> > >         }
> > >
> > > -       if (!uart_console(uport)) {
> > > -               irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
> > > -               irq_en &= ~(M_TX_FIFO_WATERMARK_EN);
> > > -               writel_relaxed(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
> > > -               writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
> > > -       }
> > > +       avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
> > > +       avail *= port->tx_bytes_pw;
> > > +       if (avail < 0)
> > > +               avail = 0;
> >
> > How can 'avail' be less than 0? It's size_t which is unsigned? If
> > underflow is happening from that subtraction or overflow from the
> > multiply that could be bad but I hope that is impossible.
> 
> I hope underflow is impossible as well. However, if the hardware did
> wind up in a strange state I wanted to err on the side of not throwing
> away data and being able to resume later if things recovered. I can
> remove the defensive checks if that's the custom, otherwise I'll
> update the comparison logic accordingly.

Well it looks like impossible code because an unsigned value can't be
less than zero. So it's not about customs, more about dead code removal.

> 
> >
> > >
> > > -       avail = (port->tx_fifo_depth - port->tx_wm) * port->tx_bytes_pw;
> > >         tail = xmit->tail;
> > > -       chunk = min3((size_t)chunk, (size_t)(UART_XMIT_SIZE - tail), avail);
> > > +       chunk = min3((size_t)pending, (size_t)(UART_XMIT_SIZE - tail), avail);
> >
> > Nitpick: If we made 'avail' unsigned int would we be able to drop the
> > casts on this min3() call? This line is quite hard to read.
> 
> Seems they can go away without any changes.

Ok!

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox