Commit 69ca9293 authored by Dave Watson's avatar Dave Watson Committed by David S. Miller

tls: Generalize zerocopy_from_iter

Refactor zerocopy_from_iter to take arguments for pages and size,
such that it can be used for both tx and rx. RX will also support
zerocopy direct to output iter, as long as the full message can
be copied at once (a large enough userspace buffer was provided).
Signed-off-by: default avatarDave Watson <davejwatson@fb.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ae06c70b
...@@ -226,23 +226,24 @@ static int tls_sw_push_pending_record(struct sock *sk, int flags) ...@@ -226,23 +226,24 @@ static int tls_sw_push_pending_record(struct sock *sk, int flags)
} }
static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from, static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
int length) int length, int *pages_used,
unsigned int *size_used,
struct scatterlist *to, int to_max_pages,
bool charge)
{ {
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
struct page *pages[MAX_SKB_FRAGS]; struct page *pages[MAX_SKB_FRAGS];
size_t offset; size_t offset;
ssize_t copied, use; ssize_t copied, use;
int i = 0; int i = 0;
unsigned int size = ctx->sg_plaintext_size; unsigned int size = *size_used;
int num_elem = ctx->sg_plaintext_num_elem; int num_elem = *pages_used;
int rc = 0; int rc = 0;
int maxpages; int maxpages;
while (length > 0) { while (length > 0) {
i = 0; i = 0;
maxpages = ARRAY_SIZE(ctx->sg_plaintext_data) - num_elem; maxpages = to_max_pages - num_elem;
if (maxpages == 0) { if (maxpages == 0) {
rc = -EFAULT; rc = -EFAULT;
goto out; goto out;
...@@ -262,10 +263,11 @@ static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from, ...@@ -262,10 +263,11 @@ static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
while (copied) { while (copied) {
use = min_t(int, copied, PAGE_SIZE - offset); use = min_t(int, copied, PAGE_SIZE - offset);
sg_set_page(&ctx->sg_plaintext_data[num_elem], sg_set_page(&to[num_elem],
pages[i], use, offset); pages[i], use, offset);
sg_unmark_end(&ctx->sg_plaintext_data[num_elem]); sg_unmark_end(&to[num_elem]);
sk_mem_charge(sk, use); if (charge)
sk_mem_charge(sk, use);
offset = 0; offset = 0;
copied -= use; copied -= use;
...@@ -276,8 +278,9 @@ static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from, ...@@ -276,8 +278,9 @@ static int zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
} }
out: out:
ctx->sg_plaintext_size = size; *size_used = size;
ctx->sg_plaintext_num_elem = num_elem; *pages_used = num_elem;
return rc; return rc;
} }
...@@ -374,7 +377,11 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) ...@@ -374,7 +377,11 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
if (full_record || eor) { if (full_record || eor) {
ret = zerocopy_from_iter(sk, &msg->msg_iter, ret = zerocopy_from_iter(sk, &msg->msg_iter,
try_to_copy); try_to_copy, &ctx->sg_plaintext_num_elem,
&ctx->sg_plaintext_size,
ctx->sg_plaintext_data,
ARRAY_SIZE(ctx->sg_plaintext_data),
true);
if (ret) if (ret)
goto fallback_to_reg_send; goto fallback_to_reg_send;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment