]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
serial_core.c: add put_device() after device_find_child()
authorFederico Vaga <federico.vaga@gmail.com>
Mon, 15 Apr 2013 14:01:07 +0000 (16:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 May 2013 02:57:22 +0000 (19:57 -0700)
commit 5a65dcc04cda41f4122aacc37a5a348454645399 upstream.

The serial core uses device_find_child() but does not drop the reference to
the retrieved child after using it. This patch add the missing put_device().

What I have done to test this issue.

I used a machine with an AMBA PL011 serial driver. I tested the patch on
next-20120408 because the last branch [next-20120415] does not boot on this
board.

For test purpose, I added some pr_info() messages to print the refcount
after device_find_child() (lines: 1937,2009), and after put_device()
(lines: 1947, 2021).

Boot the machine *without* put_device(). Then:

echo reboot > /sys/power/disk
echo disk > /sys/power/state
[   87.058575] uart_suspend_port:1937 refcount 4
[   87.058582] uart_suspend_port:1947 refcount 4
[   87.098083] uart_resume_port:2009refcount 5
[   87.098088] uart_resume_port:2021 refcount 5

echo disk > /sys/power/state
[  103.055574] uart_suspend_port:1937 refcount 6
[  103.055580] uart_suspend_port:1947 refcount 6
[  103.095322] uart_resume_port:2009 refcount 7
[  103.095327] uart_resume_port:2021 refcount 7

echo disk > /sys/power/state
[  252.459580] uart_suspend_port:1937 refcount 8
[  252.459586] uart_suspend_port:1947 refcount 8
[  252.499611] uart_resume_port:2009 refcount 9
[  252.499616] uart_resume_port:2021 refcount 9

The refcount continuously increased.

Boot the machine *with* this patch. Then:

echo reboot > /sys/power/disk
echo disk > /sys/power/state
[  159.333559] uart_suspend_port:1937 refcount 4
[  159.333566] uart_suspend_port:1947 refcount 3
[  159.372751] uart_resume_port:2009 refcount 4
[  159.372755] uart_resume_port:2021 refcount 3

echo disk > /sys/power/state
[  185.713614] uart_suspend_port:1937 refcount 4
[  185.713621] uart_suspend_port:1947 refcount 3
[  185.752935] uart_resume_port:2009 refcount 4
[  185.752940] uart_resume_port:2021 refcount 3

echo disk > /sys/power/state
[  207.458584] uart_suspend_port:1937 refcount 4
[  207.458591] uart_suspend_port:1947 refcount 3
[  207.498598] uart_resume_port:2009 refcount 4
[  207.498605] uart_resume_port:2021 refcount 3

The refcount correctly handled.

Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/serial_core.c

index de5e33fc129021be7bb7ff2ed8bde4b0f4de5552..28630b61ad1bf471ae08bc22ebace47c9ddf5cab 100644 (file)
@@ -1917,6 +1917,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
                mutex_unlock(&port->mutex);
                return 0;
        }
+       put_device(tty_dev);
+
        if (console_suspend_enabled || !uart_console(uport))
                uport->suspended = 1;
 
@@ -1982,9 +1984,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
                        disable_irq_wake(uport->irq);
                        uport->irq_wake = 0;
                }
+               put_device(tty_dev);
                mutex_unlock(&port->mutex);
                return 0;
        }
+       put_device(tty_dev);
        uport->suspended = 0;
 
        /*