Possible deadlock in ipv6?
Subsystems (3)
I'm not familiar with the linux net subsystem, so I would appreciate if someone could clarify if the following call chain is possible:
addrconf_ifdown() calls neigh_ifdown(nd_tbl) which locks nd_tbl.lock for writing and calls
pneigh_ifdown
pndisc_destructor
ipv6_dev_mc_dec
__ipv6_dev_mc_dec
igmp6_group_dropped
igmp6_leave_group
igmp6_send
icmp6_dst_alloc
ip6_neigh_lookup
neigh_createand neigh_create() locks nd_tbl.lock for writing again resulting in a deadlock.
Thank you.
Quoted 17 lines · Vladimir Davydov
I'm not familiar with the linux net subsystem, so I would appreciate if someone could clarify if the following call chain is possible:
addrconf_ifdown()callsneigh_ifdown(nd_tbl)which locks nd_tbl.lock for writing and callspneigh_ifdown pndisc_destructor ipv6_dev_mc_dec __ipv6_dev_mc_dec igmp6_group_dropped igmp6_leave_group igmp6_send icmp6_dst_alloc ip6_neigh_lookup neigh_create
Quoted 2 lines
and
neigh_create()locks nd_tbl.lock for writing again resulting in a deadlock.
It seems a deadlock is possible indeed, good catch !
Quoted 18 lines · Eric Dumazet
Quoted 17 lines · Vladimir Davydov
I'm not familiar with the linux net subsystem, so I would appreciate if someone could clarify if the following call chain is possible:
addrconf_ifdown()callsneigh_ifdown(nd_tbl)which locks nd_tbl.lock for writing and callspneigh_ifdown pndisc_destructor ipv6_dev_mc_dec __ipv6_dev_mc_dec igmp6_group_dropped igmp6_leave_group igmp6_send icmp6_dst_alloc ip6_neigh_lookup neigh_create
Quoted 6 lines
Quoted 2 lines
and
neigh_create()locks nd_tbl.lock for writing again resulting in a deadlock.It seems a deadlock is possible indeed, good catch !
And it seems this neigh_down() can be removed, its called later (after dev->ip6_ptr is cleared)
net/ipv6/addrconf.c +0 -1
@@ -2750,7 +2750,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)ASSERT_RTNL ();rt6_ifdown (net, dev); -neigh_ifdown (&nd_tbl, dev); idev =__in6_dev_get (dev);if (idev ==NULL )
Quoted 22 lines · Eric Dumazet
Quoted 21 lines · Eric Dumazet
Quoted 19 lines · Vladimir Davydov
I'm not familiar with the linux net subsystem, so I would appreciate if someone could clarify if the following call chain is possible:
addrconf_ifdown()callsneigh_ifdown(nd_tbl)which locks nd_tbl.lock for writing and callspneigh_ifdown pndisc_destructor ipv6_dev_mc_dec __ipv6_dev_mc_dec igmp6_group_dropped igmp6_leave_group igmp6_send icmp6_dst_alloc ip6_neigh_lookup neigh_createand
neigh_create()locks nd_tbl.lock for writing again resulting in a deadlock.
Quoted 7 lines
Quoted 3 lines
It seems a deadlock is possible indeed, good catch !
And it seems this
neigh_down()can be removed, its called later (afterdev->ip6_ptris cleared)
BTW, commit d1ed113f1669390da9898da3beddcc058d938587 did exactly the same, but it was reverted along with a bundle of other commits by 73a8bd74e2618990dbb218c3d82f53e60acd9af0.
Quoted 14 lines
net/ipv6/addrconf.c +0
-1@@ -2750,7 +2750,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)ASSERT_RTNL ();rt6_ifdown (net, dev); -neigh_ifdown (&nd_tbl, dev); idev =__in6_dev_get (dev);if (idev ==NULL )
Quoted 28 lines · Vladimir Davydov
Quoted 26 lines · Eric Dumazet
Quoted 24 lines · Eric Dumazet
Quoted 17 lines · Vladimir Davydov
I'm not familiar with the linux net subsystem, so I would appreciate if someone could clarify if the following call chain is possible:
addrconf_ifdown()callsneigh_ifdown(nd_tbl)which locks nd_tbl.lock for writing and callspneigh_ifdown pndisc_destructor ipv6_dev_mc_dec __ipv6_dev_mc_dec igmp6_group_dropped igmp6_leave_group igmp6_send icmp6_dst_alloc ip6_neigh_lookup neigh_createQuoted 2 lines
and
neigh_create()locks nd_tbl.lock for writing again resulting in a deadlock.It seems a deadlock is possible indeed, good catch !
Quoted 5 lines
Quoted 3 lines
And it seems this
neigh_down()can be removed, its called later (afterdev->ip6_ptris cleared)BTW, commit
d1ed113f1669390da9898da3beddcc058d938587did exactly the same, but it was reverted along with a bundle of other commits by73a8bd74e2618990dbb218c3d82f53e60acd9af0.
Yes, but the revert was a 'revert a serie', while this particular patch seems fine, especially if fixing a deadlock ;)
David Miller
maintainerFrom: Eric Dumazet <[email protected]>
Date: Wed, 06 Jun 2012 17:58:34 +0200
Quoted 2 lines
And it seems this
neigh_down()can be removed, its called later (afterdev->ip6_ptris cleared)
It is unclear whether we need to do the the neigh_down() in both the 'how' and '!how' cases. If so then we can't make this change.
Quoted 9 lines · David Miller
From: Eric Dumazet <[email protected]>
Date: Wed, 06 Jun 2012 17:58:34 +0200Quoted 2 lines
And it seems this
neigh_down()can be removed, its called later (afterdev->ip6_ptris cleared)It is unclear whether we need to do the the
neigh_down()in both the 'how' and '!how' cases. If so then we can't make this change.
Hmm...
Is it expected we send traffic on device dismantle ?
If no, we could do :
net/core/neighbour.c +0 -2
@@ -681,8 +681,6 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)while ((n = *np) !=NULL ) {if (!dev || n->dev == dev) { *np = n->next; -if (tbl->pdestructor) - tbl->pdestructor (n);if (n->dev)dev_put (n->dev);release_net (pneigh_net (n));
David Miller
maintainerFrom: Eric Dumazet <[email protected]>
Date: Tue, 12 Jun 2012 11:09:44 +0200
Quoted 1 line
Is it expected we send traffic on device dismantle ?
If we are subscribed to multicast groups we could, to announce our leaving those groups.