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 | 3090 | static void addrconf_rs_timer(unsigned long data) |
| 3091 | 3091 | { |
| 3092 | 3092 | struct inet6_dev *idev = (struct inet6_dev *)data; |
| 3093 | + struct net_device *dev = idev->dev; | |
| 3093 | 3094 | struct in6_addr lladdr; |
| 3094 | 3095 | |
| 3095 | 3096 | write_lock(&idev->lock); |
| @@ -3104,12 +3105,14 @@ static void addrconf_rs_timer(unsigned long data) · 8 unmodified lines | ||
| 3104 | 3105 | goto out; |
| 3105 | 3106 | |
| 3106 | 3107 | if (idev->rs_probes++ < idev->cnf.rtr_solicits) { |
| 3107 | − if (!__ipv6_get_lladdr(idev, &lladdr, IFA_F_TENTATIVE)) | |
| 3108 | − ndisc_send_rs(idev->dev, &lladdr, | |
| 3108 | + write_unlock(&idev->lock); | |
| 3109 | + if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE)) | |
| 3110 | + ndisc_send_rs(dev, &lladdr, | |
| 3109 | 3111 | &in6addr_linklocal_allrouters); |
| 3110 | 3112 | else |
| 3111 | − goto out; | |
| 3113 | + goto put; | |
| 3112 | 3114 | |
| 3115 | + write_lock(&idev->lock); | |
| 3113 | 3116 | /* The wait after the last probe can be shorter */ |
| 3114 | 3117 | addrconf_mod_rs_timer(idev, (idev->rs_probes == |
| 3115 | 3118 | idev->cnf.rtr_solicits) ? |
| @@ -3125,6 +3128,7 @@ static void addrconf_rs_timer(unsigned long data) · 9 unmodified lines | ||
| 3125 | 3128 | |
| 3126 | 3129 | out: |
| 3127 | 3130 | write_unlock(&idev->lock); |
| 3131 | +put: | |
| 3128 | 3132 | in6_dev_put(idev); |
| 3129 | 3133 | } |
| 3130 | 3134 | |