Commit 19e16d22 authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

neigh: support smaller retrans_time settting

Currently, we limited the retrans_time to be greater than HZ/2. i.e.
setting retrans_time less than 500ms will not work. This makes the user
unable to achieve a more accurate control for bonding arp fast failover.

Update the sanity check to HZ/100, which is 10ms, to let users have more
ability on the retrans_time control.

v3: sync the behavior with IPv6 and update all the timer handler
v2: use HZ instead of hard code number
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 64948427
...@@ -1065,11 +1065,12 @@ static void neigh_timer_handler(struct timer_list *t) ...@@ -1065,11 +1065,12 @@ static void neigh_timer_handler(struct timer_list *t)
neigh->updated = jiffies; neigh->updated = jiffies;
atomic_set(&neigh->probes, 0); atomic_set(&neigh->probes, 0);
notify = 1; notify = 1;
next = now + NEIGH_VAR(neigh->parms, RETRANS_TIME); next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
HZ/100);
} }
} else { } else {
/* NUD_PROBE|NUD_INCOMPLETE */ /* NUD_PROBE|NUD_INCOMPLETE */
next = now + NEIGH_VAR(neigh->parms, RETRANS_TIME); next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), HZ/100);
} }
if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
...@@ -1125,7 +1126,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) ...@@ -1125,7 +1126,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
neigh->nud_state = NUD_INCOMPLETE; neigh->nud_state = NUD_INCOMPLETE;
neigh->updated = now; neigh->updated = now;
next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
HZ/2); HZ/100);
neigh_add_timer(neigh, next); neigh_add_timer(neigh, next);
immediate_probe = true; immediate_probe = true;
} else { } else {
...@@ -1427,7 +1428,8 @@ void __neigh_set_probe_once(struct neighbour *neigh) ...@@ -1427,7 +1428,8 @@ void __neigh_set_probe_once(struct neighbour *neigh)
neigh->nud_state = NUD_INCOMPLETE; neigh->nud_state = NUD_INCOMPLETE;
atomic_set(&neigh->probes, neigh_max_probes(neigh)); atomic_set(&neigh->probes, neigh_max_probes(neigh));
neigh_add_timer(neigh, neigh_add_timer(neigh,
jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); jiffies + max(NEIGH_VAR(neigh->parms, RETRANS_TIME),
HZ/100));
} }
EXPORT_SYMBOL(__neigh_set_probe_once); EXPORT_SYMBOL(__neigh_set_probe_once);
......
...@@ -1357,7 +1357,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, ...@@ -1357,7 +1357,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
regen_advance = idev->cnf.regen_max_retry * regen_advance = idev->cnf.regen_max_retry *
idev->cnf.dad_transmits * idev->cnf.dad_transmits *
NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ; max(NEIGH_VAR(idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
/* recalculate max_desync_factor each time and update /* recalculate max_desync_factor each time and update
* idev->desync_factor if it's larger * idev->desync_factor if it's larger
...@@ -4121,7 +4121,8 @@ static void addrconf_dad_work(struct work_struct *w) ...@@ -4121,7 +4121,8 @@ static void addrconf_dad_work(struct work_struct *w)
ifp->dad_probes--; ifp->dad_probes--;
addrconf_mod_dad_work(ifp, addrconf_mod_dad_work(ifp,
NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME)); max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME),
HZ/100));
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
...@@ -4527,7 +4528,7 @@ static void addrconf_verify_rtnl(void) ...@@ -4527,7 +4528,7 @@ static void addrconf_verify_rtnl(void)
!(ifp->flags&IFA_F_TENTATIVE)) { !(ifp->flags&IFA_F_TENTATIVE)) {
unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
ifp->idev->cnf.dad_transmits * ifp->idev->cnf.dad_transmits *
NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ; max(NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME), HZ/100) / HZ;
if (age >= ifp->prefered_lft - regen_advance) { if (age >= ifp->prefered_lft - regen_advance) {
struct inet6_ifaddr *ifpub = ifp->ifpub; struct inet6_ifaddr *ifpub = ifp->ifpub;
......
...@@ -1359,8 +1359,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1359,8 +1359,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) { if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
rtime = (rtime*HZ)/1000; rtime = (rtime*HZ)/1000;
if (rtime < HZ/10) if (rtime < HZ/100)
rtime = HZ/10; rtime = HZ/100;
NEIGH_VAR_SET(in6_dev->nd_parms, RETRANS_TIME, rtime); NEIGH_VAR_SET(in6_dev->nd_parms, RETRANS_TIME, rtime);
in6_dev->tstamp = jiffies; in6_dev->tstamp = jiffies;
send_ifinfo_notify = true; send_ifinfo_notify = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment