From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, dingtianhong <dingtianhong@huawei.com>,
Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
"David S. Miller" <davem@davemloft.net>,
Hannes Frederic Sowa <hannes@stressinduktion.org>,
Chen Weilong <chenweilong@huawei.com>,
Cong Wang <amwang@redhat.com>
Subject: [ 20/45] ipv6,mcast: always hold idev->lock before mca_lock
Date: Fri, 26 Jul 2013 13:57:40 -0700 [thread overview]
Message-ID: <20130726205657.107956655@linuxfoundation.org> (raw)
In-Reply-To: <20130726205654.896050165@linuxfoundation.org>
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amerigo Wang <amwang@redhat.com>
[ Upstream commit 8965779d2c0e6ab246c82a405236b1fb2adae6b2, with
some bits from commit b7b1bfce0bb68bd8f6e62a28295922785cc63781
("ipv6: split duplicate address detection and router solicitation timer")
to get the __ipv6_get_lladdr() used by this patch. ]
dingtianhong reported the following deadlock detected by lockdep:
======================================================
[ INFO: possible circular locking dependency detected ]
3.4.24.05-0.1-default #1 Not tainted
-------------------------------------------------------
ksoftirqd/0/3 is trying to acquire lock:
(&ndev->lock){+.+...}, at: [<ffffffff8147f804>] ipv6_get_lladdr+0x74/0x120
but task is already holding lock:
(&mc->mca_lock){+.+...}, at: [<ffffffff8149d130>] mld_send_report+0x40/0x150
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&mc->mca_lock){+.+...}:
[<ffffffff810a8027>] validate_chain+0x637/0x730
[<ffffffff810a8417>] __lock_acquire+0x2f7/0x500
[<ffffffff810a8734>] lock_acquire+0x114/0x150
[<ffffffff814f691a>] rt_spin_lock+0x4a/0x60
[<ffffffff8149e4bb>] igmp6_group_added+0x3b/0x120
[<ffffffff8149e5d8>] ipv6_mc_up+0x38/0x60
[<ffffffff81480a4d>] ipv6_find_idev+0x3d/0x80
[<ffffffff81483175>] addrconf_notify+0x3d5/0x4b0
[<ffffffff814fae3f>] notifier_call_chain+0x3f/0x80
[<ffffffff81073471>] raw_notifier_call_chain+0x11/0x20
[<ffffffff813d8722>] call_netdevice_notifiers+0x32/0x60
[<ffffffff813d92d4>] __dev_notify_flags+0x34/0x80
[<ffffffff813d9360>] dev_change_flags+0x40/0x70
[<ffffffff813ea627>] do_setlink+0x237/0x8a0
[<ffffffff813ebb6c>] rtnl_newlink+0x3ec/0x600
[<ffffffff813eb4d0>] rtnetlink_rcv_msg+0x160/0x310
[<ffffffff814040b9>] netlink_rcv_skb+0x89/0xb0
[<ffffffff813eb357>] rtnetlink_rcv+0x27/0x40
[<ffffffff81403e20>] netlink_unicast+0x140/0x180
[<ffffffff81404a9e>] netlink_sendmsg+0x33e/0x380
[<ffffffff813c4252>] sock_sendmsg+0x112/0x130
[<ffffffff813c537e>] __sys_sendmsg+0x44e/0x460
[<ffffffff813c5544>] sys_sendmsg+0x44/0x70
[<ffffffff814feab9>] system_call_fastpath+0x16/0x1b
-> #0 (&ndev->lock){+.+...}:
[<ffffffff810a798e>] check_prev_add+0x3de/0x440
[<ffffffff810a8027>] validate_chain+0x637/0x730
[<ffffffff810a8417>] __lock_acquire+0x2f7/0x500
[<ffffffff810a8734>] lock_acquire+0x114/0x150
[<ffffffff814f6c82>] rt_read_lock+0x42/0x60
[<ffffffff8147f804>] ipv6_get_lladdr+0x74/0x120
[<ffffffff8149b036>] mld_newpack+0xb6/0x160
[<ffffffff8149b18b>] add_grhead+0xab/0xc0
[<ffffffff8149d03b>] add_grec+0x3ab/0x460
[<ffffffff8149d14a>] mld_send_report+0x5a/0x150
[<ffffffff8149f99e>] igmp6_timer_handler+0x4e/0xb0
[<ffffffff8105705a>] call_timer_fn+0xca/0x1d0
[<ffffffff81057b9f>] run_timer_softirq+0x1df/0x2e0
[<ffffffff8104e8c7>] handle_pending_softirqs+0xf7/0x1f0
[<ffffffff8104ea3b>] __do_softirq_common+0x7b/0xf0
[<ffffffff8104f07f>] __thread_do_softirq+0x1af/0x210
[<ffffffff8104f1c1>] run_ksoftirqd+0xe1/0x1f0
[<ffffffff8106c7de>] kthread+0xae/0xc0
[<ffffffff814fff74>] kernel_thread_helper+0x4/0x10
actually we can just hold idev->lock before taking pmc->mca_lock,
and avoid taking idev->lock again when iterating idev->addr_list,
since the upper callers of mld_newpack() already take
read_lock_bh(&idev->lock).
Reported-by: dingtianhong <dingtianhong@huawei.com>
Cc: dingtianhong <dingtianhong@huawei.com>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Tested-by: Ding Tianhong <dingtianhong@huawei.com>
Tested-by: Chen Weilong <chenweilong@huawei.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/addrconf.h | 3 +++
net/ipv6/addrconf.c | 28 ++++++++++++++++++----------
net/ipv6/mcast.c | 18 ++++++++++--------
3 files changed, 31 insertions(+), 18 deletions(-)
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -81,6 +81,9 @@ extern int ipv6_dev_get_saddr(struct n
const struct in6_addr *daddr,
unsigned int srcprefs,
struct in6_addr *saddr);
+extern int __ipv6_get_lladdr(struct inet6_dev *idev,
+ struct in6_addr *addr,
+ unsigned char banned_flags);
extern int ipv6_get_lladdr(struct net_device *dev,
struct in6_addr *addr,
unsigned char banned_flags);
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1235,6 +1235,23 @@ try_nextdev:
}
EXPORT_SYMBOL(ipv6_dev_get_saddr);
+int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
+ unsigned char banned_flags)
+{
+ struct inet6_ifaddr *ifp;
+ int err = -EADDRNOTAVAIL;
+
+ list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ if (ifp->scope == IFA_LINK &&
+ !(ifp->flags & banned_flags)) {
+ ipv6_addr_copy(addr, &ifp->addr);
+ err = 0;
+ break;
+ }
+ }
+ return err;
+}
+
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
unsigned char banned_flags)
{
@@ -1244,17 +1261,8 @@ int ipv6_get_lladdr(struct net_device *d
rcu_read_lock();
idev = __in6_dev_get(dev);
if (idev) {
- struct inet6_ifaddr *ifp;
-
read_lock_bh(&idev->lock);
- list_for_each_entry(ifp, &idev->addr_list, if_list) {
- if (ifp->scope == IFA_LINK &&
- !(ifp->flags & banned_flags)) {
- ipv6_addr_copy(addr, &ifp->addr);
- err = 0;
- break;
- }
- }
+ err = __ipv6_get_lladdr(idev, addr, banned_flags);
read_unlock_bh(&idev->lock);
}
rcu_read_unlock();
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1334,8 +1334,9 @@ mld_scount(struct ifmcaddr6 *pmc, int ty
return scount;
}
-static struct sk_buff *mld_newpack(struct net_device *dev, int size)
+static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size)
{
+ struct net_device *dev = idev->dev;
struct net *net = dev_net(dev);
struct sock *sk = net->ipv6.igmp_sk;
struct sk_buff *skb;
@@ -1358,7 +1359,7 @@ static struct sk_buff *mld_newpack(struc
skb_reserve(skb, LL_RESERVED_SPACE(dev));
- if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
+ if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
/* <draft-ietf-magma-mld-source-05.txt>:
* use unspecified address as the source address
* when a valid link-local address is not available.
@@ -1461,7 +1462,7 @@ static struct sk_buff *add_grhead(struct
struct mld2_grec *pgr;
if (!skb)
- skb = mld_newpack(dev, dev->mtu);
+ skb = mld_newpack(pmc->idev, dev->mtu);
if (!skb)
return NULL;
pgr = (struct mld2_grec *)skb_put(skb, sizeof(struct mld2_grec));
@@ -1481,7 +1482,8 @@ static struct sk_buff *add_grhead(struct
static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
int type, int gdeleted, int sdeleted)
{
- struct net_device *dev = pmc->idev->dev;
+ struct inet6_dev *idev = pmc->idev;
+ struct net_device *dev = idev->dev;
struct mld2_report *pmr;
struct mld2_grec *pgr = NULL;
struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list;
@@ -1510,7 +1512,7 @@ static struct sk_buff *add_grec(struct s
AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
if (skb)
mld_sendpack(skb);
- skb = mld_newpack(dev, dev->mtu);
+ skb = mld_newpack(idev, dev->mtu);
}
}
first = 1;
@@ -1537,7 +1539,7 @@ static struct sk_buff *add_grec(struct s
pgr->grec_nsrcs = htons(scount);
if (skb)
mld_sendpack(skb);
- skb = mld_newpack(dev, dev->mtu);
+ skb = mld_newpack(idev, dev->mtu);
first = 1;
scount = 0;
}
@@ -1592,8 +1594,8 @@ static void mld_send_report(struct inet6
struct sk_buff *skb = NULL;
int type;
+ read_lock_bh(&idev->lock);
if (!pmc) {
- read_lock_bh(&idev->lock);
for (pmc=idev->mc_list; pmc; pmc=pmc->next) {
if (pmc->mca_flags & MAF_NOREPORT)
continue;
@@ -1605,7 +1607,6 @@ static void mld_send_report(struct inet6
skb = add_grec(skb, pmc, type, 0, 0);
spin_unlock_bh(&pmc->mca_lock);
}
- read_unlock_bh(&idev->lock);
} else {
spin_lock_bh(&pmc->mca_lock);
if (pmc->mca_sfcount[MCAST_EXCLUDE])
@@ -1615,6 +1616,7 @@ static void mld_send_report(struct inet6
skb = add_grec(skb, pmc, type, 0, 0);
spin_unlock_bh(&pmc->mca_lock);
}
+ read_unlock_bh(&idev->lock);
if (skb)
mld_sendpack(skb);
}
next prev parent reply other threads:[~2013-07-26 20:58 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-26 20:57 [ 00/45] 3.0.88-stable review Greg Kroah-Hartman
2013-07-26 20:57 ` [ 01/45] tick: Prevent uncontrolled switch to oneshot mode Greg Kroah-Hartman
2013-07-26 20:57 ` [ 02/45] ASoC: sglt5000: Fix SGTL5000_PLL_FRAC_DIV_MASK Greg Kroah-Hartman
2013-07-26 20:57 ` [ 03/45] rt2x00: read 5GHz TX power values from the correct offset Greg Kroah-Hartman
2013-07-26 20:57 ` [ 04/45] SCSI: zfcp: fix adapter (re)open recovery while link to SAN is down Greg Kroah-Hartman
2013-07-26 20:57 ` [ 05/45] SCSI: mpt2sas: fix firmware failure with wrong task attribute Greg Kroah-Hartman
2013-07-26 20:57 ` [ 06/45] tracing: Use current_uid() for critical time tracing Greg Kroah-Hartman
2013-07-26 20:57 ` [ 07/45] perf: Clone child context from parent context pmu Greg Kroah-Hartman
2013-07-26 20:57 ` [ 08/45] perf: Remove WARN_ON_ONCE() check in __perf_event_enable() for valid scenario Greg Kroah-Hartman
2013-07-26 20:57 ` [ 09/45] perf: Fix perf_lock_task_context() vs RCU Greg Kroah-Hartman
2013-07-26 20:57 ` [ 10/45] sparc32: vm_area_struct access for old Sun SPARCs Greg Kroah-Hartman
2013-07-26 20:57 ` [ 11/45] sparc64 address-congruence property Greg Kroah-Hartman
2013-07-26 20:57 ` Greg Kroah-Hartman
2013-07-26 20:57 ` [ 12/45] sparc: tsb must be flushed before tlb Greg Kroah-Hartman
2013-07-26 20:57 ` [ 13/45] bridge: fix switched interval for MLD Query types Greg Kroah-Hartman
2013-07-26 20:57 ` [ 14/45] ipv6: dont call addrconf_dst_alloc again when enable lo Greg Kroah-Hartman
2013-07-26 20:57 ` [ 15/45] ipv6: ip6_sk_dst_check() must not assume ipv6 dst Greg Kroah-Hartman
2013-07-26 20:57 ` [ 16/45] af_key: fix info leaks in notify messages Greg Kroah-Hartman
2013-07-26 20:57 ` Greg Kroah-Hartman
2013-07-26 20:57 ` [ 17/45] neighbour: fix a race in neigh_destroy() Greg Kroah-Hartman
2013-07-26 20:57 ` [ 18/45] x25: Fix broken locking in ioctl error paths Greg Kroah-Hartman
2013-07-26 20:57 ` [ 19/45] net: Swap ver and type in pppoe_hdr Greg Kroah-Hartman
2013-07-26 20:57 ` Greg Kroah-Hartman [this message]
2013-07-26 20:57 ` [ 21/45] l2tp: add missing .owner to struct pppox_proto Greg Kroah-Hartman
2013-07-26 20:57 ` [ 22/45] ipv6: call udp_push_pending_frames when uncorking a socket with AF_INET pending data Greg Kroah-Hartman
2013-07-26 20:57 ` [ 23/45] sunvnet: vnet_port_remove must call unregister_netdev Greg Kroah-Hartman
2013-07-26 20:57 ` [ 24/45] ifb: fix rcu_sched self-detected stalls Greg Kroah-Hartman
2013-07-26 20:57 ` [ 25/45] dummy: fix oops when loading the dummy failed Greg Kroah-Hartman
2013-07-26 20:57 ` [ 26/45] ifb: fix oops when loading the ifb failed Greg Kroah-Hartman
2013-07-26 20:57 ` [ 27/45] vlan: fix a race in egress prio management Greg Kroah-Hartman
2013-07-26 20:57 ` [ 28/45] writeback: Fix periodic writeback after fs mount Greg Kroah-Hartman
2013-07-26 20:57 ` [ 29/45] SCSI: megaraid_sas: fix memory leak if SGL has zero length entries Greg Kroah-Hartman
2013-07-26 20:57 ` [ 30/45] SCSI: Fix incorrect memset in bnx2fc_parse_fcp_rsp Greg Kroah-Hartman
2013-07-26 20:57 ` [ 31/45] usb: serial: option: blacklist ONDA MT689DC QMI interface Greg Kroah-Hartman
2013-07-26 20:57 ` [ 32/45] usb: option: add TP-LINK MA260 Greg Kroah-Hartman
2013-07-26 20:57 ` [ 33/45] usb: serial: option: add Olivetti Olicard 200 Greg Kroah-Hartman
2013-07-26 20:57 ` [ 34/45] usb: serial: option.c: remove ONDA MT825UP product ID fromdriver Greg Kroah-Hartman
2013-07-26 20:57 ` [ 35/45] USB: option: append Petatel NP10T device to GSM modems list Greg Kroah-Hartman
2013-07-26 20:57 ` [ 36/45] USB: option: add D-Link DWM-152/C1 and DWM-156/C1 Greg Kroah-Hartman
2013-07-26 20:57 ` [ 37/45] usb: serial: option: Add ONYX 3G device support Greg Kroah-Hartman
2013-07-26 20:57 ` [ 38/45] usb: serial: cp210x: Add USB ID for Netgear Switches embedded serial adapter Greg Kroah-Hartman
2013-07-26 20:57 ` [ 39/45] USB: cp210x: add MMB and PI ZigBee USB Device Support Greg Kroah-Hartman
2013-07-26 20:58 ` [ 40/45] usb: cp210x support SEL C662 Vendor/Device Greg Kroah-Hartman
2013-07-26 20:58 ` [ 41/45] lockd: protect nlm_blocked access in nlmsvc_retry_blocked Greg Kroah-Hartman
2013-07-26 20:58 ` [ 42/45] tracing: Fix irqs-off tag display in syscall tracing Greg Kroah-Hartman
2013-07-26 20:58 ` [ 43/45] hrtimers: Move SMP function call to thread context Greg Kroah-Hartman
2013-07-26 20:58 ` Greg Kroah-Hartman
2013-07-26 20:58 ` [ 44/45] [SCSI] zfcp: status read buffers on first adapter open with link down Greg Kroah-Hartman
2013-07-26 20:58 ` [ 45/45] ALSA: usb-audio: 6fire: return correct XRUN indication Greg Kroah-Hartman
2013-07-27 11:22 ` [ 00/45] 3.0.88-stable review linux
2013-07-27 23:30 ` Ben Hutchings
2013-07-28 1:31 ` Guenter Roeck
2013-07-28 18:39 ` Greg Kroah-Hartman
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=20130726205657.107956655@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=amwang@redhat.com \
--cc=chenweilong@huawei.com \
--cc=davem@davemloft.net \
--cc=dingtianhong@huawei.com \
--cc=hannes@stressinduktion.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=yoshfuji@linux-ipv6.org \
/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.