diff options
author | Doron Roberts-Kedes <doronrk@fb.com> | 2018-07-25 17:48:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-26 17:11:34 -0400 |
commit | 0a26cf3ff47d9e70fbed2fa79b0678ee70e25113 (patch) | |
tree | 2074e891ca6150854be948a07a4aa60d13ab3069 /net/tls | |
parent | 2ed9db3074fcd8d12709fe40ff0e691d74229818 (diff) |
tls: Skip zerocopy path for ITER_KVEC
The zerocopy path ultimately calls iov_iter_get_pages, which defines the
step function for ITER_KVECs as simply, return -EFAULT. Taking the
non-zerocopy path for ITER_KVECs avoids the unnecessary fallback.
See https://lore.kernel.org/lkml/20150401023311.GL29656@ZenIV.linux.org.uk/T/#u
for a discussion of why zerocopy for vmalloc data is not a good idea.
Discovered while testing NBD traffic encrypted with ktls.
Fixes: c46234ebb4d1 ("tls: RX path for ktls")
Signed-off-by: Doron Roberts-Kedes <doronrk@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tls')
-rw-r--r-- | net/tls/tls_sw.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 0687a7a4689f..f9971717f7e0 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
@@ -362,6 +362,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | |||
362 | int record_room; | 362 | int record_room; |
363 | bool full_record; | 363 | bool full_record; |
364 | int orig_size; | 364 | int orig_size; |
365 | bool is_kvec = msg->msg_iter.type & ITER_KVEC; | ||
365 | 366 | ||
366 | if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL)) | 367 | if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL)) |
367 | return -ENOTSUPP; | 368 | return -ENOTSUPP; |
@@ -410,8 +411,7 @@ alloc_encrypted: | |||
410 | try_to_copy -= required_size - ctx->sg_encrypted_size; | 411 | try_to_copy -= required_size - ctx->sg_encrypted_size; |
411 | full_record = true; | 412 | full_record = true; |
412 | } | 413 | } |
413 | 414 | if (!is_kvec && (full_record || eor)) { | |
414 | if (full_record || eor) { | ||
415 | ret = zerocopy_from_iter(sk, &msg->msg_iter, | 415 | ret = zerocopy_from_iter(sk, &msg->msg_iter, |
416 | try_to_copy, &ctx->sg_plaintext_num_elem, | 416 | try_to_copy, &ctx->sg_plaintext_num_elem, |
417 | &ctx->sg_plaintext_size, | 417 | &ctx->sg_plaintext_size, |
@@ -779,6 +779,7 @@ int tls_sw_recvmsg(struct sock *sk, | |||
779 | bool cmsg = false; | 779 | bool cmsg = false; |
780 | int target, err = 0; | 780 | int target, err = 0; |
781 | long timeo; | 781 | long timeo; |
782 | bool is_kvec = msg->msg_iter.type & ITER_KVEC; | ||
782 | 783 | ||
783 | flags |= nonblock; | 784 | flags |= nonblock; |
784 | 785 | ||
@@ -822,7 +823,7 @@ int tls_sw_recvmsg(struct sock *sk, | |||
822 | page_count = iov_iter_npages(&msg->msg_iter, | 823 | page_count = iov_iter_npages(&msg->msg_iter, |
823 | MAX_SKB_FRAGS); | 824 | MAX_SKB_FRAGS); |
824 | to_copy = rxm->full_len - tls_ctx->rx.overhead_size; | 825 | to_copy = rxm->full_len - tls_ctx->rx.overhead_size; |
825 | if (to_copy <= len && page_count < MAX_SKB_FRAGS && | 826 | if (!is_kvec && to_copy <= len && page_count < MAX_SKB_FRAGS && |
826 | likely(!(flags & MSG_PEEK))) { | 827 | likely(!(flags & MSG_PEEK))) { |
827 | struct scatterlist sgin[MAX_SKB_FRAGS + 1]; | 828 | struct scatterlist sgin[MAX_SKB_FRAGS + 1]; |
828 | int pages = 0; | 829 | int pages = 0; |