Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 333ef69e authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller
Browse files

tipc: simplify link timer implementation



We create a second, simpler, link timer function, tipc_link_timeout().
The new function  makes use of the new FSM function introduced in the
previous commit, and just like it, takes a buffer queue as parameter.
It returns an event bit field and potentially a link protocol packet
to the caller.

The existing timer function, link_timeout(), is still needed for a
while, so we redesign it to become a wrapper around the new function.

Reviewed-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 6ab30f9c
Loading
Loading
Loading
Loading
+71 −45
Original line number Diff line number Diff line
@@ -193,60 +193,30 @@ int tipc_link_is_active(struct tipc_link *l)

/**
 * link_timeout - handle expiration of link timer
 * @l_ptr: pointer to link
 */
static void link_timeout(unsigned long data)
{
	struct tipc_link *l_ptr = (struct tipc_link *)data;
	struct tipc_link *l = (struct tipc_link *)data;
	struct sk_buff_head xmitq;
	struct sk_buff *skb;
	int rc;

	tipc_node_lock(l_ptr->owner);
	__skb_queue_head_init(&xmitq);

	/* update counters used in statistical profiling of send traffic */
	l_ptr->stats.accu_queue_sz += skb_queue_len(&l_ptr->transmq);
	l_ptr->stats.queue_sz_counts++;
	tipc_node_lock(l->owner);

	skb = skb_peek(&l_ptr->transmq);
	if (skb) {
		struct tipc_msg *msg = buf_msg(skb);
		u32 length = msg_size(msg);
	rc = tipc_link_timeout(l, &xmitq);

		if ((msg_user(msg) == MSG_FRAGMENTER) &&
		    (msg_type(msg) == FIRST_FRAGMENT)) {
			length = msg_size(msg_get_wrapped(msg));
		}
		if (length) {
			l_ptr->stats.msg_lengths_total += length;
			l_ptr->stats.msg_length_counts++;
			if (length <= 64)
				l_ptr->stats.msg_length_profile[0]++;
			else if (length <= 256)
				l_ptr->stats.msg_length_profile[1]++;
			else if (length <= 1024)
				l_ptr->stats.msg_length_profile[2]++;
			else if (length <= 4096)
				l_ptr->stats.msg_length_profile[3]++;
			else if (length <= 16384)
				l_ptr->stats.msg_length_profile[4]++;
			else if (length <= 32768)
				l_ptr->stats.msg_length_profile[5]++;
			else
				l_ptr->stats.msg_length_profile[6]++;
		}
	}

	/* do all other link processing performed on a periodic basis */
	if (l_ptr->silent_intv_cnt)
		link_state_event(l_ptr, SILENCE_EVT);
	else if (link_working(l_ptr) && tipc_bclink_acks_missing(l_ptr->owner))
		tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0);
	if (rc & TIPC_LINK_DOWN_EVT)
		tipc_link_reset(l);

	l_ptr->silent_intv_cnt++;
	if (skb_queue_len(&l_ptr->backlogq))
		tipc_link_push_packets(l_ptr);
	link_set_timer(l_ptr, l_ptr->keepalive_intv);
	tipc_node_unlock(l_ptr->owner);
	tipc_link_put(l_ptr);
	skb = __skb_dequeue(&xmitq);
	if (skb)
		tipc_bearer_send(l->owner->net, l->bearer_id,
				 skb, &l->media_addr);
	link_set_timer(l, l->keepalive_intv);
	tipc_node_unlock(l->owner);
	tipc_link_put(l);
}

static void link_set_timer(struct tipc_link *link, unsigned long time)
@@ -499,6 +469,62 @@ static int tipc_link_fsm_evt(struct tipc_link *l, int evt,
	return rc;
}

/* link_profile_stats - update statistical profiling of traffic
 */
static void link_profile_stats(struct tipc_link *l)
{
	struct sk_buff *skb;
	struct tipc_msg *msg;
	int length;

	/* Update counters used in statistical profiling of send traffic */
	l->stats.accu_queue_sz += skb_queue_len(&l->transmq);
	l->stats.queue_sz_counts++;

	skb = skb_peek(&l->transmq);
	if (!skb)
		return;
	msg = buf_msg(skb);
	length = msg_size(msg);

	if (msg_user(msg) == MSG_FRAGMENTER) {
		if (msg_type(msg) != FIRST_FRAGMENT)
			return;
		length = msg_size(msg_get_wrapped(msg));
	}
	l->stats.msg_lengths_total += length;
	l->stats.msg_length_counts++;
	if (length <= 64)
		l->stats.msg_length_profile[0]++;
	else if (length <= 256)
		l->stats.msg_length_profile[1]++;
	else if (length <= 1024)
		l->stats.msg_length_profile[2]++;
	else if (length <= 4096)
		l->stats.msg_length_profile[3]++;
	else if (length <= 16384)
		l->stats.msg_length_profile[4]++;
	else if (length <= 32768)
		l->stats.msg_length_profile[5]++;
	else
		l->stats.msg_length_profile[6]++;
}

/* tipc_link_timeout - perform periodic task as instructed from node timeout
 */
int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
{
	int rc = 0;

	link_profile_stats(l);
	if (l->silent_intv_cnt)
		rc = tipc_link_fsm_evt(l, SILENCE_EVT, xmitq);
	else if (link_working(l) && tipc_bclink_acks_missing(l->owner))
		tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, xmitq);
	l->silent_intv_cnt++;
	return rc;
}

/**
 * link_schedule_user - schedule a message sender for wakeup after congestion
 * @link: congested link
+1 −0
Original line number Diff line number Diff line
@@ -245,6 +245,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
void link_prepare_wakeup(struct tipc_link *l);
int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);

static inline u32 link_own_addr(struct tipc_link *l)
{