Commit 1149557d64c97dc9adf3103347a1c0e8c06d3b89
Committed by
David S. Miller
1 parent
cf2157f88a
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>
Showing 2 changed files with 10 additions and 9 deletions Side-by-side Diff
net/tipc/link.c
... | ... | @@ -1075,13 +1075,8 @@ |
1075 | 1075 | if (unlikely(!tipc_msg_validate(skb))) |
1076 | 1076 | goto discard; |
1077 | 1077 | |
1078 | - /* Ensure message data is a single contiguous unit */ | |
1079 | - if (unlikely(skb_linearize(skb))) | |
1080 | - goto discard; | |
1081 | - | |
1082 | 1078 | /* Handle arrival of a non-unicast link message */ |
1083 | 1079 | msg = buf_msg(skb); |
1084 | - | |
1085 | 1080 | if (unlikely(msg_non_seq(msg))) { |
1086 | 1081 | if (msg_user(msg) == LINK_CONFIG) |
1087 | 1082 | tipc_disc_rcv(net, skb, b_ptr); |
net/tipc/msg.c
... | ... | @@ -165,6 +165,9 @@ |
165 | 165 | } |
166 | 166 | |
167 | 167 | if (fragid == LAST_FRAGMENT) { |
168 | + TIPC_SKB_CB(head)->validated = false; | |
169 | + if (unlikely(!tipc_msg_validate(head))) | |
170 | + goto err; | |
168 | 171 | *buf = head; |
169 | 172 | TIPC_SKB_CB(head)->tail = NULL; |
170 | 173 | *headbuf = NULL; |
... | ... | @@ -172,7 +175,6 @@ |
172 | 175 | } |
173 | 176 | *buf = NULL; |
174 | 177 | return 0; |
175 | - | |
176 | 178 | err: |
177 | 179 | pr_warn_ratelimited("Unable to build fragment list\n"); |
178 | 180 | kfree_skb(*buf); |
179 | 181 | |
180 | 182 | |
... | ... | @@ -378,10 +380,14 @@ |
378 | 380 | */ |
379 | 381 | bool 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 | 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 | 391 | /* Is there space left for shortest possible message? */ |
386 | 392 | if (*pos > (msg_data_sz(msg) - SHORT_H_SIZE)) |
387 | 393 | goto none; |
388 | 394 | |
... | ... | @@ -463,11 +469,11 @@ |
463 | 469 | |
464 | 470 | if (skb_linearize(buf)) |
465 | 471 | goto exit; |
472 | + msg = buf_msg(buf); | |
466 | 473 | if (msg_dest_droppable(msg)) |
467 | 474 | goto exit; |
468 | 475 | if (msg_errcode(msg)) |
469 | 476 | goto exit; |
470 | - | |
471 | 477 | memcpy(&ohdr, msg, msg_hdr_sz(msg)); |
472 | 478 | imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE); |
473 | 479 | if (msg_isdata(msg)) |