summaryrefslogtreecommitdiffstats
path: root/lib/iov_iter.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-02-26 13:42:39 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2019-02-26 14:05:20 -0500
commit6daef95b8c914866a46247232a048447fff97279 (patch)
tree086688168650fe491deae0da957307c337bc26c5 /lib/iov_iter.c
parent77000bc43da17d5d6bc4ebfaf44d52d43bb69492 (diff)
iov_iter: optimize page_copy_sane()
Avoid cache line miss dereferencing struct page if we can. page_copy_sane() mostly deals with order-0 pages. Extra cache line miss is visible on TCP recvmsg() calls dealing with GRO packets (typically 45 page frags are attached to one skb). Bringing the 45 struct pages into cpu cache while copying the data is not free, since the freeing of the skb (and associated page frags put_page()) can happen after cache lines have been evicted. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r--lib/iov_iter.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index be4bd627caf0..ea36dc355da1 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -861,8 +861,21 @@ EXPORT_SYMBOL(_copy_from_iter_full_nocache);
861 861
862static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) 862static inline bool page_copy_sane(struct page *page, size_t offset, size_t n)
863{ 863{
864 struct page *head = compound_head(page); 864 struct page *head;
865 size_t v = n + offset + page_address(page) - page_address(head); 865 size_t v = n + offset;
866
867 /*
868 * The general case needs to access the page order in order
869 * to compute the page size.
870 * However, we mostly deal with order-0 pages and thus can
871 * avoid a possible cache line miss for requests that fit all
872 * page orders.
873 */
874 if (n <= v && v <= PAGE_SIZE)
875 return true;
876
877 head = compound_head(page);
878 v += (page - head) << PAGE_SHIFT;
866 879
867 if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) 880 if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head))))
868 return true; 881 return true;