aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sock.h2
-rw-r--r--net/core/sock.c27
-rw-r--r--net/tls/tls_sw.c4
3 files changed, 19 insertions, 14 deletions
diff --git a/include/net/sock.h b/include/net/sock.h
index 447150c51feb..b7c75e024e37 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2142,7 +2142,7 @@ static inline struct page_frag *sk_page_frag(struct sock *sk)
2142bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); 2142bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
2143 2143
2144int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg, 2144int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2145 int *sg_num_elem, unsigned int *sg_size, 2145 int sg_start, int *sg_curr, unsigned int *sg_size,
2146 int first_coalesce); 2146 int first_coalesce);
2147 2147
2148/* 2148/*
diff --git a/net/core/sock.c b/net/core/sock.c
index f68dff0d7bc4..4f92c2910200 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2240,19 +2240,20 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag)
2240EXPORT_SYMBOL(sk_page_frag_refill); 2240EXPORT_SYMBOL(sk_page_frag_refill);
2241 2241
2242int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg, 2242int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2243 int *sg_num_elem, unsigned int *sg_size, 2243 int sg_start, int *sg_curr_index, unsigned int *sg_curr_size,
2244 int first_coalesce) 2244 int first_coalesce)
2245{ 2245{
2246 int sg_curr = *sg_curr_index, use = 0, rc = 0;
2247 unsigned int size = *sg_curr_size;
2246 struct page_frag *pfrag; 2248 struct page_frag *pfrag;
2247 unsigned int size = *sg_size;
2248 int num_elem = *sg_num_elem, use = 0, rc = 0;
2249 struct scatterlist *sge; 2249 struct scatterlist *sge;
2250 unsigned int orig_offset;
2251 2250
2252 len -= size; 2251 len -= size;
2253 pfrag = sk_page_frag(sk); 2252 pfrag = sk_page_frag(sk);
2254 2253
2255 while (len > 0) { 2254 while (len > 0) {
2255 unsigned int orig_offset;
2256
2256 if (!sk_page_frag_refill(sk, pfrag)) { 2257 if (!sk_page_frag_refill(sk, pfrag)) {
2257 rc = -ENOMEM; 2258 rc = -ENOMEM;
2258 goto out; 2259 goto out;
@@ -2270,17 +2271,21 @@ int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2270 orig_offset = pfrag->offset; 2271 orig_offset = pfrag->offset;
2271 pfrag->offset += use; 2272 pfrag->offset += use;
2272 2273
2273 sge = sg + num_elem - 1; 2274 sge = sg + sg_curr - 1;
2274 if (num_elem > first_coalesce && sg_page(sg) == pfrag->page && 2275 if (sg_curr > first_coalesce && sg_page(sg) == pfrag->page &&
2275 sg->offset + sg->length == orig_offset) { 2276 sg->offset + sg->length == orig_offset) {
2276 sg->length += use; 2277 sg->length += use;
2277 } else { 2278 } else {
2278 sge++; 2279 sge = sg + sg_curr;
2279 sg_unmark_end(sge); 2280 sg_unmark_end(sge);
2280 sg_set_page(sge, pfrag->page, use, orig_offset); 2281 sg_set_page(sge, pfrag->page, use, orig_offset);
2281 get_page(pfrag->page); 2282 get_page(pfrag->page);
2282 ++num_elem; 2283 sg_curr++;
2283 if (num_elem == MAX_SKB_FRAGS) { 2284
2285 if (sg_curr == MAX_SKB_FRAGS)
2286 sg_curr = 0;
2287
2288 if (sg_curr == sg_start) {
2284 rc = -ENOSPC; 2289 rc = -ENOSPC;
2285 break; 2290 break;
2286 } 2291 }
@@ -2289,8 +2294,8 @@ int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
2289 len -= use; 2294 len -= use;
2290 } 2295 }
2291out: 2296out:
2292 *sg_size = size; 2297 *sg_curr_size = size;
2293 *sg_num_elem = num_elem; 2298 *sg_curr_index = sg_curr;
2294 return rc; 2299 return rc;
2295} 2300}
2296EXPORT_SYMBOL(sk_alloc_sg); 2301EXPORT_SYMBOL(sk_alloc_sg);
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 0fc8a24c6473..057a558ed6d7 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -94,7 +94,7 @@ static int alloc_encrypted_sg(struct sock *sk, int len)
94 int rc = 0; 94 int rc = 0;
95 95
96 rc = sk_alloc_sg(sk, len, 96 rc = sk_alloc_sg(sk, len,
97 ctx->sg_encrypted_data, 97 ctx->sg_encrypted_data, 0,
98 &ctx->sg_encrypted_num_elem, 98 &ctx->sg_encrypted_num_elem,
99 &ctx->sg_encrypted_size, 0); 99 &ctx->sg_encrypted_size, 0);
100 100
@@ -107,7 +107,7 @@ static int alloc_plaintext_sg(struct sock *sk, int len)
107 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx); 107 struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
108 int rc = 0; 108 int rc = 0;
109 109
110 rc = sk_alloc_sg(sk, len, ctx->sg_plaintext_data, 110 rc = sk_alloc_sg(sk, len, ctx->sg_plaintext_data, 0,
111 &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size, 111 &ctx->sg_plaintext_num_elem, &ctx->sg_plaintext_size,
112 tls_ctx->pending_open_record_frags); 112 tls_ctx->pending_open_record_frags);
113 113