Commit 5ca509fc authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: change node timer unit from jiffies to ms

The node keepalive interval is recalculated at each timer expiration
to catch any changes in the link tolerance, and stored in a field in
struct tipc_node. We use jiffies as unit for the stored value.

This is suboptimal, because it makes the calculation unnecessary
complex, including two unit conversions. The conversions also lead to
a rounding error that causes the link "abort limit" to be 3 in the
normal case, instead of 4, as intended. This again leads to unnecessary
link resets when the network is pushed close to its limit, e.g., in an
environment with hundreds of nodes or namesapces.

In this commit, we do instead let the keepalive value be calculated and
stored in milliseconds, so that there is only one conversion and the
rounding error is eliminated.

We also remove a redundant "keepalive" field in struct tipc_link. This
is remnant from the previous implementation.
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4282ca7
...@@ -87,7 +87,6 @@ struct tipc_stats { ...@@ -87,7 +87,6 @@ struct tipc_stats {
* @peer_bearer_id: bearer id used by link's peer endpoint * @peer_bearer_id: bearer id used by link's peer endpoint
* @bearer_id: local bearer id used by link * @bearer_id: local bearer id used by link
* @tolerance: minimum link continuity loss needed to reset link [in ms] * @tolerance: minimum link continuity loss needed to reset link [in ms]
* @keepalive_intv: link keepalive timer interval
* @abort_limit: # of unacknowledged continuity probes needed to reset link * @abort_limit: # of unacknowledged continuity probes needed to reset link
* @state: current state of link FSM * @state: current state of link FSM
* @peer_caps: bitmap describing capabilities of peer node * @peer_caps: bitmap describing capabilities of peer node
...@@ -131,7 +130,6 @@ struct tipc_link { ...@@ -131,7 +130,6 @@ struct tipc_link {
u32 peer_bearer_id; u32 peer_bearer_id;
u32 bearer_id; u32 bearer_id;
u32 tolerance; u32 tolerance;
unsigned long keepalive_intv;
u32 abort_limit; u32 abort_limit;
u32 state; u32 state;
u16 peer_caps; u16 peer_caps;
......
...@@ -378,14 +378,13 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l) ...@@ -378,14 +378,13 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
{ {
unsigned long tol = tipc_link_tolerance(l); unsigned long tol = tipc_link_tolerance(l);
unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4; unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
unsigned long keepalive_intv = msecs_to_jiffies(intv);
/* Link with lowest tolerance determines timer interval */ /* Link with lowest tolerance determines timer interval */
if (keepalive_intv < n->keepalive_intv) if (intv < n->keepalive_intv)
n->keepalive_intv = keepalive_intv; n->keepalive_intv = intv;
/* Ensure link's abort limit corresponds to current interval */ /* Ensure link's abort limit corresponds to current tolerance */
tipc_link_set_abort_limit(l, tol / jiffies_to_msecs(n->keepalive_intv)); tipc_link_set_abort_limit(l, tol / n->keepalive_intv);
} }
static void tipc_node_delete(struct tipc_node *node) static void tipc_node_delete(struct tipc_node *node)
...@@ -526,7 +525,7 @@ static void tipc_node_timeout(unsigned long data) ...@@ -526,7 +525,7 @@ static void tipc_node_timeout(unsigned long data)
if (rc & TIPC_LINK_DOWN_EVT) if (rc & TIPC_LINK_DOWN_EVT)
tipc_node_link_down(n, bearer_id, false); tipc_node_link_down(n, bearer_id, false);
} }
mod_timer(&n->timer, jiffies + n->keepalive_intv); mod_timer(&n->timer, jiffies + msecs_to_jiffies(n->keepalive_intv));
} }
/** /**
...@@ -735,6 +734,7 @@ void tipc_node_check_dest(struct net *net, u32 onode, ...@@ -735,6 +734,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
bool accept_addr = false; bool accept_addr = false;
bool reset = true; bool reset = true;
char *if_name; char *if_name;
unsigned long intv;
*dupl_addr = false; *dupl_addr = false;
*respond = false; *respond = false;
...@@ -840,10 +840,12 @@ void tipc_node_check_dest(struct net *net, u32 onode, ...@@ -840,10 +840,12 @@ void tipc_node_check_dest(struct net *net, u32 onode,
le->link = l; le->link = l;
n->link_cnt++; n->link_cnt++;
tipc_node_calculate_timer(n, l); tipc_node_calculate_timer(n, l);
if (n->link_cnt == 1) if (n->link_cnt == 1) {
if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) intv = jiffies + msecs_to_jiffies(n->keepalive_intv);
if (!mod_timer(&n->timer, intv))
tipc_node_get(n); tipc_node_get(n);
} }
}
memcpy(&le->maddr, maddr, sizeof(*maddr)); memcpy(&le->maddr, maddr, sizeof(*maddr));
exit: exit:
tipc_node_write_unlock(n); tipc_node_write_unlock(n);
......
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