linux/mm
Mel Gorman 5dd02a8952 mm: filemap: avoid unnecessary calls to lock_page when waiting for IO to complete during a read
commit ebded02788 upstream.

In the generic read paths the kernel looks up a page in the page cache
and if it's up to date, it is used.  If not, the page lock is acquired
to wait for IO to complete and then check the page.  If multiple
processes are waiting on IO, they all serialise against the lock and
duplicate the checks.  This is unnecessary.

The page lock in itself does not give any guarantees to the callers
about the page state as it can be immediately truncated or reclaimed
after the page is unlocked.  It's sufficient to wait_on_page_locked and
then continue if the page is up to date on wakeup.

It is possible that a truncated but up-to-date page is returned but the
reference taken during read prevents it disappearing underneath the
caller and the data is still valid if PageUptodate.

The overall impact is small as even if processes serialise on the lock,
the lock section is tiny once the IO is complete.  Profiles indicated
that unlock_page and friends are generally a tiny portion of a
read-intensive workload.  An artificial test was created that had
instances of dd access a cache-cold file on an ext4 filesystem and
measure how long the read took.

paralleldd
                                    4.4.0                 4.4.0
                                  vanilla             avoidlock
Amean    Elapsd-1          5.28 (  0.00%)        5.15 (  2.50%)
Amean    Elapsd-4          5.29 (  0.00%)        5.17 (  2.12%)
Amean    Elapsd-7          5.28 (  0.00%)        5.18 (  1.78%)
Amean    Elapsd-12         5.20 (  0.00%)        5.33 ( -2.50%)
Amean    Elapsd-21         5.14 (  0.00%)        5.21 ( -1.41%)
Amean    Elapsd-30         5.30 (  0.00%)        5.12 (  3.38%)
Amean    Elapsd-48         5.78 (  0.00%)        5.42 (  6.21%)
Amean    Elapsd-79         6.78 (  0.00%)        6.62 (  2.46%)
Amean    Elapsd-110        9.09 (  0.00%)        8.99 (  1.15%)
Amean    Elapsd-128       10.60 (  0.00%)       10.43 (  1.66%)

The impact is small but intuitively, it makes sense to avoid unnecessary
calls to lock_page.

Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-05-26 08:48:54 +02:00
..
kasan kasan: respect /proc/sys/kernel/traceoff_on_warning 2017-06-17 06:39:36 +02:00
backing-dev.c writeback: fix the wrong congested state variable definition 2018-04-08 11:51:56 +02:00
balloon_compaction.c virtio_balloon: fix race between migration and ballooning 2016-03-03 15:07:18 -08:00
bootmem.c bootmem: avoid freeing to bootmem after bootmem is done 2015-09-08 15:35:28 -07:00
cleancache.c
cma_debug.c
cma.c cma: fix calculation of aligned offset 2018-01-31 12:06:09 +01:00
cma.h
compaction.c mm/compaction: pass only pageblock aligned range to pageblock_pfn_to_page 2018-01-17 09:35:26 +01:00
debug-pagealloc.c mm, hwpoison: fixup "mm: check the return value of lookup_page_ext for all call sites" 2017-11-24 11:26:29 +01:00
debug.c mm: make compound_head() robust 2015-11-06 17:50:42 -08:00
dmapool.c mm, page_alloc: distinguish between being unable to sleep, unwilling to sleep and avoiding waking kswapd 2015-11-06 17:50:42 -08:00
early_ioremap.c mm/early_ioremap: Fix boot hang with earlyprintk=efi,keep 2018-02-25 11:03:41 +01:00
fadvise.c
failslab.c mm, page_alloc: rename __GFP_WAIT to __GFP_RECLAIM 2015-11-06 17:50:42 -08:00
filemap.c mm: filemap: avoid unnecessary calls to lock_page when waiting for IO to complete during a read 2018-05-26 08:48:54 +02:00
frame_vector.c mm: fix docbook comment for get_vaddr_frames() 2015-11-05 19:34:48 -08:00
frontswap.c
gup.c mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
highmem.c
huge_memory.c thp: fix MADV_DONTNEED vs. numa balancing race 2017-12-16 10:33:50 +01:00
hugetlb_cgroup.c mm: make compound_head() robust 2015-11-06 17:50:42 -08:00
hugetlb.c mm, hugetlb: use pte_present() instead of pmd_present() in follow_huge_pmd() 2017-04-08 09:53:32 +02:00
hwpoison-inject.c hwpoison: use page_cgroup_ino for filtering by memcg 2015-09-10 13:29:01 -07:00
init-mm.c mm: Add a user_ns owner to mm_struct and fix ptrace permission checks 2017-01-06 11:16:11 +01:00
internal.h mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries 2017-08-11 09:08:50 -07:00
interval_tree.c
Kconfig mm: make compound_head() robust 2015-11-06 17:50:42 -08:00
Kconfig.debug
kmemcheck.c
kmemleak-test.c
kmemleak.c kmemleak: add scheduling point to kmemleak_scan() 2018-02-03 17:04:29 +01:00
ksm.c mm,ksm: fix endless looping in allocating memory when ksm enable 2016-10-07 15:23:40 +02:00
list_lru.c mm/list_lru.c: fix list_lru_count_node() to be race free 2017-07-21 07:44:56 +02:00
maccess.c mm/maccess.c: actually return -EFAULT from strncpy_from_unsafe 2015-11-05 19:34:48 -08:00
madvise.c mm/madvise.c: fix madvise() infinite loop under special circumstances 2017-12-05 11:22:50 +01:00
Makefile media updates for v4.3-rc1 2015-09-11 16:42:39 -07:00
memblock.c mm: consider memblock reservations for deferred memory initialization sizing 2017-06-14 13:16:26 +02:00
memcontrol.c hwpoison, memcg: forcibly uncharge LRU pages 2018-01-31 12:06:09 +01:00
memory_hotplug.c base/memory, hotplug: fix a kernel oops in show_valid_zones() 2017-02-09 08:02:47 +01:00
memory-failure.c hwpoison, memcg: forcibly uncharge LRU pages 2018-01-31 12:06:09 +01:00
memory.c mm: allow GFP_{FS,IO} for page_cache_read page cache allocation 2018-04-24 09:32:11 +02:00
mempolicy.c mm/mempolicy: fix use after free when calling get_mempolicy 2017-08-24 17:02:35 -07:00
mempool.c mm/mempool: avoid KASAN marking mempool poison checks as use-after-free 2017-08-12 19:29:09 -07:00
memtest.c
migrate.c Sanitize 'move_pages()' permission checks 2017-08-24 17:02:36 -07:00
mincore.c mm/mincore: use offset_in_page macro 2015-11-05 19:34:48 -08:00
mlock.c mlock: fix mlock count can not decrease in race condition 2017-06-07 12:06:01 +02:00
mm_init.c
mmap.c mm/mmap.c: do not blow on PROT_NONE MAP_FIXED holes in the stack 2018-01-31 12:06:09 +01:00
mmu_context.c mm/mmu_context, sched/core: Fix mmu_context.h assumption 2017-12-25 14:22:09 +01:00
mmu_notifier.c mmu-notifier: add clear_young callback 2015-09-10 13:29:01 -07:00
mmzone.c
mprotect.c mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries 2017-08-11 09:08:50 -07:00
mremap.c mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries 2017-08-11 09:08:50 -07:00
msync.c mm/msync: use offset_in_page macro 2015-11-05 19:34:48 -08:00
nobootmem.c
nommu.c mm/nommu.c: drop unlikely inside BUG_ON() 2015-11-05 19:34:48 -08:00
oom_kill.c mm/oom_kill.c: avoid attempting to kill init sharing same memory 2015-12-12 10:15:34 -08:00
page_alloc.c mm, page_alloc: fix potential false positive in __zone_watermark_ok 2018-01-31 12:06:09 +01:00
page_counter.c mm: page_counter: let page_counter_try_charge() return bool 2015-11-05 19:34:48 -08:00
page_ext.c mm/page_ext.c: check if page_ext is not prepared 2017-11-24 08:32:25 +01:00
page_idle.c mm: introduce idle page tracking 2015-09-10 13:29:01 -07:00
page_io.c
page_isolation.c mm: fix invalid node in alloc_migrate_target() 2016-04-20 15:41:53 +09:00
page_owner.c mm: check the return value of lookup_page_ext for all call sites 2017-11-24 08:32:25 +01:00
page-writeback.c writeback: safer lock nesting 2018-04-24 09:32:12 +02:00
pagewalk.c mm/pagewalk.c: report holes in hugetlb ranges 2017-11-24 08:32:25 +01:00
percpu-km.c
percpu-vm.c
percpu.c percpu: include linux/sched.h for cond_resched() 2018-05-16 10:06:46 +02:00
pgtable-generic.c mm,thp: khugepaged: call pte flush at the time of collapse 2016-02-25 12:01:23 -08:00
process_vm_access.c ptrace: use fsuid, fsgid, effective creds for fs access checks 2016-02-25 12:01:16 -08:00
quicklist.c
readahead.c mm, fs: introduce mapping_gfp_constraint() 2015-11-06 17:50:42 -08:00
rmap.c mm/rmap: batched invalidations should use existing api 2017-12-25 14:22:09 +01:00
shmem.c tmpfs: fix regression hang in fallocate undo 2016-07-27 09:47:40 -07:00
slab_common.c slub: do not merge cache if slub_debug contains a never-merge flag 2017-10-21 17:09:05 +02:00
slab.c mm, slab: reschedule cache_reap() on the same CPU 2018-04-24 09:32:05 +02:00
slab.h slab/slub: adjust kmem_cache_alloc_bulk API 2015-11-22 11:58:44 -08:00
slob.c slab/slub: adjust kmem_cache_alloc_bulk API 2015-11-22 11:58:44 -08:00
slub.c slub/memcg: cure the brainless abuse of sysfs attributes 2017-06-07 12:06:01 +02:00
sparse-vmemmap.c
sparse.c
swap_cgroup.c mm, swap_cgroup: reschedule when neeed in swap_cgroup_swapoff() 2017-07-05 14:37:15 +02:00
swap_state.c mm: swap: zswap: maybe_preload & refactoring 2015-09-08 15:35:28 -07:00
swap.c mm: make compound_head() robust 2015-11-06 17:50:42 -08:00
swapfile.c swapfile: fix memory corruption via malformed swapfile 2016-11-18 10:48:34 +01:00
truncate.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
userfaultfd.c
util.c Provide a function to create a NUL-terminated string from unterminated data 2018-02-25 11:03:36 +01:00
vmacache.c mm/vmacache: inline vmacache_valid_mm() 2015-11-05 19:34:48 -08:00
vmalloc.c mm: vmalloc: don't remove inexistent guard hole in remove_vm_area() 2015-11-20 16:17:32 -08:00
vmpressure.c mm: vmpressure: fix sending wrong events on underflow 2017-03-12 06:37:25 +01:00
vmscan.c vmscan: do not force-scan file lru if its absolute size is small 2018-05-26 08:48:53 +02:00
vmstat.c proc: much faster /proc/vmstat 2018-01-10 09:27:14 +01:00
workingset.c mm: workingset: fix crash in shadow node shrinker caused by replace_page_cache_page() 2016-10-28 03:01:34 -04:00
zbud.c mm: zsmalloc: constify struct zs_pool name 2015-11-06 17:50:42 -08:00
zpool.c mm: zsmalloc: constify struct zs_pool name 2015-11-06 17:50:42 -08:00
zsmalloc.c zsmalloc: fix zs_can_compact() integer overflow 2016-05-18 17:06:44 -07:00
zswap.c zswap: don't param_set_charp while holding spinlock 2018-01-17 09:35:27 +01:00