diff options
author | Filipe Manana <fdmanana@suse.com> | 2014-08-07 21:47:05 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-08-21 10:55:25 -0400 |
commit | 7064dd5c36187725e7ccfd837e07678ae435d3f5 (patch) | |
tree | ff4d54b9ff4cd9e36566100d3623f68cbe975a23 /fs/btrfs/inode.c | |
parent | 74121f7cbb2f60b41c48184ad5b889c0704e7b90 (diff) |
Btrfs: don't monopolize a core when evicting inode
If an inode has a very large number of extent maps, we can spend
a lot of time freeing them, which triggers a soft lockup warning.
Therefore reschedule if we need to when freeing the extent maps
while evicting the inode.
I could trigger this all the time by running xfstests/generic/299 on
a file system with the no-holes feature enabled. That test creates
an inode with 11386677 extent maps.
$ mkfs.btrfs -f -O no-holes $TEST_DEV
$ MKFS_OPTIONS="-O no-holes" ./check generic/299
generic/299 382s ...
Message from syslogd@debian-vm3 at Aug 7 10:44:29 ...
kernel:[85304.208017] BUG: soft lockup - CPU#0 stuck for 22s! [umount:25330]
384s
Ran: generic/299
Passed all 1 tests
$ dmesg
(...)
[86304.300017] BUG: soft lockup - CPU#0 stuck for 23s! [umount:25330]
(...)
[86304.300036] Call Trace:
[86304.300036] [<ffffffff81698ba9>] __slab_free+0x54/0x295
[86304.300036] [<ffffffffa02ee9cc>] ? free_extent_map+0x5c/0xb0 [btrfs]
[86304.300036] [<ffffffff811a6cd2>] kmem_cache_free+0x282/0x2a0
[86304.300036] [<ffffffffa02ee9cc>] free_extent_map+0x5c/0xb0 [btrfs]
[86304.300036] [<ffffffffa02e3775>] btrfs_evict_inode+0xd5/0x660 [btrfs]
[86304.300036] [<ffffffff811e7c8d>] ? __inode_wait_for_writeback+0x6d/0xc0
[86304.300036] [<ffffffff816a389b>] ? _raw_spin_unlock+0x2b/0x40
[86304.300036] [<ffffffff811d8cbb>] evict+0xab/0x180
[86304.300036] [<ffffffff811d8dce>] dispose_list+0x3e/0x60
[86304.300036] [<ffffffff811d9b04>] evict_inodes+0xf4/0x110
[86304.300036] [<ffffffff811bd953>] generic_shutdown_super+0x53/0x110
[86304.300036] [<ffffffff811bdaa6>] kill_anon_super+0x16/0x30
[86304.300036] [<ffffffffa02a78ba>] btrfs_kill_super+0x1a/0xa0 [btrfs]
[86304.300036] [<ffffffff811bd3a9>] deactivate_locked_super+0x59/0x80
[86304.300036] [<ffffffff811be44e>] deactivate_super+0x4e/0x70
[86304.300036] [<ffffffff811dec14>] mntput_no_expire+0x174/0x1f0
[86304.300036] [<ffffffff811deab7>] ? mntput_no_expire+0x17/0x1f0
[86304.300036] [<ffffffff811e0517>] SyS_umount+0x97/0x100
(...)
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Tested-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 57c3129ee2a2..2ac260d41ccd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4674,6 +4674,11 @@ static void evict_inode_truncate_pages(struct inode *inode) | |||
4674 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | 4674 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); |
4675 | remove_extent_mapping(map_tree, em); | 4675 | remove_extent_mapping(map_tree, em); |
4676 | free_extent_map(em); | 4676 | free_extent_map(em); |
4677 | if (need_resched()) { | ||
4678 | write_unlock(&map_tree->lock); | ||
4679 | cond_resched(); | ||
4680 | write_lock(&map_tree->lock); | ||
4681 | } | ||
4677 | } | 4682 | } |
4678 | write_unlock(&map_tree->lock); | 4683 | write_unlock(&map_tree->lock); |
4679 | 4684 | ||
@@ -4696,6 +4701,7 @@ static void evict_inode_truncate_pages(struct inode *inode) | |||
4696 | &cached_state, GFP_NOFS); | 4701 | &cached_state, GFP_NOFS); |
4697 | free_extent_state(state); | 4702 | free_extent_state(state); |
4698 | 4703 | ||
4704 | cond_resched(); | ||
4699 | spin_lock(&io_tree->lock); | 4705 | spin_lock(&io_tree->lock); |
4700 | } | 4706 | } |
4701 | spin_unlock(&io_tree->lock); | 4707 | spin_unlock(&io_tree->lock); |