Because vxlan module will call ip6_dst_lookup() in TX path, which will hold write lock. So we have to release this write lock before calling ndisc_send_rs(), otherwise could deadlock.
Unified · Split
| @@ -3090,6 +3090,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) · 3089 unmodified lines | |||
| 3090 | static void addrconf_rs_timer(unsigned long data) | 3090 | static void addrconf_rs_timer(unsigned long data) |
| 3091 | { | 3091 | { |
| 3092 | struct inet6_dev *idev = (struct inet6_dev *)data; | 3092 | struct inet6_dev *idev = (struct inet6_dev *)data; |
| 3093 | struct net_device *dev = idev->dev; | ||
| 3093 | struct in6_addr lladdr; | 3094 | struct in6_addr lladdr; |
| 3094 | 3095 | ||
| 3095 | write_lock(&idev->lock); | 3096 | write_lock(&idev->lock); |
| @@ -3104,12 +3105,14 @@ static void addrconf_rs_timer(unsigned long data) · 8 unmodified lines | |||
| 3104 | goto out; | 3105 | goto out; |
| 3105 | 3106 | ||
| 3106 | if (idev->rs_probes++ < idev->cnf.rtr_solicits) { | 3107 | if (idev->rs_probes++ < idev->cnf.rtr_solicits) { |
| 3107 | if (!__ipv6_get_lladdr(idev, &lladdr, IFA_F_TENTATIVE)) | 3108 | write_unlock(&idev->lock); |
| 3108 | ndisc_send_rs(idev->dev, &lladdr, | 3109 | if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE)) |
| 3110 | ndisc_send_rs(dev, &lladdr, | ||
| 3109 | &in6addr_linklocal_allrouters); | 3111 | &in6addr_linklocal_allrouters); |
| 3110 | else | 3112 | else |
| 3111 | goto out; | 3113 | goto put; |
| 3112 | 3114 | ||
| 3115 | write_lock(&idev->lock); | ||
| 3113 | /* The wait after the last probe can be shorter */ | 3116 | /* The wait after the last probe can be shorter */ |
| 3114 | addrconf_mod_rs_timer(idev, (idev->rs_probes == | 3117 | addrconf_mod_rs_timer(idev, (idev->rs_probes == |
| 3115 | idev->cnf.rtr_solicits) ? | 3118 | idev->cnf.rtr_solicits) ? |
| @@ -3125,6 +3128,7 @@ static void addrconf_rs_timer(unsigned long data) · 9 unmodified lines | |||
| 3125 | 3128 | ||
| 3126 | out: | 3129 | out: |
| 3127 | write_unlock(&idev->lock); | 3130 | write_unlock(&idev->lock); |
| 3131 | put: | ||
| 3128 | in6_dev_put(idev); | 3132 | in6_dev_put(idev); |
| 3129 | } | 3133 | } |
| 3130 | 3134 | ||