aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-03-13 16:08:07 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-14 14:38:32 -0400
commit1149557d64c97dc9adf3103347a1c0e8c06d3b89 (patch)
tree1253880332cf983760ba27a157f6b77aa11859e4 /net/tipc/msg.c
parentcf2157f88a5abf1a64b8c51a737a35e918dc67e5 (diff)
tipc: eliminate unnecessary linearization of incoming buffers
Currently, TIPC linearizes all incoming buffers directly at reception before passing them upwards in the stack. This is clearly a waste of CPU resources, and must be avoided. In this commit, we eliminate this unnecessary linearization. We still ensure that at least the message header is linear, and that the buffer is linearized where this is still needed, i.e. when unbundling and when reversing messages. In addition, we ensure that fragmented messages are validated after reassembly before delivering them upwards in the stack. Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 4a64caf6fa20..ff8c64cd1cd9 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -165,6 +165,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
165 } 165 }
166 166
167 if (fragid == LAST_FRAGMENT) { 167 if (fragid == LAST_FRAGMENT) {
168 TIPC_SKB_CB(head)->validated = false;
169 if (unlikely(!tipc_msg_validate(head)))
170 goto err;
168 *buf = head; 171 *buf = head;
169 TIPC_SKB_CB(head)->tail = NULL; 172 TIPC_SKB_CB(head)->tail = NULL;
170 *headbuf = NULL; 173 *headbuf = NULL;
@@ -172,7 +175,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
172 } 175 }
173 *buf = NULL; 176 *buf = NULL;
174 return 0; 177 return 0;
175
176err: 178err:
177 pr_warn_ratelimited("Unable to build fragment list\n"); 179 pr_warn_ratelimited("Unable to build fragment list\n");
178 kfree_skb(*buf); 180 kfree_skb(*buf);
@@ -378,10 +380,14 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu)
378 */ 380 */
379bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos) 381bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)
380{ 382{
381 struct tipc_msg *msg = buf_msg(skb); 383 struct tipc_msg *msg;
382 int imsz; 384 int imsz;
383 struct tipc_msg *imsg = (struct tipc_msg *)(msg_data(msg) + *pos); 385 struct tipc_msg *imsg;
384 386
387 if (unlikely(skb_linearize(skb)))
388 return false;
389 msg = buf_msg(skb);
390 imsg = (struct tipc_msg *)(msg_data(msg) + *pos);
385 /* Is there space left for shortest possible message? */ 391 /* Is there space left for shortest possible message? */
386 if (*pos > (msg_data_sz(msg) - SHORT_H_SIZE)) 392 if (*pos > (msg_data_sz(msg) - SHORT_H_SIZE))
387 goto none; 393 goto none;
@@ -463,11 +469,11 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
463 469
464 if (skb_linearize(buf)) 470 if (skb_linearize(buf))
465 goto exit; 471 goto exit;
472 msg = buf_msg(buf);
466 if (msg_dest_droppable(msg)) 473 if (msg_dest_droppable(msg))
467 goto exit; 474 goto exit;
468 if (msg_errcode(msg)) 475 if (msg_errcode(msg))
469 goto exit; 476 goto exit;
470
471 memcpy(&ohdr, msg, msg_hdr_sz(msg)); 477 memcpy(&ohdr, msg, msg_hdr_sz(msg));
472 imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE); 478 imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
473 if (msg_isdata(msg)) 479 if (msg_isdata(msg))