Skip to content

Commit 1149557

Browse files
Jon Paul Maloydavem330
authored andcommitted
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 <[email protected]> Reviewed-by: Ying Xue <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cf2157f commit 1149557

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

net/tipc/link.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,13 +1075,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
10751075
if (unlikely(!tipc_msg_validate(skb)))
10761076
goto discard;
10771077

1078-
/* Ensure message data is a single contiguous unit */
1079-
if (unlikely(skb_linearize(skb)))
1080-
goto discard;
1081-
10821078
/* Handle arrival of a non-unicast link message */
10831079
msg = buf_msg(skb);
1084-
10851080
if (unlikely(msg_non_seq(msg))) {
10861081
if (msg_user(msg) == LINK_CONFIG)
10871082
tipc_disc_rcv(net, skb, b_ptr);

net/tipc/msg.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,16 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
165165
}
166166

167167
if (fragid == LAST_FRAGMENT) {
168+
TIPC_SKB_CB(head)->validated = false;
169+
if (unlikely(!tipc_msg_validate(head)))
170+
goto err;
168171
*buf = head;
169172
TIPC_SKB_CB(head)->tail = NULL;
170173
*headbuf = NULL;
171174
return 1;
172175
}
173176
*buf = NULL;
174177
return 0;
175-
176178
err:
177179
pr_warn_ratelimited("Unable to build fragment list\n");
178180
kfree_skb(*buf);
@@ -378,10 +380,14 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu)
378380
*/
379381
bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)
380382
{
381-
struct tipc_msg *msg = buf_msg(skb);
383+
struct tipc_msg *msg;
382384
int imsz;
383-
struct tipc_msg *imsg = (struct tipc_msg *)(msg_data(msg) + *pos);
385+
struct tipc_msg *imsg;
384386

387+
if (unlikely(skb_linearize(skb)))
388+
return false;
389+
msg = buf_msg(skb);
390+
imsg = (struct tipc_msg *)(msg_data(msg) + *pos);
385391
/* Is there space left for shortest possible message? */
386392
if (*pos > (msg_data_sz(msg) - SHORT_H_SIZE))
387393
goto none;
@@ -463,11 +469,11 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
463469

464470
if (skb_linearize(buf))
465471
goto exit;
472+
msg = buf_msg(buf);
466473
if (msg_dest_droppable(msg))
467474
goto exit;
468475
if (msg_errcode(msg))
469476
goto exit;
470-
471477
memcpy(&ohdr, msg, msg_hdr_sz(msg));
472478
imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
473479
if (msg_isdata(msg))

0 commit comments

Comments
 (0)