linux/fs/nfs
David Howells 8c209ce721 NFS: nfs_migrate_page() does not wait for FS-Cache to finish with a page
nfs_migrate_page() does not wait for FS-Cache to finish with a page, probably
leading to the following bad-page-state:

 BUG: Bad page state in process python-bin  pfn:17d39b
 page:ffffea00053649e8 flags:004000000000100c count:0 mapcount:0 mapping:(null)
index:38686 (Tainted: G    B      ---------------- )
 Pid: 31053, comm: python-bin Tainted: G    B      ----------------
2.6.32-71.24.1.el6.x86_64 #1
 Call Trace:
 [<ffffffff8111bfe7>] bad_page+0x107/0x160
 [<ffffffff8111ee69>] free_hot_cold_page+0x1c9/0x220
 [<ffffffff8111ef19>] __pagevec_free+0x59/0xb0
 [<ffffffff8104b988>] ? flush_tlb_others_ipi+0x128/0x130
 [<ffffffff8112230c>] release_pages+0x21c/0x250
 [<ffffffff8115b92a>] ? remove_migration_pte+0x28a/0x2b0
 [<ffffffff8115f3f8>] ? mem_cgroup_get_reclaim_stat_from_page+0x18/0x70
 [<ffffffff81122687>] ____pagevec_lru_add+0x167/0x180
 [<ffffffff811226f8>] __lru_cache_add+0x58/0x70
 [<ffffffff81122731>] lru_cache_add_lru+0x21/0x40
 [<ffffffff81123f49>] putback_lru_page+0x69/0x100
 [<ffffffff8115c0bd>] migrate_pages+0x13d/0x5d0
 [<ffffffff81122687>] ? ____pagevec_lru_add+0x167/0x180
 [<ffffffff81152ab0>] ? compaction_alloc+0x0/0x370
 [<ffffffff8115255c>] compact_zone+0x4cc/0x600
 [<ffffffff8111cfac>] ? get_page_from_freelist+0x15c/0x820
 [<ffffffff810672f4>] ? check_preempt_wakeup+0x1c4/0x3c0
 [<ffffffff8115290e>] compact_zone_order+0x7e/0xb0
 [<ffffffff81152a49>] try_to_compact_pages+0x109/0x170
 [<ffffffff8111e94d>] __alloc_pages_nodemask+0x5ed/0x850
 [<ffffffff814c9136>] ? thread_return+0x4e/0x778
 [<ffffffff81150d43>] alloc_pages_vma+0x93/0x150
 [<ffffffff81167ea5>] do_huge_pmd_anonymous_page+0x135/0x340
 [<ffffffff814cb6f6>] ? rwsem_down_read_failed+0x26/0x30
 [<ffffffff81136755>] handle_mm_fault+0x245/0x2b0
 [<ffffffff814ce383>] do_page_fault+0x123/0x3a0
 [<ffffffff814cbdf5>] page_fault+0x25/0x30

nfs_migrate_page() calls nfs_fscache_release_page() which doesn't actually wait
- even if __GFP_WAIT is set.  The reason that doesn't wait is that
fscache_maybe_release_page() might deadlock the allocator as the work threads
writing to the cache may all end up sleeping on memory allocation.

However, I wonder if that is actually a problem.  There are a number of things
I can do to deal with this:

 (1) Make nfs_migrate_page() wait.

 (2) Make fscache_maybe_release_page() honour the __GFP_WAIT flag.

 (3) Set a timeout around the wait.

 (4) Make nfs_migrate_page() return an error if the page is still busy.

For the moment, I'll select (2) and (4).

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
2012-12-20 22:12:03 +00:00
..
blocklayout NFSv4.1: Move slot table and session struct definitions to nfs4session.h 2012-12-06 00:30:46 +01:00
objlayout NFSv4.1: Remove unused function last_byte_offset 2012-11-04 14:43:38 -05:00
cache_lib.c NFSv4: Get rid of unnecessary BUG_ON()s 2012-11-04 14:43:39 -05:00
cache_lib.h NFS: DNS resolver PipeFS notifier introduced 2012-01-31 18:20:26 -05:00
callback.c NFSv4: Fix the return value for nfs_callback_start_svc 2012-10-16 13:14:42 -04:00
callback.h NFSv4.1: Clean up session draining 2012-12-06 00:30:44 +01:00
callback_proc.c NFSv4.1: Cleanup move session slot management to fs/nfs/nfs4session.c 2012-12-06 00:30:45 +01:00
callback_xdr.c NFSv4.1: Move slot table and session struct definitions to nfs4session.h 2012-12-06 00:30:46 +01:00
client.c NFS: avoid NULL dereference in nfs_destroy_server 2012-12-12 23:55:56 -05:00
delegation.c NFS: Create a return_delegation rpc op 2012-06-29 11:46:45 -04:00
delegation.h NFS: Convert v4 into a module 2012-07-30 19:06:52 -04:00
dir.c NFS client updates for Linux 3.8 2012-12-18 09:36:34 -08:00
direct.c nfs: fix page dirtying in NFS DIO read codepath 2012-12-12 12:56:19 -05:00
dns_resolve.c NFS: fix bug in legacy DNS resolver. 2012-10-31 16:25:59 -04:00
dns_resolve.h NFS: DNS resolver cache per network namespace context introduced 2012-01-31 18:20:26 -05:00
file.c lseek: the "whence" argument is called "whence" 2012-12-17 17:15:12 -08:00
fscache-index.c NFS: Use the inode->i_version to cache NFSv4 change attribute information 2011-10-18 09:14:34 -07:00
fscache.c NFS: Don't pass mount data to nfs_fscache_get_super_cookie() 2012-05-14 17:30:26 -07:00
fscache.h NFS: Use FS-Cache invalidation 2012-12-20 22:06:33 +00:00
getroot.c nfs: include internal.h in getroot.h 2012-10-02 08:17:04 -07:00
idmap.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security 2012-12-16 15:40:50 -08:00
inode.c NFS: Use FS-Cache invalidation 2012-12-20 22:06:33 +00:00
internal.h NFS: Ensure that we always drop inodes that have been marked as stale 2012-12-14 14:36:36 -05:00
iostat.h NFS: Squelch compiler warning in nfs_add_server_stats() 2010-05-14 15:09:31 -04:00
Kconfig NFSv4.1: Remove the dependency on CONFIG_EXPERIMENTAL 2012-10-03 10:54:50 -07:00
Makefile NFSv4.1: Cleanup move session slot management to fs/nfs/nfs4session.c 2012-12-06 00:30:45 +01:00
mount_clnt.c NFS: Remove the BUG_ON() in the mount code 2012-11-04 14:43:39 -05:00
namespace.c nfs: Show original device name verbatim in /proc/*/mount{s,info} 2012-10-31 16:26:26 -04:00
netns.h nfs: include NFSv4 header in netns.h 2012-10-02 08:17:02 -07:00
nfs.h NFS: Convert v4 into a module 2012-07-30 19:06:52 -04:00
nfs2super.c NFS: Convert v2 into a module 2012-07-30 19:06:41 -04:00
nfs2xdr.c NFS: Remove asserts from the NFS XDR code 2012-11-04 14:43:38 -05:00
nfs3acl.c userns: Pass a userns parameter into posix_acl_to_xattr and posix_acl_from_xattr 2012-09-18 01:01:35 -07:00
nfs3client.c NFS: Only initialize the ACL client in the v3 case 2012-07-30 19:05:54 -04:00
nfs3proc.c SUNRPC handle EKEYEXPIRED in call_refreshresult 2012-12-12 15:36:02 -05:00
nfs3super.c NFS: Convert v3 into a module 2012-07-30 19:06:46 -04:00
nfs3xdr.c NFS: Remove asserts from the NFS XDR code 2012-11-04 14:43:38 -05:00
nfs4_fs.h Merge branch 'bugfixes' into nfs-for-next 2012-12-11 09:16:26 -05:00
nfs4client.c NFSv4.1: Cleanup move session slot management to fs/nfs/nfs4session.c 2012-12-06 00:30:45 +01:00
nfs4file.c NFSv4: Get rid of unnecessary BUG_ON()s 2012-11-04 14:43:39 -05:00
nfs4filelayout.c SUNRPC handle EKEYEXPIRED in call_refreshresult 2012-12-12 15:36:02 -05:00
nfs4filelayout.h NFSv4.1: Kill nfs4_ds_disconnect() 2012-10-15 10:49:42 -04:00
nfs4filelayoutdev.c NFSv4.1: Cleanup move session slot management to fs/nfs/nfs4session.c 2012-12-06 00:30:45 +01:00
nfs4getroot.c NFSv4: fs/nfs/nfs4getroot.c needs to include "internal.h" 2012-10-16 12:37:59 -04:00
nfs4namespace.c nfs: Show original device name verbatim in /proc/*/mount{s,info} 2012-10-31 16:26:26 -04:00
nfs4proc.c NFS: Use FS-Cache invalidation 2012-12-20 22:06:33 +00:00
nfs4renewd.c workqueue: use mod_delayed_work() instead of cancel + queue 2012-08-13 16:27:37 -07:00
nfs4session.c NFSv4.1: Deal effectively with interrupted RPC calls. 2012-12-15 15:39:59 -05:00
nfs4session.h NFSv4.1: Deal effectively with interrupted RPC calls. 2012-12-15 15:39:59 -05:00
nfs4state.c nfs: Remove unused list nfs4_clientid_list 2012-12-13 10:40:09 -05:00
nfs4super.c NFS: Ensure that we always drop inodes that have been marked as stale 2012-12-14 14:36:36 -05:00
nfs4sysctl.c nfs: include nfs4_fh.h in nfs4sysctl.c 2012-10-02 08:17:03 -07:00
nfs4xdr.c Merge branch 'bugfixes' into nfs-for-next 2012-12-11 09:16:26 -05:00
nfsroot.c SUNRPC/NFS: Add Kbuild dependencies for NFS_DEBUG/RPC_DEBUG 2012-03-20 13:08:26 -04:00
pagelist.c NFS: Clean up helper function nfs4_select_rw_stateid() 2012-09-28 16:03:04 -04:00
pnfs.c NFSv4.1: Remove assertion BUG_ON()s from the files and generic layout code 2012-11-04 14:43:39 -05:00
pnfs.h NFSv4.1: Do not call pnfs_return_layout() from an rpciod context 2012-10-15 10:49:43 -04:00
pnfs_dev.c NFSv4.1: pNFS data servers may be temporarily offline 2012-09-28 16:03:09 -04:00
proc.c SUNRPC handle EKEYEXPIRED in call_refreshresult 2012-12-12 15:36:02 -05:00
read.c Merge branch 'akpm' (Andrew's patch-bomb) 2012-07-31 19:25:39 -07:00
super.c NFS: Ensure that we always drop inodes that have been marked as stale 2012-12-14 14:36:36 -05:00
symlink.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
sysctl.c NFS: Initialize v4 sysctls from nfs_init_v4() 2012-07-17 13:33:18 -04:00
unlink.c NFS: add nfs_sb_deactive_async to avoid deadlock 2012-10-31 16:26:26 -04:00
write.c NFS: nfs_migrate_page() does not wait for FS-Cache to finish with a page 2012-12-20 22:12:03 +00:00