From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Ying Xue <ying.xue@windriver.com>,
Jon Maloy <jon.maloy@ericsson.com>,
Paul Gortmaker <paul.gortmaker@windriver.com>,
"David S. Miller" <davem@davemloft.net>
Subject: [ 19/23] tipc: fix lockdep warning during bearer initialization
Date: Thu, 12 Sep 2013 10:45:15 -0700 [thread overview]
Message-ID: <20130912174453.835176228@linuxfoundation.org> (raw)
In-Reply-To: <20130912174451.748805761@linuxfoundation.org>
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ying Xue <ying.xue@windriver.com>
[ Upstream commit 4225a398c1352a7a5c14dc07277cb5cc4473983b ]
When the lockdep validator is enabled, it will report the below
warning when we enable a TIPC bearer:
[ INFO: possible irq lock inversion dependency detected ]
---------------------------------------------------------
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(ptype_lock);
local_irq_disable();
lock(tipc_net_lock);
lock(ptype_lock);
<Interrupt>
lock(tipc_net_lock);
*** DEADLOCK ***
the shortest dependencies between 2nd lock and 1st lock:
-> (ptype_lock){+.+...} ops: 10 {
[...]
SOFTIRQ-ON-W at:
[<c1089418>] __lock_acquire+0x528/0x13e0
[<c108a360>] lock_acquire+0x90/0x100
[<c1553c38>] _raw_spin_lock+0x38/0x50
[<c14651ca>] dev_add_pack+0x3a/0x60
[<c182da75>] arp_init+0x1a/0x48
[<c182dce5>] inet_init+0x181/0x27e
[<c1001114>] do_one_initcall+0x34/0x170
[<c17f7329>] kernel_init+0x110/0x1b2
[<c155b6a2>] kernel_thread_helper+0x6/0x10
[...]
... key at: [<c17e4b10>] ptype_lock+0x10/0x20
... acquired at:
[<c108a360>] lock_acquire+0x90/0x100
[<c1553c38>] _raw_spin_lock+0x38/0x50
[<c14651ca>] dev_add_pack+0x3a/0x60
[<c8bc18d2>] enable_bearer+0xf2/0x140 [tipc]
[<c8bb283a>] tipc_enable_bearer+0x1ba/0x450 [tipc]
[<c8bb3a04>] tipc_cfg_do_cmd+0x5c4/0x830 [tipc]
[<c8bbc032>] handle_cmd+0x42/0xd0 [tipc]
[<c148e802>] genl_rcv_msg+0x232/0x280
[<c148d3f6>] netlink_rcv_skb+0x86/0xb0
[<c148e5bc>] genl_rcv+0x1c/0x30
[<c148d144>] netlink_unicast+0x174/0x1f0
[<c148ddab>] netlink_sendmsg+0x1eb/0x2d0
[<c1456bc1>] sock_aio_write+0x161/0x170
[<c1135a7c>] do_sync_write+0xac/0xf0
[<c11360f6>] vfs_write+0x156/0x170
[<c11361e2>] sys_write+0x42/0x70
[<c155b0df>] sysenter_do_call+0x12/0x38
[...]
}
-> (tipc_net_lock){+..-..} ops: 4 {
[...]
IN-SOFTIRQ-R at:
[<c108953a>] __lock_acquire+0x64a/0x13e0
[<c108a360>] lock_acquire+0x90/0x100
[<c15541cd>] _raw_read_lock_bh+0x3d/0x50
[<c8bb874d>] tipc_recv_msg+0x1d/0x830 [tipc]
[<c8bc195f>] recv_msg+0x3f/0x50 [tipc]
[<c146a5fa>] __netif_receive_skb+0x22a/0x590
[<c146ab0b>] netif_receive_skb+0x2b/0xf0
[<c13c43d2>] pcnet32_poll+0x292/0x780
[<c146b00a>] net_rx_action+0xfa/0x1e0
[<c103a4be>] __do_softirq+0xae/0x1e0
[...]
}
>>From the log, we can see three different call chains between
CPU0 and CPU1:
Time 0 on CPU0:
kernel_init()->inet_init()->dev_add_pack()
At time 0, the ptype_lock is held by CPU0 in dev_add_pack();
Time 1 on CPU1:
tipc_enable_bearer()->enable_bearer()->dev_add_pack()
At time 1, tipc_enable_bearer() first holds tipc_net_lock, and then
wants to take ptype_lock to register TIPC protocol handler into the
networking stack. But the ptype_lock has been taken by dev_add_pack()
on CPU0, so at this time the dev_add_pack() running on CPU1 has to be
busy looping.
Time 2 on CPU0:
netif_receive_skb()->recv_msg()->tipc_recv_msg()
At time 2, an incoming TIPC packet arrives at CPU0, hence
tipc_recv_msg() will be invoked. In tipc_recv_msg(), it first wants
to hold tipc_net_lock. At the moment, below scenario happens:
On CPU0, below is our sequence of taking locks:
lock(ptype_lock)->lock(tipc_net_lock)
On CPU1, our sequence of taking locks looks like:
lock(tipc_net_lock)->lock(ptype_lock)
Obviously deadlock may happen in this case.
But please note the deadlock possibly doesn't occur at all when the
first TIPC bearer is enabled. Before enable_bearer() -- running on
CPU1 does not hold ptype_lock, so the TIPC receive handler (i.e.
recv_msg()) is not registered successfully via dev_add_pack(), so
the tipc_recv_msg() cannot be called by recv_msg() even if a TIPC
message comes to CPU0. But when the second TIPC bearer is
registered, the deadlock can perhaps really happen.
To fix it, we will push the work of registering TIPC protocol
handler into workqueue context. After the change, both paths taking
ptype_lock are always in process contexts, thus, the deadlock should
never occur.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/eth_media.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -53,6 +53,7 @@ struct eth_bearer {
struct tipc_bearer *bearer;
struct net_device *dev;
struct packet_type tipc_packet_type;
+ struct work_struct setup;
struct work_struct cleanup;
};
@@ -138,6 +139,17 @@ static int recv_msg(struct sk_buff *buf,
}
/**
+ * setup_bearer - setup association between Ethernet bearer and interface
+ */
+static void setup_bearer(struct work_struct *work)
+{
+ struct eth_bearer *eb_ptr =
+ container_of(work, struct eth_bearer, setup);
+
+ dev_add_pack(&eb_ptr->tipc_packet_type);
+}
+
+/**
* enable_bearer - attach TIPC bearer to an Ethernet interface
*/
@@ -181,7 +193,8 @@ static int enable_bearer(struct tipc_bea
eb_ptr->tipc_packet_type.func = recv_msg;
eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
- dev_add_pack(&eb_ptr->tipc_packet_type);
+ INIT_WORK(&eb_ptr->setup, setup_bearer);
+ schedule_work(&eb_ptr->setup);
/* Associate TIPC bearer with Ethernet bearer */
next prev parent reply other threads:[~2013-09-12 17:45 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-12 17:44 [ 00/23] 3.4.62-stable review Greg Kroah-Hartman
2013-09-12 17:44 ` [ 01/23] htb: fix sign extension bug Greg Kroah-Hartman
2013-09-13 5:04 ` [00/23] 3.4.62-stable review Guenter Roeck
2013-09-13 12:35 ` Greg Kroah-Hartman
2013-09-12 17:44 ` [ 02/23] net: check net.core.somaxconn sysctl values Greg Kroah-Hartman
2013-09-12 17:44 ` [ 03/23] neighbour: populate neigh_parms on alloc before calling ndo_neigh_setup Greg Kroah-Hartman
2013-09-12 17:45 ` [ 04/23] bonding: modify only neigh_parms owned by us Greg Kroah-Hartman
2013-09-12 17:45 ` [ 05/23] fib_trie: remove potential out of bound access Greg Kroah-Hartman
2013-09-12 17:45 ` [ 06/23] tcp: cubic: fix overflow error in bictcp_update() Greg Kroah-Hartman
2013-09-12 17:45 ` [ 07/23] tcp: cubic: fix bug in bictcp_acked() Greg Kroah-Hartman
2013-09-12 17:45 ` [ 08/23] ipv6: dont stop backtracking in fib6_lookup_1 if subtree does not match Greg Kroah-Hartman
2013-09-12 17:45 ` [ 09/23] 8139cp: Fix skb leak in rx_status_loop failure path Greg Kroah-Hartman
2013-09-12 17:45 ` [ 10/23] tun: signedness bug in tun_get_user() Greg Kroah-Hartman
2013-09-12 17:45 ` [ 11/23] ipv6: remove max_addresses check from ipv6_create_tempaddr Greg Kroah-Hartman
2013-09-12 17:45 ` [ 12/23] ipv6: drop packets with multiple fragmentation headers Greg Kroah-Hartman
2013-09-12 17:45 ` [ 13/23] ipv6: Dont depend on per socket memory for neighbour discovery messages Greg Kroah-Hartman
2013-09-12 17:45 ` [ 14/23] net: bridge: convert MLDv2 Query MRC into msecs_to_jiffies for max_delay Greg Kroah-Hartman
2013-09-12 17:45 ` [ 15/23] ICMPv6: treat dest unreachable codes 5 and 6 as EACCES, not EPROTO Greg Kroah-Hartman
2013-09-12 17:45 ` [ 16/23] net: ipv6: tcp: fix potential use after free in tcp_v6_do_rcv Greg Kroah-Hartman
2013-09-12 17:45 ` [ 17/23] vhost: zerocopy: poll vq in zerocopy callback Greg Kroah-Hartman
2013-09-12 17:45 ` [ 18/23] macvtap: do not zerocopy if iov needs more pages than MAX_SKB_FRAGS Greg Kroah-Hartman
2013-09-12 17:45 ` Greg Kroah-Hartman [this message]
2013-09-12 17:45 ` [ 20/23] m32r: consistently use "suffix-$(...)" Greg Kroah-Hartman
2013-09-12 17:45 ` [ 21/23] m32r: add memcpy() for CONFIG_KERNEL_GZIP=y Greg Kroah-Hartman
2013-09-12 17:45 ` [ 22/23] m32r: make memset() global for CONFIG_KERNEL_BZIP2=y Greg Kroah-Hartman
2013-09-12 17:45 ` [ 23/23] Revert "KVM: X86 emulator: fix source operand decoding for 8bit mov[zs]x instructions" Greg Kroah-Hartman
2013-09-13 23:02 ` [ 00/23] 3.4.62-stable review Shuah Khan
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=20130912174453.835176228@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=davem@davemloft.net \
--cc=jon.maloy@ericsson.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paul.gortmaker@windriver.com \
--cc=stable@vger.kernel.org \
--cc=ying.xue@windriver.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).