diff options
| -rw-r--r-- | include/net/sock.h | 2 | ||||
| -rw-r--r-- | net/core/sock.c | 27 | ||||
| -rw-r--r-- | net/tls/tls_sw.c | 4 |
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) | |||
| 2142 | bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); | 2142 | bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); |
| 2143 | 2143 | ||
| 2144 | int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg, | 2144 | int 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) | |||
| 2240 | EXPORT_SYMBOL(sk_page_frag_refill); | 2240 | EXPORT_SYMBOL(sk_page_frag_refill); |
| 2241 | 2241 | ||
| 2242 | int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg, | 2242 | int 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 | } |
| 2291 | out: | 2296 | out: |
| 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 | } |
| 2296 | EXPORT_SYMBOL(sk_alloc_sg); | 2301 | EXPORT_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 | ||
