Skip to content

Commit fda497e

Browse files
nxa22042davem330
authored andcommitted
Optimize sk_msg_clone() by data merge to end dst sg entry
Function sk_msg_clone has been modified to merge the data from source sg entry to destination sg entry if the cloned data resides in same page and is contiguous to the end entry of destination sk_msg. This improves kernel tls throughput to the tune of 10%. When the user space tls application calls sendmsg() with MSG_MORE, it leads to calling sk_msg_clone() with new data being cloned placed continuous to previously cloned data. Without this optimization, a new SG entry in the destination sk_msg i.e. rec->msg_plaintext in tls_clone_plaintext_msg() gets used. This leads to exhaustion of sg entries in rec->msg_plaintext even before a full 16K of allowable record data is accumulated. Hence we lose oppurtunity to encrypt and send a full 16K record. With this patch, the kernel tls can accumulate full 16K of record data irrespective of the size of data passed in sendmsg() with MSG_MORE. Signed-off-by: Vakul Garg <vakul.garg@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 4559dd2 commit fda497e

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

net/core/skmsg.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,9 @@ int sk_msg_clone(struct sock *sk, struct sk_msg *dst, struct sk_msg *src,
7878
{
7979
int i = src->sg.start;
8080
struct scatterlist *sge = sk_msg_elem(src, i);
81+
struct scatterlist *sgd = NULL;
8182
u32 sge_len, sge_off;
8283

83-
if (sk_msg_full(dst))
84-
return -ENOSPC;
85-
8684
while (off) {
8785
if (sge->length > off)
8886
break;
@@ -94,16 +92,27 @@ int sk_msg_clone(struct sock *sk, struct sk_msg *dst, struct sk_msg *src,
9492
}
9593

9694
while (len) {
97-
if (sk_msg_full(dst))
98-
return -ENOSPC;
99-
10095
sge_len = sge->length - off;
101-
sge_off = sge->offset + off;
10296
if (sge_len > len)
10397
sge_len = len;
98+
99+
if (dst->sg.end)
100+
sgd = sk_msg_elem(dst, dst->sg.end - 1);
101+
102+
if (sgd &&
103+
(sg_page(sge) == sg_page(sgd)) &&
104+
(sg_virt(sge) + off == sg_virt(sgd) + sgd->length)) {
105+
sgd->length += sge_len;
106+
dst->sg.size += sge_len;
107+
} else if (!sk_msg_full(dst)) {
108+
sge_off = sge->offset + off;
109+
sk_msg_page_add(dst, sg_page(sge), sge_len, sge_off);
110+
} else {
111+
return -ENOSPC;
112+
}
113+
104114
off = 0;
105115
len -= sge_len;
106-
sk_msg_page_add(dst, sg_page(sge), sge_len, sge_off);
107116
sk_mem_charge(sk, sge_len);
108117
sk_msg_iter_var_next(i);
109118
if (i == src->sg.end && len)

0 commit comments

Comments
 (0)