diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /net/tipc/bcast.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'net/tipc/bcast.c')
| -rw-r--r-- | net/tipc/bcast.c | 61 | 
1 files changed, 55 insertions, 6 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a816382fc8af..41042de3ae9b 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -170,6 +170,30 @@ static void bclink_retransmit_pkt(struct tipc_net *tn, u32 after, u32 to)  }  /** + * bclink_prepare_wakeup - prepare users for wakeup after congestion + * @bcl: broadcast link + * @resultq: queue for users which can be woken up + * Move a number of waiting users, as permitted by available space in + * the send queue, from link wait queue to specified queue for wakeup + */ +static void bclink_prepare_wakeup(struct tipc_link *bcl, struct sk_buff_head *resultq) +{ +	int pnd[TIPC_SYSTEM_IMPORTANCE + 1] = {0,}; +	int imp, lim; +	struct sk_buff *skb, *tmp; + +	skb_queue_walk_safe(&bcl->wakeupq, skb, tmp) { +		imp = TIPC_SKB_CB(skb)->chain_imp; +		lim = bcl->window + bcl->backlog[imp].limit; +		pnd[imp] += TIPC_SKB_CB(skb)->chain_sz; +		if ((pnd[imp] + bcl->backlog[imp].len) >= lim) +			continue; +		skb_unlink(skb, &bcl->wakeupq); +		skb_queue_tail(resultq, skb); +	} +} + +/**   * tipc_bclink_wakeup_users - wake up pending users   *   * Called with no locks taken @@ -177,8 +201,12 @@ static void bclink_retransmit_pkt(struct tipc_net *tn, u32 after, u32 to)  void tipc_bclink_wakeup_users(struct net *net)  {  	struct tipc_net *tn = net_generic(net, tipc_net_id); +	struct tipc_link *bcl = tn->bcl; +	struct sk_buff_head resultq; -	tipc_sk_rcv(net, &tn->bclink->link.wakeupq); +	skb_queue_head_init(&resultq); +	bclink_prepare_wakeup(bcl, &resultq); +	tipc_sk_rcv(net, &resultq);  }  /** @@ -316,6 +344,29 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr,  	}  } +void tipc_bclink_sync_state(struct tipc_node *n, struct tipc_msg *hdr) +{ +	u16 last = msg_last_bcast(hdr); +	int mtyp = msg_type(hdr); + +	if (unlikely(msg_user(hdr) != LINK_PROTOCOL)) +		return; +	if (mtyp == STATE_MSG) { +		tipc_bclink_update_link_state(n, last); +		return; +	} +	/* Compatibility: older nodes don't know BCAST_PROTOCOL synchronization, +	 * and transfer synch info in LINK_PROTOCOL messages. +	 */ +	if (tipc_node_is_up(n)) +		return; +	if ((mtyp != RESET_MSG) && (mtyp != ACTIVATE_MSG)) +		return; +	n->bclink.last_sent = last; +	n->bclink.last_in = last; +	n->bclink.oos_state = 0; +} +  /**   * bclink_peek_nack - monitor retransmission requests sent by other nodes   * @@ -358,10 +409,9 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)  	/* Prepare clone of message for local node */  	skb = tipc_msg_reassemble(list); -	if (unlikely(!skb)) { -		__skb_queue_purge(list); +	if (unlikely(!skb))  		return -EHOSTUNREACH; -	} +  	/* Broadcast to all nodes */  	if (likely(bclink)) {  		tipc_bclink_lock(net); @@ -413,7 +463,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)  	 * all nodes in the cluster don't ACK at the same time  	 */  	if (((seqno - tn->own_addr) % TIPC_MIN_LINK_WIN) == 0) { -		tipc_link_proto_xmit(node->active_links[node->addr & 1], +		tipc_link_proto_xmit(node_active_link(node, node->addr),  				     STATE_MSG, 0, 0, 0, 0);  		tn->bcl->stats.sent_acks++;  	} @@ -925,7 +975,6 @@ int tipc_bclink_init(struct net *net)  	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);  	bcl->bearer_id = MAX_BEARERS;  	rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer); -	bcl->state = WORKING_WORKING;  	bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg;  	msg_set_prevnode(bcl->pmsg, tn->own_addr);  	strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);  |