aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/bcast.c2
-rw-r--r--net/tipc/link.c58
-rw-r--r--net/tipc/link.h7
3 files changed, 42 insertions, 25 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 52307397e0b1..79355531c3e2 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -831,7 +831,7 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
831 prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); 831 prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
832 if (!prop) 832 if (!prop)
833 goto attr_msg_full; 833 goto attr_msg_full;
834 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->queue_limit[0])) 834 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->window))
835 goto prop_msg_full; 835 goto prop_msg_full;
836 nla_nest_end(msg->skb, prop); 836 nla_nest_end(msg->skb, prop);
837 837
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 8c98c4d00ad6..b9325a1bddaa 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -310,7 +310,6 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
310 link_init_max_pkt(l_ptr); 310 link_init_max_pkt(l_ptr);
311 l_ptr->priority = b_ptr->priority; 311 l_ptr->priority = b_ptr->priority;
312 tipc_link_set_queue_limits(l_ptr, b_ptr->window); 312 tipc_link_set_queue_limits(l_ptr, b_ptr->window);
313
314 l_ptr->next_out_no = 1; 313 l_ptr->next_out_no = 1;
315 __skb_queue_head_init(&l_ptr->transmq); 314 __skb_queue_head_init(&l_ptr->transmq);
316 __skb_queue_head_init(&l_ptr->backlogq); 315 __skb_queue_head_init(&l_ptr->backlogq);
@@ -398,19 +397,22 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport,
398 * Move a number of waiting users, as permitted by available space in 397 * Move a number of waiting users, as permitted by available space in
399 * the send queue, from link wait queue to node wait queue for wakeup 398 * the send queue, from link wait queue to node wait queue for wakeup
400 */ 399 */
401void link_prepare_wakeup(struct tipc_link *link) 400void link_prepare_wakeup(struct tipc_link *l)
402{ 401{
403 uint pend_qsz = skb_queue_len(&link->backlogq); 402 int pnd[TIPC_SYSTEM_IMPORTANCE + 1] = {0,};
403 int imp, lim;
404 struct sk_buff *skb, *tmp; 404 struct sk_buff *skb, *tmp;
405 405
406 skb_queue_walk_safe(&link->wakeupq, skb, tmp) { 406 skb_queue_walk_safe(&l->wakeupq, skb, tmp) {
407 if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(skb)->chain_imp]) 407 imp = TIPC_SKB_CB(skb)->chain_imp;
408 lim = l->window + l->backlog[imp].limit;
409 pnd[imp] += TIPC_SKB_CB(skb)->chain_sz;
410 if ((pnd[imp] + l->backlog[imp].len) >= lim)
408 break; 411 break;
409 pend_qsz += TIPC_SKB_CB(skb)->chain_sz; 412 skb_unlink(skb, &l->wakeupq);
410 skb_unlink(skb, &link->wakeupq); 413 skb_queue_tail(&l->inputq, skb);
411 skb_queue_tail(&link->inputq, skb); 414 l->owner->inputq = &l->inputq;
412 link->owner->inputq = &link->inputq; 415 l->owner->action_flags |= TIPC_MSG_EVT;
413 link->owner->action_flags |= TIPC_MSG_EVT;
414 } 416 }
415} 417}
416 418
@@ -424,6 +426,16 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
424 l_ptr->reasm_buf = NULL; 426 l_ptr->reasm_buf = NULL;
425} 427}
426 428
429static void tipc_link_purge_backlog(struct tipc_link *l)
430{
431 __skb_queue_purge(&l->backlogq);
432 l->backlog[TIPC_LOW_IMPORTANCE].len = 0;
433 l->backlog[TIPC_MEDIUM_IMPORTANCE].len = 0;
434 l->backlog[TIPC_HIGH_IMPORTANCE].len = 0;
435 l->backlog[TIPC_CRITICAL_IMPORTANCE].len = 0;
436 l->backlog[TIPC_SYSTEM_IMPORTANCE].len = 0;
437}
438
427/** 439/**
428 * tipc_link_purge_queues - purge all pkt queues associated with link 440 * tipc_link_purge_queues - purge all pkt queues associated with link
429 * @l_ptr: pointer to link 441 * @l_ptr: pointer to link
@@ -432,7 +444,7 @@ void tipc_link_purge_queues(struct tipc_link *l_ptr)
432{ 444{
433 __skb_queue_purge(&l_ptr->deferdq); 445 __skb_queue_purge(&l_ptr->deferdq);
434 __skb_queue_purge(&l_ptr->transmq); 446 __skb_queue_purge(&l_ptr->transmq);
435 __skb_queue_purge(&l_ptr->backlogq); 447 tipc_link_purge_backlog(l_ptr);
436 tipc_link_reset_fragments(l_ptr); 448 tipc_link_reset_fragments(l_ptr);
437} 449}
438 450
@@ -466,13 +478,13 @@ void tipc_link_reset(struct tipc_link *l_ptr)
466 478
467 /* Clean up all queues, except inputq: */ 479 /* Clean up all queues, except inputq: */
468 __skb_queue_purge(&l_ptr->transmq); 480 __skb_queue_purge(&l_ptr->transmq);
469 __skb_queue_purge(&l_ptr->backlogq);
470 __skb_queue_purge(&l_ptr->deferdq); 481 __skb_queue_purge(&l_ptr->deferdq);
471 if (!owner->inputq) 482 if (!owner->inputq)
472 owner->inputq = &l_ptr->inputq; 483 owner->inputq = &l_ptr->inputq;
473 skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq); 484 skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq);
474 if (!skb_queue_empty(owner->inputq)) 485 if (!skb_queue_empty(owner->inputq))
475 owner->action_flags |= TIPC_MSG_EVT; 486 owner->action_flags |= TIPC_MSG_EVT;
487 tipc_link_purge_backlog(l_ptr);
476 l_ptr->rcv_unacked = 0; 488 l_ptr->rcv_unacked = 0;
477 l_ptr->checkpoint = 1; 489 l_ptr->checkpoint = 1;
478 l_ptr->next_out_no = 1; 490 l_ptr->next_out_no = 1;
@@ -754,16 +766,14 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
754 struct sk_buff_head *backlogq = &link->backlogq; 766 struct sk_buff_head *backlogq = &link->backlogq;
755 struct sk_buff *skb, *tmp; 767 struct sk_buff *skb, *tmp;
756 768
757 /* Match queue limit against msg importance: */ 769 /* Match backlog limit against msg importance: */
758 if (unlikely(skb_queue_len(backlogq) >= link->queue_limit[imp])) 770 if (unlikely(link->backlog[imp].len >= link->backlog[imp].limit))
759 return tipc_link_cong(link, list); 771 return tipc_link_cong(link, list);
760 772
761 /* Has valid packet limit been used ? */
762 if (unlikely(msg_size(msg) > mtu)) { 773 if (unlikely(msg_size(msg) > mtu)) {
763 __skb_queue_purge(list); 774 __skb_queue_purge(list);
764 return -EMSGSIZE; 775 return -EMSGSIZE;
765 } 776 }
766
767 /* Prepare each packet for sending, and add to relevant queue: */ 777 /* Prepare each packet for sending, and add to relevant queue: */
768 skb_queue_walk_safe(list, skb, tmp) { 778 skb_queue_walk_safe(list, skb, tmp) {
769 __skb_unlink(skb, list); 779 __skb_unlink(skb, list);
@@ -786,8 +796,10 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
786 if (tipc_msg_make_bundle(&skb, mtu, link->addr)) { 796 if (tipc_msg_make_bundle(&skb, mtu, link->addr)) {
787 link->stats.sent_bundled++; 797 link->stats.sent_bundled++;
788 link->stats.sent_bundles++; 798 link->stats.sent_bundles++;
799 imp = msg_importance(buf_msg(skb));
789 } 800 }
790 __skb_queue_tail(backlogq, skb); 801 __skb_queue_tail(backlogq, skb);
802 link->backlog[imp].len++;
791 seqno++; 803 seqno++;
792 } 804 }
793 link->next_out_no = seqno; 805 link->next_out_no = seqno;
@@ -914,6 +926,7 @@ void tipc_link_push_packets(struct tipc_link *link)
914 if (!skb) 926 if (!skb)
915 break; 927 break;
916 msg = buf_msg(skb); 928 msg = buf_msg(skb);
929 link->backlog[msg_importance(msg)].len--;
917 msg_set_ack(msg, ack); 930 msg_set_ack(msg, ack);
918 msg_set_bcast_ack(msg, link->owner->bclink.last_in); 931 msg_set_bcast_ack(msg, link->owner->bclink.last_in);
919 link->rcv_unacked = 0; 932 link->rcv_unacked = 0;
@@ -1610,6 +1623,7 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
1610 tipc_msg_init(link_own_addr(l_ptr), &tunnel_hdr, CHANGEOVER_PROTOCOL, 1623 tipc_msg_init(link_own_addr(l_ptr), &tunnel_hdr, CHANGEOVER_PROTOCOL,
1611 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); 1624 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
1612 skb_queue_splice_tail_init(&l_ptr->backlogq, &l_ptr->transmq); 1625 skb_queue_splice_tail_init(&l_ptr->backlogq, &l_ptr->transmq);
1626 tipc_link_purge_backlog(l_ptr);
1613 msgcount = skb_queue_len(&l_ptr->transmq); 1627 msgcount = skb_queue_len(&l_ptr->transmq);
1614 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 1628 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
1615 msg_set_msgcnt(&tunnel_hdr, msgcount); 1629 msg_set_msgcnt(&tunnel_hdr, msgcount);
@@ -1817,11 +1831,11 @@ void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1817 int max_bulk = TIPC_MAX_PUBLICATIONS / (l->max_pkt / ITEM_SIZE); 1831 int max_bulk = TIPC_MAX_PUBLICATIONS / (l->max_pkt / ITEM_SIZE);
1818 1832
1819 l->window = win; 1833 l->window = win;
1820 l->queue_limit[TIPC_LOW_IMPORTANCE] = win / 2; 1834 l->backlog[TIPC_LOW_IMPORTANCE].limit = win / 2;
1821 l->queue_limit[TIPC_MEDIUM_IMPORTANCE] = win; 1835 l->backlog[TIPC_MEDIUM_IMPORTANCE].limit = win;
1822 l->queue_limit[TIPC_HIGH_IMPORTANCE] = win / 2 * 3; 1836 l->backlog[TIPC_HIGH_IMPORTANCE].limit = win / 2 * 3;
1823 l->queue_limit[TIPC_CRITICAL_IMPORTANCE] = win * 2; 1837 l->backlog[TIPC_CRITICAL_IMPORTANCE].limit = win * 2;
1824 l->queue_limit[TIPC_SYSTEM_IMPORTANCE] = max_bulk; 1838 l->backlog[TIPC_SYSTEM_IMPORTANCE].limit = max_bulk;
1825} 1839}
1826 1840
1827/* tipc_link_find_owner - locate owner node of link by link's name 1841/* tipc_link_find_owner - locate owner node of link by link's name
@@ -2120,7 +2134,7 @@ static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
2120 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance)) 2134 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance))
2121 goto prop_msg_full; 2135 goto prop_msg_full;
2122 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, 2136 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN,
2123 link->queue_limit[TIPC_LOW_IMPORTANCE])) 2137 link->window))
2124 goto prop_msg_full; 2138 goto prop_msg_full;
2125 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority)) 2139 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
2126 goto prop_msg_full; 2140 goto prop_msg_full;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index eec3ecf2d450..99543a46095a 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -118,7 +118,7 @@ struct tipc_stats {
118 * @pmsg: convenience pointer to "proto_msg" field 118 * @pmsg: convenience pointer to "proto_msg" field
119 * @priority: current link priority 119 * @priority: current link priority
120 * @net_plane: current link network plane ('A' through 'H') 120 * @net_plane: current link network plane ('A' through 'H')
121 * @queue_limit: outbound message queue congestion thresholds (indexed by user) 121 * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
122 * @exp_msg_count: # of tunnelled messages expected during link changeover 122 * @exp_msg_count: # of tunnelled messages expected during link changeover
123 * @reset_checkpoint: seq # of last acknowledged message at time of link reset 123 * @reset_checkpoint: seq # of last acknowledged message at time of link reset
124 * @max_pkt: current maximum packet size for this link 124 * @max_pkt: current maximum packet size for this link
@@ -166,7 +166,6 @@ struct tipc_link {
166 struct tipc_msg *pmsg; 166 struct tipc_msg *pmsg;
167 u32 priority; 167 u32 priority;
168 char net_plane; 168 char net_plane;
169 u32 queue_limit[15]; /* queue_limit[0]==window limit */
170 169
171 /* Changeover */ 170 /* Changeover */
172 u32 exp_msg_count; 171 u32 exp_msg_count;
@@ -180,6 +179,10 @@ struct tipc_link {
180 /* Sending */ 179 /* Sending */
181 struct sk_buff_head transmq; 180 struct sk_buff_head transmq;
182 struct sk_buff_head backlogq; 181 struct sk_buff_head backlogq;
182 struct {
183 u16 len;
184 u16 limit;
185 } backlog[5];
183 u32 next_out_no; 186 u32 next_out_no;
184 u32 window; 187 u32 window;
185 u32 last_retransmitted; 188 u32 last_retransmitted;