From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
To: Dmitry Safonov <dima@arista.com>
Cc: Jiri Slaby <jslaby@suse.cz>,
kernel test robot <rong.a.chen@intel.com>,
lkp@01.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mikulas Patocka <mpatocka@redhat.com>,
LKML <linux-kernel@vger.kernel.org>,
linux-serial@vger.kernel.org,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Petr Mladek <pmladek@suse.com>,
Steven Rostedt <rostedt@goodmis.org>,
Peter Zijlstra <peterz@infradead.org>,
Waiman Long <longman@redhat.com>
Subject: Re: [LKP] [tty] c96cf923a9: WARNING:possible_circular_locking_dependency_detected
Date: Wed, 12 Dec 2018 12:42:52 +0900 [thread overview]
Message-ID: <20181212034252.GD431@jagdpanzerIV> (raw)
In-Reply-To: <2780774e-b397-dcc2-6950-cccb527d5014@arista.com>
Hi,
Cc-ing Peter, Waiman
Hmm, so, how it looks to me
On (12/11/18 20:59), Dmitry Safonov wrote:
> >> [ 87.218483] -> #2 (&port_lock_key){-.-.}:
> >> [ 87.219282] lock_acquire+0x28c/0x2e7
> >> [ 87.219901] _raw_spin_lock_irqsave+0x35/0x49
> >> [ 87.220601] serial8250_console_write+0x110/0x5b5
> >> [ 87.221354] univ8250_console_write+0x5f/0x64
> >> [ 87.222056] console_unlock+0x61c/0x7cf
> >> [ 87.222680] register_console+0x63a/0x7b0
> >> [ 87.223345] univ8250_console_init+0x1e/0x28
> >> [ 87.224041] console_init+0x3be/0x57e
> >> [ 87.224641] start_kernel+0x441/0x6c6
> >> [ 87.225246] x86_64_start_reservations+0x29/0x2b
> >> [ 87.225979] x86_64_start_kernel+0x6f/0x72
> >> [ 87.226637] secondary_startup_64+0xa4/0xb0
console_sem -> uart_port->lock
> >> [ 87.227314] -> #1 (console_owner){-...}:
> >> [ 87.228127] lock_acquire+0x28c/0x2e7
> >> [ 87.228728] console_unlock+0x424/0x7cf
> >> [ 87.229363] vprintk_emit+0x22d/0x252
> >> [ 87.229969] vprintk_default+0x18/0x1a
> >> [ 87.230576] vprintk_func+0xa9/0xab
> >> [ 87.231156] printk+0x97/0xbe
> >> [ 87.231659] __debug_object_init+0x8db/0x92d
> >> [ 87.232349] debug_object_init+0x14/0x17
> >> [ 87.232987] __init_work+0x1b/0x1d
> >> [ 87.233551] rhashtable_init+0x53b/0x602
> >> [ 87.234192] rhltable_init+0xe/0x41
> >> [ 87.234772] test_insert_dup+0xac/0xa94
> >> [ 87.235467] test_rht_init+0x387/0x79c
> >> [ 87.236222] do_one_initcall+0x23c/0x4af
> >> [ 87.236869] kernel_init_freeable+0x5ec/0x69f
> >> [ 87.237855] kernel_init+0xc/0x100
> >> [ 87.238470] ret_from_fork+0x3a/0x50
db->lock -> console_sem -> uart_port->lock
obj_hash[i].lock
/* db->lock */
__debug_object_init()
debug_print_object()
printk()
spin_lock_irqsave(uart->port_lock)
BTW, there is a patch from Waiman which moves debug_print_object()
out of db->lock scope [1].
> >> [ 87.239071] -> #0 (&obj_hash[i].lock){-.-.}:
> >> [ 87.239904] __lock_acquire+0x1f78/0x22d1
> >> [ 87.240556] lock_acquire+0x28c/0x2e7
> >> [ 87.241173] _raw_spin_lock_irqsave+0x35/0x49
> >> [ 87.241882] debug_check_no_obj_freed+0xb4/0x302
> >> [ 87.242620] free_unref_page_prepare+0x33a/0x483
> >> [ 87.243368] free_unref_page+0x48/0x80
> >> [ 87.243991] __free_pages+0x2e/0x40
> >> [ 87.244611] free_pages+0x54/0x5a
> >> [ 87.245188] uart_shutdown+0x3df/0x4e2
> >> [ 87.245817] uart_hangup+0x123/0x280
> >> [ 87.246406] __tty_hangup+0x4da/0x50f
> >> [ 87.247025] tty_vhangup_session+0xe/0x10
> >> [ 87.247680] disassociate_ctty+0xeb/0x5c5
> >> [ 87.248349] do_exit+0xc97/0x1daf
> >> [ 87.248920] __x64_sys_exit_group+0x0/0x3e
> >> [ 87.249587] __wake_up_parent+0x0/0x52
> >> [ 87.250211] do_syscall_64+0x5e8/0x881
> >> [ 87.250839] entry_SYSCALL_64_after_hwframe+0x49/0xbe
But I think what really makes lockdep nervous is this thing:
uart_shutdown()
uart_port_lock() // spin_lock_irqsave(uart_port->lock)
free_page()
debug_check_no_obj_freed()
db->lock
debug_print_object()
printk()
spin_lock_irqsave(uart_port->lock)
Lockdep complains about: uart_port->lock -> db->lock
It knows that we already have the reverse chain: db->lock -> uart_port->lock
From
db->lock -> debug_print_object() -> printk() -> console_sem -> uart_port->lock
> >> [ 87.255156] CPU0 CPU1
> >> [ 87.255813] ---- ----
> >> [ 87.256460] lock(&port_lock_key);
> >> [ 87.256973] lock(console_owner);
> >> [ 87.257829] lock(&port_lock_key);
> >> [ 87.258680] lock(&obj_hash[i].lock);
So it's like
CPU0 CPU1
uart_shutdown() db->lock
uart_port->lock debug_print_object()
free_page() printk
debug_check_no_obj_freed uart_port->lock
db->lock
In this particular case we probably can just move free_page()
out of uart_port lock scope. Note that free_page()->MM can printk()
on its own.
Something like this (not tested):
---
drivers/tty/serial/serial_core.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index c439a5a1e6c0..64050f506348 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -268,6 +268,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
struct uart_port *uport = uart_port_check(state);
struct tty_port *port = &state->port;
unsigned long flags = 0;
+ char *xmit_buf = NULL;
/*
* Set the TTY IO error marker
@@ -297,15 +298,16 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
*/
tty_port_set_suspended(port, 0);
+ uart_port_lock(state, flags);
+ xmit_buf = state->xmit.buf;
+ state->xmit.buf = NULL;
+ uart_port_unlock(uport, flags);
+
/*
* Free the transmit buffer page.
*/
- uart_port_lock(state, flags);
- if (state->xmit.buf) {
- free_page((unsigned long)state->xmit.buf);
- state->xmit.buf = NULL;
- }
- uart_port_unlock(uport, flags);
+ if (xmit_buf)
+ free_page((unsigned long)xmit_buf);
}
/**
---
Can send a formal patch, if it works for you guys.
[1] https://lore.kernel.org/lkml/1542653726-5655-8-git-send-email-longman@redhat.com/T/#u
-ss
WARNING: multiple messages have this Message-ID (diff)
From: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
To: lkp@lists.01.org
Subject: Re: [tty] c96cf923a9: WARNING:possible_circular_locking_dependency_detected
Date: Wed, 12 Dec 2018 12:42:52 +0900 [thread overview]
Message-ID: <20181212034252.GD431@jagdpanzerIV> (raw)
In-Reply-To: <2780774e-b397-dcc2-6950-cccb527d5014@arista.com>
[-- Attachment #1: Type: text/plain, Size: 5836 bytes --]
Hi,
Cc-ing Peter, Waiman
Hmm, so, how it looks to me
On (12/11/18 20:59), Dmitry Safonov wrote:
> >> [ 87.218483] -> #2 (&port_lock_key){-.-.}:
> >> [ 87.219282] lock_acquire+0x28c/0x2e7
> >> [ 87.219901] _raw_spin_lock_irqsave+0x35/0x49
> >> [ 87.220601] serial8250_console_write+0x110/0x5b5
> >> [ 87.221354] univ8250_console_write+0x5f/0x64
> >> [ 87.222056] console_unlock+0x61c/0x7cf
> >> [ 87.222680] register_console+0x63a/0x7b0
> >> [ 87.223345] univ8250_console_init+0x1e/0x28
> >> [ 87.224041] console_init+0x3be/0x57e
> >> [ 87.224641] start_kernel+0x441/0x6c6
> >> [ 87.225246] x86_64_start_reservations+0x29/0x2b
> >> [ 87.225979] x86_64_start_kernel+0x6f/0x72
> >> [ 87.226637] secondary_startup_64+0xa4/0xb0
console_sem -> uart_port->lock
> >> [ 87.227314] -> #1 (console_owner){-...}:
> >> [ 87.228127] lock_acquire+0x28c/0x2e7
> >> [ 87.228728] console_unlock+0x424/0x7cf
> >> [ 87.229363] vprintk_emit+0x22d/0x252
> >> [ 87.229969] vprintk_default+0x18/0x1a
> >> [ 87.230576] vprintk_func+0xa9/0xab
> >> [ 87.231156] printk+0x97/0xbe
> >> [ 87.231659] __debug_object_init+0x8db/0x92d
> >> [ 87.232349] debug_object_init+0x14/0x17
> >> [ 87.232987] __init_work+0x1b/0x1d
> >> [ 87.233551] rhashtable_init+0x53b/0x602
> >> [ 87.234192] rhltable_init+0xe/0x41
> >> [ 87.234772] test_insert_dup+0xac/0xa94
> >> [ 87.235467] test_rht_init+0x387/0x79c
> >> [ 87.236222] do_one_initcall+0x23c/0x4af
> >> [ 87.236869] kernel_init_freeable+0x5ec/0x69f
> >> [ 87.237855] kernel_init+0xc/0x100
> >> [ 87.238470] ret_from_fork+0x3a/0x50
db->lock -> console_sem -> uart_port->lock
obj_hash[i].lock
/* db->lock */
__debug_object_init()
debug_print_object()
printk()
spin_lock_irqsave(uart->port_lock)
BTW, there is a patch from Waiman which moves debug_print_object()
out of db->lock scope [1].
> >> [ 87.239071] -> #0 (&obj_hash[i].lock){-.-.}:
> >> [ 87.239904] __lock_acquire+0x1f78/0x22d1
> >> [ 87.240556] lock_acquire+0x28c/0x2e7
> >> [ 87.241173] _raw_spin_lock_irqsave+0x35/0x49
> >> [ 87.241882] debug_check_no_obj_freed+0xb4/0x302
> >> [ 87.242620] free_unref_page_prepare+0x33a/0x483
> >> [ 87.243368] free_unref_page+0x48/0x80
> >> [ 87.243991] __free_pages+0x2e/0x40
> >> [ 87.244611] free_pages+0x54/0x5a
> >> [ 87.245188] uart_shutdown+0x3df/0x4e2
> >> [ 87.245817] uart_hangup+0x123/0x280
> >> [ 87.246406] __tty_hangup+0x4da/0x50f
> >> [ 87.247025] tty_vhangup_session+0xe/0x10
> >> [ 87.247680] disassociate_ctty+0xeb/0x5c5
> >> [ 87.248349] do_exit+0xc97/0x1daf
> >> [ 87.248920] __x64_sys_exit_group+0x0/0x3e
> >> [ 87.249587] __wake_up_parent+0x0/0x52
> >> [ 87.250211] do_syscall_64+0x5e8/0x881
> >> [ 87.250839] entry_SYSCALL_64_after_hwframe+0x49/0xbe
But I think what really makes lockdep nervous is this thing:
uart_shutdown()
uart_port_lock() // spin_lock_irqsave(uart_port->lock)
free_page()
debug_check_no_obj_freed()
db->lock
debug_print_object()
printk()
spin_lock_irqsave(uart_port->lock)
Lockdep complains about: uart_port->lock -> db->lock
It knows that we already have the reverse chain: db->lock -> uart_port->lock
From
db->lock -> debug_print_object() -> printk() -> console_sem -> uart_port->lock
> >> [ 87.255156] CPU0 CPU1
> >> [ 87.255813] ---- ----
> >> [ 87.256460] lock(&port_lock_key);
> >> [ 87.256973] lock(console_owner);
> >> [ 87.257829] lock(&port_lock_key);
> >> [ 87.258680] lock(&obj_hash[i].lock);
So it's like
CPU0 CPU1
uart_shutdown() db->lock
uart_port->lock debug_print_object()
free_page() printk
debug_check_no_obj_freed uart_port->lock
db->lock
In this particular case we probably can just move free_page()
out of uart_port lock scope. Note that free_page()->MM can printk()
on its own.
Something like this (not tested):
---
drivers/tty/serial/serial_core.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index c439a5a1e6c0..64050f506348 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -268,6 +268,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
struct uart_port *uport = uart_port_check(state);
struct tty_port *port = &state->port;
unsigned long flags = 0;
+ char *xmit_buf = NULL;
/*
* Set the TTY IO error marker
@@ -297,15 +298,16 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
*/
tty_port_set_suspended(port, 0);
+ uart_port_lock(state, flags);
+ xmit_buf = state->xmit.buf;
+ state->xmit.buf = NULL;
+ uart_port_unlock(uport, flags);
+
/*
* Free the transmit buffer page.
*/
- uart_port_lock(state, flags);
- if (state->xmit.buf) {
- free_page((unsigned long)state->xmit.buf);
- state->xmit.buf = NULL;
- }
- uart_port_unlock(uport, flags);
+ if (xmit_buf)
+ free_page((unsigned long)xmit_buf);
}
/**
---
Can send a formal patch, if it works for you guys.
[1] https://lore.kernel.org/lkml/1542653726-5655-8-git-send-email-longman(a)redhat.com/T/#u
-ss
next prev parent reply other threads:[~2018-12-12 3:42 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-11 9:11 [LKP] [tty] c96cf923a9: WARNING:possible_circular_locking_dependency_detected kernel test robot
2018-12-11 9:11 ` kernel test robot
2018-12-11 13:49 ` [LKP] " Jiri Slaby
2018-12-11 13:49 ` Jiri Slaby
2018-12-11 20:59 ` [LKP] " Dmitry Safonov
2018-12-11 20:59 ` Dmitry Safonov
2018-12-12 3:42 ` Sergey Senozhatsky [this message]
2018-12-12 3:42 ` Sergey Senozhatsky
2018-12-12 5:04 ` [LKP] " Sergey Senozhatsky
2018-12-12 5:04 ` Sergey Senozhatsky
2018-12-12 15:12 ` [LKP] " Waiman Long
2018-12-12 15:12 ` Waiman Long
2018-12-12 9:07 ` [LKP] " Peter Zijlstra
2018-12-12 9:07 ` Peter Zijlstra
2018-12-13 5:38 ` [LKP] " Sergey Senozhatsky
2018-12-13 5:38 ` Sergey Senozhatsky
2018-12-12 14:54 ` [LKP] " Dmitry Safonov
2018-12-12 14:54 ` Dmitry Safonov
2018-12-13 2:19 ` [LKP] " Sergey Senozhatsky
2018-12-13 2:19 ` Sergey Senozhatsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181212034252.GD431@jagdpanzerIV \
--to=sergey.senozhatsky.work@gmail.com \
--cc=dima@arista.com \
--cc=gregkh@linuxfoundation.org \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=lkp@01.org \
--cc=longman@redhat.com \
--cc=mpatocka@redhat.com \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=rong.a.chen@intel.com \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.