Skip to content

Commit 0ceb13c

Browse files
Matthew WilcoxMichal Hocko
authored andcommitted
mm: tighten up the fault path a little
The round_up() macro generates a couple of unnecessary instructions in this usage: 48cd: 49 8b 47 50 mov 0x50(%r15),%rax 48d1: 48 83 e8 01 sub $0x1,%rax 48d5: 48 0d ff 0f 00 00 or $0xfff,%rax 48db: 48 83 c0 01 add $0x1,%rax 48df: 48 c1 f8 0c sar $0xc,%rax 48e3: 48 39 c3 cmp %rax,%rbx 48e6: 72 2e jb 4916 <filemap_fault+0x96> If we change round_up() to ((x) + __round_mask(x, y)) & ~__round_mask(x, y) then GCC can see through it and remove the mask (because that would be dead code given the subsequent shift): 48cd: 49 8b 47 50 mov 0x50(%r15),%rax 48d1: 48 05 ff 0f 00 00 add $0xfff,%rax 48d7: 48 c1 e8 0c shr $0xc,%rax 48db: 48 39 c3 cmp %rax,%rbx 48de: 72 2e jb 490e <filemap_fault+0x8e> But that's problematic because we'd evaluate 'y' twice. Converting round_up into an inline function prevents it from being used in other definitions. The easiest thing to do is just change these three usages of round_up to use DIV_ROUND_UP. Also add an unlikely() because GCC's heuristic is wrong in this case. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 3c93cb0 commit 0ceb13c

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

mm/filemap.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,12 +2201,12 @@ int filemap_fault(struct vm_fault *vmf)
22012201
struct file_ra_state *ra = &file->f_ra;
22022202
struct inode *inode = mapping->host;
22032203
pgoff_t offset = vmf->pgoff;
2204+
pgoff_t max_off;
22042205
struct page *page;
2205-
loff_t size;
22062206
int ret = 0;
22072207

2208-
size = round_up(i_size_read(inode), PAGE_SIZE);
2209-
if (offset >= size >> PAGE_SHIFT)
2208+
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
2209+
if (unlikely(offset >= max_off))
22102210
return VM_FAULT_SIGBUS;
22112211

22122212
/*
@@ -2255,8 +2255,8 @@ int filemap_fault(struct vm_fault *vmf)
22552255
* Found the page and have a reference on it.
22562256
* We must recheck i_size under page lock.
22572257
*/
2258-
size = round_up(i_size_read(inode), PAGE_SIZE);
2259-
if (unlikely(offset >= size >> PAGE_SHIFT)) {
2258+
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
2259+
if (unlikely(offset >= max_off)) {
22602260
unlock_page(page);
22612261
put_page(page);
22622262
return VM_FAULT_SIGBUS;
@@ -2322,7 +2322,7 @@ void filemap_map_pages(struct vm_fault *vmf,
23222322
struct file *file = vmf->vma->vm_file;
23232323
struct address_space *mapping = file->f_mapping;
23242324
pgoff_t last_pgoff = start_pgoff;
2325-
loff_t size;
2325+
unsigned long max_idx;
23262326
struct page *head, *page;
23272327

23282328
rcu_read_lock();
@@ -2368,8 +2368,8 @@ void filemap_map_pages(struct vm_fault *vmf,
23682368
if (page->mapping != mapping || !PageUptodate(page))
23692369
goto unlock;
23702370

2371-
size = round_up(i_size_read(mapping->host), PAGE_SIZE);
2372-
if (page->index >= size >> PAGE_SHIFT)
2371+
max_idx = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE);
2372+
if (page->index >= max_idx)
23732373
goto unlock;
23742374

23752375
if (file->f_ra.mmap_miss > 0)

0 commit comments

Comments
 (0)