Skip to content

Commit bb7f5d9

Browse files
author
Andreas Gruenbacher
committed
gfs2: Fix should_fault_in_pages() logic
Fix the fault-in window size logic: * Use a maximum window size of 1 MiB instead of BIO_MAX_VECS * PAGE_SIZE. The previous window size was always one page because the pages variable was accidentally being defined and then redefined in should_fault_in_pages(). * The nr_dirtied heuristic for guessing when there might be memory pressure often results in very small window sizes. Don't let nr_dirtied drop below 8 pages (as btrfs does). * Compute the window size in units of bytes, not pages. * Account for page overlap (unaligned iterators). Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent b296393 commit bb7f5d9

1 file changed

Lines changed: 9 additions & 8 deletions

File tree

fs/gfs2/file.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,7 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
775775
size_t *window_size)
776776
{
777777
size_t count = iov_iter_count(i);
778-
char __user *p;
779-
int pages = 1;
778+
size_t size, offs;
780779

781780
if (likely(!count))
782781
return false;
@@ -785,18 +784,20 @@ static inline bool should_fault_in_pages(ssize_t ret, struct iov_iter *i,
785784
if (!iter_is_iovec(i))
786785
return false;
787786

787+
size = PAGE_SIZE;
788+
offs = offset_in_page(i->iov[0].iov_base + i->iov_offset);
788789
if (*prev_count != count || !*window_size) {
789-
int pages, nr_dirtied;
790+
size_t nr_dirtied;
790791

791-
pages = min_t(int, BIO_MAX_VECS, DIV_ROUND_UP(count, PAGE_SIZE));
792+
size = ALIGN(offs + count, PAGE_SIZE);
793+
size = min_t(size_t, size, SZ_1M);
792794
nr_dirtied = max(current->nr_dirtied_pause -
793-
current->nr_dirtied, 1);
794-
pages = min(pages, nr_dirtied);
795+
current->nr_dirtied, 8);
796+
size = min(size, nr_dirtied << PAGE_SHIFT);
795797
}
796798

797799
*prev_count = count;
798-
p = i->iov[0].iov_base + i->iov_offset;
799-
*window_size = (size_t)PAGE_SIZE * pages - offset_in_page(p);
800+
*window_size = size - offs;
800801
return true;
801802
}
802803

0 commit comments

Comments
 (0)