]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.6.8/tmpfs-change-final-i_blocks-bug-to-warning.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 3.6.8 / tmpfs-change-final-i_blocks-bug-to-warning.patch
1 From 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 Mon Sep 17 00:00:00 2001
2 From: Hugh Dickins <hughd@google.com>
3 Date: Fri, 16 Nov 2012 14:15:04 -0800
4 Subject: tmpfs: change final i_blocks BUG to WARNING
5
6 From: Hugh Dickins <hughd@google.com>
7
8 commit 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 upstream.
9
10 Under a particular load on one machine, I have hit shmem_evict_inode()'s
11 BUG_ON(inode->i_blocks), enough times to narrow it down to a particular
12 race between swapout and eviction.
13
14 It comes from the "if (freed > 0)" asymmetry in shmem_recalc_inode(),
15 and the lack of coherent locking between mapping's nrpages and shmem's
16 swapped count. There's a window in shmem_writepage(), between lowering
17 nrpages in shmem_delete_from_page_cache() and then raising swapped
18 count, when the freed count appears to be +1 when it should be 0, and
19 then the asymmetry stops it from being corrected with -1 before hitting
20 the BUG.
21
22 One answer is coherent locking: using tree_lock throughout, without
23 info->lock; reasonable, but the raw_spin_lock in percpu_counter_add() on
24 used_blocks makes that messier than expected. Another answer may be a
25 further effort to eliminate the weird shmem_recalc_inode() altogether,
26 but previous attempts at that failed.
27
28 So far undecided, but for now change the BUG_ON to WARN_ON: in usual
29 circumstances it remains a useful consistency check.
30
31 Signed-off-by: Hugh Dickins <hughd@google.com>
32 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
33 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
34 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35
36 ---
37 mm/shmem.c | 2 +-
38 1 file changed, 1 insertion(+), 1 deletion(-)
39
40 --- a/mm/shmem.c
41 +++ b/mm/shmem.c
42 @@ -654,7 +654,7 @@ static void shmem_evict_inode(struct ino
43 kfree(xattr->name);
44 kfree(xattr);
45 }
46 - BUG_ON(inode->i_blocks);
47 + WARN_ON(inode->i_blocks);
48 shmem_free_inode(inode->i_sb);
49 clear_inode(inode);
50 }