diff mbox series

[RFC,net-next,3/6] iov_iter: Add a nocache copy iov iterator

Message ID 1652241268-46732-4-git-send-email-jdamato@fastly.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series Nontemporal copies in unix socket write path | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 14677 this patch: 14573
netdev/cc_maintainers success CCed 1 of 1 maintainers
netdev/build_clang success Errors and warnings before: 2392 this patch: 2392
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 14568 this patch: 14568
netdev/checkpatch warning CHECK: Alignment should match open parenthesis CHECK: Unbalanced braces around else statement WARNING: line length of 82 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Joe Damato May 11, 2022, 3:54 a.m. UTC
Add copy_page_from_iter_nocache, which wraps copy_page_from_iter_iovec and
passes in a custom copyin function: __copy_from_user_nocache.

This allows callers of copy_page_from_iter_nocache to copy data without
disturbing the CPU cache.

Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 include/linux/uio.h |  2 ++
 lib/iov_iter.c      | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/uio.h b/include/linux/uio.h
index 739285f..58c7946 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -142,6 +142,8 @@  size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
 			 struct iov_iter *i);
 size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
 			 struct iov_iter *i);
+size_t copy_page_from_iter_nocache(struct page *page, size_t offset, size_t bytes,
+			 struct iov_iter *i);
 
 size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i);
 size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i);
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index ef22ec1..985bf58 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -895,6 +895,26 @@  size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
 }
 EXPORT_SYMBOL(copy_page_to_iter);
 
+size_t copy_page_from_iter_nocache(struct page *page, size_t offset, size_t
+		bytes, struct iov_iter *i)
+{
+	if (unlikely(!page_copy_sane(page, offset, bytes)))
+		return 0;
+	if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) {
+		WARN_ON(1);
+		return 0;
+	}
+	if (iov_iter_is_bvec(i) || iov_iter_is_kvec(i) || iov_iter_is_xarray(i)) {
+		void *kaddr = kmap_atomic(page);
+		size_t wanted = _copy_from_iter_nocache(kaddr + offset, bytes, i);
+
+		kunmap_atomic(kaddr);
+		return wanted;
+	} else
+		return copy_page_from_iter_iovec(page, offset, bytes, i,
+				__copy_from_user_nocache);
+}
+
 size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
 			 struct iov_iter *i)
 {