linux/mm
Daisuke Nishimura 31a5639623 mm: add_to_swap_cache() must not sleep
After commit 355cfa73 ("mm: modify swap_map and add SWAP_HAS_CACHE flag"),
read_swap_cache_async() will busy-wait while a entry doesn't exist in swap
cache but it has SWAP_HAS_CACHE flag.

Such entries can exist on add/delete path of swap cache.  On add path,
add_to_swap_cache() is called soon after SWAP_HAS_CACHE flag is set, and
on delete path, swapcache_free() will be called (SWAP_HAS_CACHE flag is
cleared) soon after __delete_from_swap_cache() is called.  So, the
busy-wait works well in most cases.

But this mechanism can cause soft lockup if add_to_swap_cache() sleeps and
read_swap_cache_async() tries to swap-in the same entry on the same cpu.

This patch calls radix_tree_preload() before swapcache_prepare() and
divides add_to_swap_cache() into two part: radix_tree_preload() part and
radix_tree_insert() part(define it as __add_to_swap_cache()).

Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-09-22 07:17:35 -07:00
..
Kconfig ksm: add some documentation 2009-09-22 07:17:33 -07:00
Kconfig.debug
Makefile ksm: the mm interface to ksm 2009-09-22 07:17:31 -07:00
allocpercpu.c
backing-dev.c writeback: splice dirty inode entries to default bdi on bdi_destroy() 2009-09-16 15:18:52 +02:00
bootmem.c kmemleak: Do not report alloc_bootmem blocks as leaks 2009-08-27 14:29:17 +01:00
bounce.c
debug-pagealloc.c
dmapool.c
fadvise.c
failslab.c
filemap.c mm: oom analysis: add shmem vmstat 2009-09-22 07:17:27 -07:00
filemap_xip.c
fremap.c
highmem.c
hugetlb.c hugetlb: restore interleaving of bootmem huge pages 2009-09-22 07:17:26 -07:00
init-mm.c
internal.h
kmemcheck.c
kmemleak-test.c
kmemleak.c kmemleak: Improve the "Early log buffer exceeded" error message 2009-09-11 10:42:09 +01:00
ksm.c ksm: unmerge is an origin of OOMs 2009-09-22 07:17:33 -07:00
maccess.c
madvise.c ksm: the mm interface to ksm 2009-09-22 07:17:31 -07:00
memcontrol.c cgroup avoid permanent sleep at rmdir 2009-07-29 19:10:35 -07:00
memory.c ksm: fix deadlock with munlock in exit_mmap 2009-09-22 07:17:32 -07:00
memory_hotplug.c memory hotplug: update zone pcp at memory online 2009-09-22 07:17:25 -07:00
mempolicy.c mm: make set_mempolicy(MPOL_INTERLEAV) N_HIGH_MEMORY aware 2009-08-07 10:39:55 -07:00
mempool.c mempool.c: clean up type-casting 2009-08-10 08:31:16 -07:00
migrate.c mm: vmstat: add isolate pages 2009-09-22 07:17:29 -07:00
mincore.c
mlock.c
mm_init.c
mmap.c ksm: clean up obsolete references 2009-09-22 07:17:33 -07:00
mmu_notifier.c ksm: add mmu_notifier set_pte_at_notify() 2009-09-22 07:17:31 -07:00
mmzone.c
mprotect.c perf: Do the big rename: Performance Counters -> Performance Events 2009-09-21 14:28:04 +02:00
mremap.c ksm: mremap use err from ksm_madvise 2009-09-22 07:17:33 -07:00
msync.c
nommu.c nommu: fix error handling in do_mmap_pgoff() 2009-09-05 11:30:42 -07:00
oom_kill.c ksm: unmerge is an origin of OOMs 2009-09-22 07:17:33 -07:00
page-writeback.c mm: count only reclaimable lru pages 2009-09-22 07:17:30 -07:00
page_alloc.c tracing, page-allocator: add trace event for page traffic related to the buddy lists 2009-09-22 07:17:34 -07:00
page_cgroup.c memory hotplug: alloc page from other node in memory online 2009-09-22 07:17:26 -07:00
page_io.c
page_isolation.c
pagewalk.c
percpu.c Merge branch 'for-next' into for-linus 2009-09-15 09:57:19 +09:00
prio_tree.c
quicklist.c
readahead.c
rmap.c ksm: no debug in page_dup_rmap() 2009-09-22 07:17:31 -07:00
shmem.c Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev 2009-09-15 09:50:49 -07:00
shmem_acl.c shmfs: use 'check_acl' instead of 'permission' 2009-09-08 11:08:46 -07:00
slab.c
slob.c slab: remove duplicate kmem_cache_init_late() declarations 2009-08-06 11:36:25 +03:00
slub.c mm: kmem_cache_create(): make it easier to catch NULL cache names 2009-09-22 07:17:33 -07:00
sparse-vmemmap.c memory hotplug: alloc page from other node in memory online 2009-09-22 07:17:26 -07:00
sparse.c memory hotplug: alloc page from other node in memory online 2009-09-22 07:17:26 -07:00
swap.c
swap_state.c mm: add_to_swap_cache() must not sleep 2009-09-22 07:17:35 -07:00
swapfile.c ksm: unmerge is an origin of OOMs 2009-09-22 07:17:33 -07:00
thrash.c
truncate.c
util.c
vmalloc.c kcore: fix vread/vwrite to be aware of holes 2009-09-22 07:17:34 -07:00
vmscan.c vmscan: kill unnecessary prefetch 2009-09-22 07:17:30 -07:00
vmstat.c mm: vmstat: add isolate pages 2009-09-22 07:17:29 -07:00