aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-03-13 16:08:11 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-14 14:38:32 -0400
commite3eea1eb47ac616ee09cf0ae5d1e7790ef8461ea (patch)
tree8d940842c102ed18354bc51ef64598374deb893c /net/tipc
parent05dcc5aa4dcced4f59f925625cea669e82b75519 (diff)
tipc: clean up handling of message priorities
Messages transferred by TIPC are assigned an "importance priority", -an integer value indicating how to treat the message when there is link or destination socket congestion. There is no separate header field for this value. Instead, the message user values have been chosen in ascending order according to perceived importance, so that the message user field can be used for this. This is not a good solution. First, we have many more users than the needed priority levels, so we end up with treating more priority levels than necessary. Second, the user field cannot always accurately reflect the priority of the message. E.g., a message fragment packet should really have the priority of the enveloped user data message, and not the priority of the MSG_FRAGMENTER user. Until now, we have been working around this problem in different ways, but it is now time to implement a consistent way of handling such priorities, although still within the constraint that we cannot allocate any more bits in the regular data message header for this. In this commit, we define a new priority level, TIPC_SYSTEM_IMPORTANCE, that will be the only one used apart from the four (lower) user data levels. All non-data messages map down to this priority. Furthermore, we take some free bits from the MSG_FRAGMENTER header and allocate them to store the priority of the enveloped message. We then adjust the functions msg_importance()/msg_set_importance() so that they read/set the correct header fields depending on user type. This small protocol change is fully compatible, because the code at the receiving end of a link currently reads the importance level only from user data messages, where there is no change. Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c1
-rw-r--r--net/tipc/link.c40
-rw-r--r--net/tipc/msg.c5
-rw-r--r--net/tipc/msg.h65
4 files changed, 50 insertions, 61 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 17cb0ff5f344..5aff0844d4d3 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -383,7 +383,6 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
383 __skb_queue_purge(list); 383 __skb_queue_purge(list);
384 return -EHOSTUNREACH; 384 return -EHOSTUNREACH;
385 } 385 }
386
387 /* Broadcast to all nodes */ 386 /* Broadcast to all nodes */
388 if (likely(bclink)) { 387 if (likely(bclink)) {
389 tipc_bclink_lock(net); 388 tipc_bclink_lock(net);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7e0036f5a364..bc49120bfb44 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -35,6 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "subscr.h"
38#include "link.h" 39#include "link.h"
39#include "bcast.h" 40#include "bcast.h"
40#include "socket.h" 41#include "socket.h"
@@ -305,12 +306,10 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
305 msg_set_session(msg, (tn->random & 0xffff)); 306 msg_set_session(msg, (tn->random & 0xffff));
306 msg_set_bearer_id(msg, b_ptr->identity); 307 msg_set_bearer_id(msg, b_ptr->identity);
307 strcpy((char *)msg_data(msg), if_name); 308 strcpy((char *)msg_data(msg), if_name);
308
309 l_ptr->priority = b_ptr->priority;
310 tipc_link_set_queue_limits(l_ptr, b_ptr->window);
311
312 l_ptr->net_plane = b_ptr->net_plane; 309 l_ptr->net_plane = b_ptr->net_plane;
313 link_init_max_pkt(l_ptr); 310 link_init_max_pkt(l_ptr);
311 l_ptr->priority = b_ptr->priority;
312 tipc_link_set_queue_limits(l_ptr, b_ptr->window);
314 313
315 l_ptr->next_out_no = 1; 314 l_ptr->next_out_no = 1;
316 __skb_queue_head_init(&l_ptr->transmq); 315 __skb_queue_head_init(&l_ptr->transmq);
@@ -708,7 +707,7 @@ static int tipc_link_cong(struct tipc_link *link, struct sk_buff_head *list)
708{ 707{
709 struct sk_buff *skb = skb_peek(list); 708 struct sk_buff *skb = skb_peek(list);
710 struct tipc_msg *msg = buf_msg(skb); 709 struct tipc_msg *msg = buf_msg(skb);
711 uint imp = tipc_msg_tot_importance(msg); 710 int imp = msg_importance(msg);
712 u32 oport = msg_tot_origport(msg); 711 u32 oport = msg_tot_origport(msg);
713 712
714 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) { 713 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
@@ -745,7 +744,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
745{ 744{
746 struct tipc_msg *msg = buf_msg(skb_peek(list)); 745 struct tipc_msg *msg = buf_msg(skb_peek(list));
747 unsigned int maxwin = link->window; 746 unsigned int maxwin = link->window;
748 uint imp = tipc_msg_tot_importance(msg); 747 unsigned int imp = msg_importance(msg);
749 uint mtu = link->max_pkt; 748 uint mtu = link->max_pkt;
750 uint ack = mod(link->next_in_no - 1); 749 uint ack = mod(link->next_in_no - 1);
751 uint seqno = link->next_out_no; 750 uint seqno = link->next_out_no;
@@ -755,7 +754,7 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
755 struct sk_buff_head *backlogq = &link->backlogq; 754 struct sk_buff_head *backlogq = &link->backlogq;
756 struct sk_buff *skb, *tmp; 755 struct sk_buff *skb, *tmp;
757 756
758 /* Match queue limits against msg importance: */ 757 /* Match queue limit against msg importance: */
759 if (unlikely(skb_queue_len(backlogq) >= link->queue_limit[imp])) 758 if (unlikely(skb_queue_len(backlogq) >= link->queue_limit[imp]))
760 return tipc_link_cong(link, list); 759 return tipc_link_cong(link, list);
761 760
@@ -1811,25 +1810,16 @@ static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol)
1811 l_ptr->abort_limit = tol / (jiffies_to_msecs(l_ptr->cont_intv) / 4); 1810 l_ptr->abort_limit = tol / (jiffies_to_msecs(l_ptr->cont_intv) / 4);
1812} 1811}
1813 1812
1814void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window) 1813void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1815{ 1814{
1816 l_ptr->window = window; 1815 int max_bulk = TIPC_MAX_PUBLICATIONS / (l->max_pkt / ITEM_SIZE);
1817 1816
1818 /* Data messages from this node, inclusive FIRST_FRAGM */ 1817 l->window = win;
1819 l_ptr->queue_limit[TIPC_LOW_IMPORTANCE] = window; 1818 l->queue_limit[TIPC_LOW_IMPORTANCE] = win / 2;
1820 l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE] = (window / 3) * 4; 1819 l->queue_limit[TIPC_MEDIUM_IMPORTANCE] = win;
1821 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE] = (window / 3) * 5; 1820 l->queue_limit[TIPC_HIGH_IMPORTANCE] = win / 2 * 3;
1822 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE] = (window / 3) * 6; 1821 l->queue_limit[TIPC_CRITICAL_IMPORTANCE] = win * 2;
1823 /* Transiting data messages,inclusive FIRST_FRAGM */ 1822 l->queue_limit[TIPC_SYSTEM_IMPORTANCE] = max_bulk;
1824 l_ptr->queue_limit[TIPC_LOW_IMPORTANCE + 4] = 300;
1825 l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE + 4] = 600;
1826 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
1827 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
1828 l_ptr->queue_limit[CONN_MANAGER] = 1200;
1829 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
1830 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
1831 /* FRAGMENT and LAST_FRAGMENT packets */
1832 l_ptr->queue_limit[MSG_FRAGMENTER] = 4000;
1833} 1823}
1834 1824
1835/* tipc_link_find_owner - locate owner node of link by link's name 1825/* tipc_link_find_owner - locate owner node of link by link's name
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 47c8fd8e2fb2..0c6dad8180a0 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -272,6 +272,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
272 FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr)); 272 FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr));
273 msg_set_size(&pkthdr, pktmax); 273 msg_set_size(&pkthdr, pktmax);
274 msg_set_fragm_no(&pkthdr, pktno); 274 msg_set_fragm_no(&pkthdr, pktno);
275 msg_set_importance(&pkthdr, msg_importance(mhdr));
275 276
276 /* Prepare first fragment */ 277 /* Prepare first fragment */
277 skb = tipc_buf_acquire(pktmax); 278 skb = tipc_buf_acquire(pktmax);
@@ -467,7 +468,6 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
467 int err) 468 int err)
468{ 469{
469 struct tipc_msg *msg = buf_msg(buf); 470 struct tipc_msg *msg = buf_msg(buf);
470 uint imp = msg_importance(msg);
471 struct tipc_msg ohdr; 471 struct tipc_msg ohdr;
472 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); 472 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
473 473
@@ -479,9 +479,6 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
479 if (msg_errcode(msg)) 479 if (msg_errcode(msg))
480 goto exit; 480 goto exit;
481 memcpy(&ohdr, msg, msg_hdr_sz(msg)); 481 memcpy(&ohdr, msg, msg_hdr_sz(msg));
482 imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
483 if (msg_isdata(msg))
484 msg_set_importance(msg, imp);
485 msg_set_errcode(msg, err); 482 msg_set_errcode(msg, err);
486 msg_set_origport(msg, msg_destport(&ohdr)); 483 msg_set_origport(msg, msg_destport(&ohdr));
487 msg_set_destport(msg, msg_origport(&ohdr)); 484 msg_set_destport(msg, msg_origport(&ohdr));
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index e5fc5fdb2ea7..bd3969a80dd4 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -54,6 +54,8 @@ struct plist;
54 * - TIPC_HIGH_IMPORTANCE 54 * - TIPC_HIGH_IMPORTANCE
55 * - TIPC_CRITICAL_IMPORTANCE 55 * - TIPC_CRITICAL_IMPORTANCE
56 */ 56 */
57#define TIPC_SYSTEM_IMPORTANCE 4
58
57 59
58/* 60/*
59 * Payload message types 61 * Payload message types
@@ -64,6 +66,19 @@ struct plist;
64#define TIPC_DIRECT_MSG 3 66#define TIPC_DIRECT_MSG 3
65 67
66/* 68/*
69 * Internal message users
70 */
71#define BCAST_PROTOCOL 5
72#define MSG_BUNDLER 6
73#define LINK_PROTOCOL 7
74#define CONN_MANAGER 8
75#define CHANGEOVER_PROTOCOL 10
76#define NAME_DISTRIBUTOR 11
77#define MSG_FRAGMENTER 12
78#define LINK_CONFIG 13
79#define SOCK_WAKEUP 14 /* pseudo user */
80
81/*
67 * Message header sizes 82 * Message header sizes
68 */ 83 */
69#define SHORT_H_SIZE 24 /* In-cluster basic payload message */ 84#define SHORT_H_SIZE 24 /* In-cluster basic payload message */
@@ -170,16 +185,6 @@ static inline void msg_set_user(struct tipc_msg *m, u32 n)
170 msg_set_bits(m, 0, 25, 0xf, n); 185 msg_set_bits(m, 0, 25, 0xf, n);
171} 186}
172 187
173static inline u32 msg_importance(struct tipc_msg *m)
174{
175 return msg_bits(m, 0, 25, 0xf);
176}
177
178static inline void msg_set_importance(struct tipc_msg *m, u32 i)
179{
180 msg_set_user(m, i);
181}
182
183static inline u32 msg_hdr_sz(struct tipc_msg *m) 188static inline u32 msg_hdr_sz(struct tipc_msg *m)
184{ 189{
185 return msg_bits(m, 0, 21, 0xf) << 2; 190 return msg_bits(m, 0, 21, 0xf) << 2;
@@ -336,6 +341,25 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
336/* 341/*
337 * Words 3-10 342 * Words 3-10
338 */ 343 */
344static inline u32 msg_importance(struct tipc_msg *m)
345{
346 if (unlikely(msg_user(m) == MSG_FRAGMENTER))
347 return msg_bits(m, 5, 13, 0x7);
348 if (likely(msg_isdata(m) && !msg_errcode(m)))
349 return msg_user(m);
350 return TIPC_SYSTEM_IMPORTANCE;
351}
352
353static inline void msg_set_importance(struct tipc_msg *m, u32 i)
354{
355 if (unlikely(msg_user(m) == MSG_FRAGMENTER))
356 msg_set_bits(m, 5, 13, 0x7, i);
357 else if (likely(i < TIPC_SYSTEM_IMPORTANCE))
358 msg_set_user(m, i);
359 else
360 pr_warn("Trying to set illegal importance in message\n");
361}
362
339static inline u32 msg_prevnode(struct tipc_msg *m) 363static inline u32 msg_prevnode(struct tipc_msg *m)
340{ 364{
341 return msg_word(m, 3); 365 return msg_word(m, 3);
@@ -458,20 +482,6 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
458 */ 482 */
459 483
460/* 484/*
461 * Internal message users
462 */
463#define BCAST_PROTOCOL 5
464#define MSG_BUNDLER 6
465#define LINK_PROTOCOL 7
466#define CONN_MANAGER 8
467#define ROUTE_DISTRIBUTOR 9 /* obsoleted */
468#define CHANGEOVER_PROTOCOL 10
469#define NAME_DISTRIBUTOR 11
470#define MSG_FRAGMENTER 12
471#define LINK_CONFIG 13
472#define SOCK_WAKEUP 14 /* pseudo user */
473
474/*
475 * Connection management protocol message types 485 * Connection management protocol message types
476 */ 486 */
477#define CONN_PROBE 0 487#define CONN_PROBE 0
@@ -743,13 +753,6 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
743 msg_set_bits(m, 9, 0, 0xffff, n); 753 msg_set_bits(m, 9, 0, 0xffff, n);
744} 754}
745 755
746static inline u32 tipc_msg_tot_importance(struct tipc_msg *m)
747{
748 if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))
749 return msg_importance(msg_get_wrapped(m));
750 return msg_importance(m);
751}
752
753static inline u32 msg_tot_origport(struct tipc_msg *m) 756static inline u32 msg_tot_origport(struct tipc_msg *m)
754{ 757{
755 if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT)) 758 if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))