]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.71/blk-throttle-check-stats_cpu-before-reading-it-from-sysfs.patch
Linux 4.14.121
[thirdparty/kernel/stable-queue.git] / releases / 3.10.71 / blk-throttle-check-stats_cpu-before-reading-it-from-sysfs.patch
1 From 045c47ca306acf30c740c285a77a4b4bda6be7c5 Mon Sep 17 00:00:00 2001
2 From: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
3 Date: Mon, 16 Feb 2015 17:16:45 -0200
4 Subject: blk-throttle: check stats_cpu before reading it from sysfs
5
6 From: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
7
8 commit 045c47ca306acf30c740c285a77a4b4bda6be7c5 upstream.
9
10 When reading blkio.throttle.io_serviced in a recently created blkio
11 cgroup, it's possible to race against the creation of a throttle policy,
12 which delays the allocation of stats_cpu.
13
14 Like other functions in the throttle code, just checking for a NULL
15 stats_cpu prevents the following oops caused by that race.
16
17 [ 1117.285199] Unable to handle kernel paging request for data at address 0x7fb4d0020
18 [ 1117.285252] Faulting instruction address: 0xc0000000003efa2c
19 [ 1137.733921] Oops: Kernel access of bad area, sig: 11 [#1]
20 [ 1137.733945] SMP NR_CPUS=2048 NUMA PowerNV
21 [ 1137.734025] Modules linked in: bridge stp llc kvm_hv kvm binfmt_misc autofs4
22 [ 1137.734102] CPU: 3 PID: 5302 Comm: blkcgroup Not tainted 3.19.0 #5
23 [ 1137.734132] task: c000000f1d188b00 ti: c000000f1d210000 task.ti: c000000f1d210000
24 [ 1137.734167] NIP: c0000000003efa2c LR: c0000000003ef9f0 CTR: c0000000003ef980
25 [ 1137.734202] REGS: c000000f1d213500 TRAP: 0300 Not tainted (3.19.0)
26 [ 1137.734230] MSR: 9000000000009032 <SF,HV,EE,ME,IR,DR,RI> CR: 42008884 XER: 20000000
27 [ 1137.734325] CFAR: 0000000000008458 DAR: 00000007fb4d0020 DSISR: 40000000 SOFTE: 0
28 GPR00: c0000000003ed3a0 c000000f1d213780 c000000000c59538 0000000000000000
29 GPR04: 0000000000000800 0000000000000000 0000000000000000 0000000000000000
30 GPR08: ffffffffffffffff 00000007fb4d0020 00000007fb4d0000 c000000000780808
31 GPR12: 0000000022000888 c00000000fdc0d80 0000000000000000 0000000000000000
32 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
33 GPR20: 000001003e120200 c000000f1d5b0cc0 0000000000000200 0000000000000000
34 GPR24: 0000000000000001 c000000000c269e0 0000000000000020 c000000f1d5b0c80
35 GPR28: c000000000ca3a08 c000000000ca3dec c000000f1c667e00 c000000f1d213850
36 [ 1137.734886] NIP [c0000000003efa2c] .tg_prfill_cpu_rwstat+0xac/0x180
37 [ 1137.734915] LR [c0000000003ef9f0] .tg_prfill_cpu_rwstat+0x70/0x180
38 [ 1137.734943] Call Trace:
39 [ 1137.734952] [c000000f1d213780] [d000000005560520] 0xd000000005560520 (unreliable)
40 [ 1137.734996] [c000000f1d2138a0] [c0000000003ed3a0] .blkcg_print_blkgs+0xe0/0x1a0
41 [ 1137.735039] [c000000f1d213960] [c0000000003efb50] .tg_print_cpu_rwstat+0x50/0x70
42 [ 1137.735082] [c000000f1d2139e0] [c000000000104b48] .cgroup_seqfile_show+0x58/0x150
43 [ 1137.735125] [c000000f1d213a70] [c0000000002749dc] .kernfs_seq_show+0x3c/0x50
44 [ 1137.735161] [c000000f1d213ae0] [c000000000218630] .seq_read+0xe0/0x510
45 [ 1137.735197] [c000000f1d213bd0] [c000000000275b04] .kernfs_fop_read+0x164/0x200
46 [ 1137.735240] [c000000f1d213c80] [c0000000001eb8e0] .__vfs_read+0x30/0x80
47 [ 1137.735276] [c000000f1d213cf0] [c0000000001eb9c4] .vfs_read+0x94/0x1b0
48 [ 1137.735312] [c000000f1d213d90] [c0000000001ebb38] .SyS_read+0x58/0x100
49 [ 1137.735349] [c000000f1d213e30] [c000000000009218] syscall_exit+0x0/0x98
50 [ 1137.735383] Instruction dump:
51 [ 1137.735405] 7c6307b4 7f891800 409d00b8 60000000 60420000 3d420004 392a63b0 786a1f24
52 [ 1137.735471] 7d49502a e93e01c8 7d495214 7d2ad214 <7cead02a> e9090008 e9490010 e9290018
53
54 And here is one code that allows to easily reproduce this, although this
55 has first been found by running docker.
56
57 void run(pid_t pid)
58 {
59 int n;
60 int status;
61 int fd;
62 char *buffer;
63 buffer = memalign(BUFFER_ALIGN, BUFFER_SIZE);
64 n = snprintf(buffer, BUFFER_SIZE, "%d\n", pid);
65 fd = open(CGPATH "/test/tasks", O_WRONLY);
66 write(fd, buffer, n);
67 close(fd);
68 if (fork() > 0) {
69 fd = open("/dev/sda", O_RDONLY | O_DIRECT);
70 read(fd, buffer, 512);
71 close(fd);
72 wait(&status);
73 } else {
74 fd = open(CGPATH "/test/blkio.throttle.io_serviced", O_RDONLY);
75 n = read(fd, buffer, BUFFER_SIZE);
76 close(fd);
77 }
78 free(buffer);
79 exit(0);
80 }
81
82 void test(void)
83 {
84 int status;
85 mkdir(CGPATH "/test", 0666);
86 if (fork() > 0)
87 wait(&status);
88 else
89 run(getpid());
90 rmdir(CGPATH "/test");
91 }
92
93 int main(int argc, char **argv)
94 {
95 int i;
96 for (i = 0; i < NR_TESTS; i++)
97 test();
98 return 0;
99 }
100
101 Reported-by: Ricardo Marin Matinata <rmm@br.ibm.com>
102 Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
103 Signed-off-by: Jens Axboe <axboe@fb.com>
104 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
105
106 ---
107 block/blk-throttle.c | 3 +++
108 1 file changed, 3 insertions(+)
109
110 --- a/block/blk-throttle.c
111 +++ b/block/blk-throttle.c
112 @@ -942,6 +942,9 @@ static u64 tg_prfill_cpu_rwstat(struct s
113 struct blkg_rwstat rwstat = { }, tmp;
114 int i, cpu;
115
116 + if (tg->stats_cpu == NULL)
117 + return 0;
118 +
119 for_each_possible_cpu(cpu) {
120 struct tg_stats_cpu *sc = per_cpu_ptr(tg->stats_cpu, cpu);
121