summaryrefslogtreecommitdiffstats
path: root/mm-Fix-the-non-RT-version-of-swap_get_cpu_var.patch
blob: a4f6f43c709103b9ddc106001958645523f7c71d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From ef9956380360aaffd9ca9dde20d8a74f22c4cc8c Mon Sep 17 00:00:00 2001
From: Wu Zhangjin <wuzhangjin@gmail.com>
Date: Fri, 4 Sep 2009 11:22:02 +0800
Subject: [PATCH] mm: Fix the non-RT version of swap_get_cpu_var

commit edc1a1c366af0d1c755f159b3ac503812e166173 in tip.

The commit(f8382688) have converted swap to percpu locked, the
non-RT version of swap_get_cpu_var should be the same as the old
implementation, but in reality, it not works as the old one:

...
+#define swap_get_cpu_var(var, cpu)                     \
+       ({                                              \
+               (void)cpu;                              \
+               &get_cpu_var(var);                      \
+        })
...
 void __lru_cache_add(struct page *page, enum lru_list lru)
 {
-       struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru];
+       struct pagevec *pvec;
+       int cpu;

+       pvec = swap_get_cpu_var(lru_add_pvecs, cpu)[lru];
        page_cache_get(page);
        if (!pagevec_add(pvec, page))
                ____pagevec_lru_add(pvec, lru);
-       put_cpu_var(lru_add_pvecs);
+       swap_put_cpu_var(lru_add_pvecs, cpu);
 }

Here is the point, the old version:

      pvec = &get_cpu_var(lru_add_pvecs)[lru];
     	   = & (get_cpu_var(lru_add_pvecs)[lru]);

new version from commit f8382688:

      pvec = ({ (void)cpu; &get_cpu_var(lru_add_pvecs); })[lru];
           = (&get_cpu_var(lru_add_pvecs)) [lru];

so, we can see, these two are really different. and it made the non-RT boot
fail:

...

ide-gd driver 1.18
hda: max request size: 512KiB
hda: 312581808 sectors (160041 MB) w/8192KiB Cache, CHS=19457/255/63
hda: cache flushes supported
 hda:Unhandled kernel unaligned access[#1]:
Cpu 0
$ 0   : 0000000000000000 000000001400c4e1 98000000013699d0 0000000000000000
$ 4   : 0000000000000000 98000000be04f980 0000000000000010 000000007fd78b57
$ 8   : 0000000000000001 0000000000200200 0000000000100100 98000000be00f210
$12   : 000000001400c4e1 000000001000001e ffffffffffffffff 98000000bd0180a8
$16   : 0000000000000000 98000000be04f998 fffffffb81a72600 ffffffff802d3270
$20   : 0000000000000000 0000000000000000 ffffffffffffffef ffffffff80667a90
$24   : 0000000000000228 ffffffff803ded88
$28   : 98000000be04c000 98000000be04f950 00000000003fffff ffffffff80200404
Hi    : 0000000000000000
Lo    : 0000000000000320
epc   : ffffffff80217194 do_ade+0x298/0x3bc
    Not tainted
ra    : ffffffff80200404 ret_from_exception+0x0/0x10
Status: 1400c4e3    KX SX UX KERNEL EXL IE
Cause : 00000014
BadVA : fffffffb81a72607
PrId  : 00006303 (ICT Loongson-2)
Modules linked in:
Process swapper (pid: 1, threadinfo=98000000be04c000, task=98000000be04b7d8, tls=0000000000000000)
Stack : ffffffff80666f60 ffffffff8025165c 98000000013699d0 0000000000000001
        98000000bd00ae30 ffffffff80200404 0000000000000000 000000001400c4e1
        000000007fd78b57 98000000013699d0 ffffffff80638070 0000000000000002
        fffffffb81a72600 000000007fd78b57 0000000000000001 0000000000200200
        0000000000100100 98000000be00f210 98000000be00f220 000000000000001d
        ffffffffffffffff 98000000bd0180a8 98000000013699d0 0000000000000001
        98000000bd00ae30 ffffffff802d3270 0000000000000000 0000000000000000
        ffffffffffffffef ffffffff80667a90 0000000000000228 ffffffff803ded88
        98000000bd00ae30 98000000bd00ae30 98000000be04c000 98000000be04fab0
        00000000003fffff ffffffff80275350 000000001400c4e3 0000000000000000
        ...
Call Trace:
[<ffffffff80217194>] do_ade+0x298/0x3bc
[<ffffffff80200404>] ret_from_exception+0x0/0x10
[<ffffffff8027fafc>] __lru_cache_add+0x94/0xd8
[<ffffffff80275350>] add_to_page_cache_lru+0x84/0xa8
[<ffffffff80275520>] read_cache_page_async+0xa8/0x1dc
[<ffffffff80275664>] read_cache_page+0x10/0x74
[<ffffffff802fed34>] read_dev_sector+0x34/0xe0
[<ffffffff802ff96c>] adfspart_check_ICS+0x44/0x1b0
[<ffffffff802ff6e4>] rescan_partitions+0x178/0x3a8
[<ffffffff802d3840>] __blkdev_get+0x238/0x318
[<ffffffff802feeb0>] register_disk+0xd0/0x15c
[<ffffffff8037c1e8>] add_disk+0xcc/0x128
[<ffffffff803fcbc4>] ide_gd_probe+0x170/0x1d0
[<ffffffff803e6e08>] driver_probe_device+0xbc/0x180
[<ffffffff803e6f38>] __driver_attach+0x6c/0xa4
[<ffffffff803e6508>] bus_for_each_dev+0x58/0xa4
[<ffffffff803e5bbc>] bus_add_driver+0xc8/0x284
[<ffffffff803e72d8>] driver_register+0xc4/0x17c
[<ffffffff8020fa5c>] do_one_initcall+0x64/0x18c
[<ffffffff806701d8>] kernel_init+0xe0/0x14c
[<ffffffff80212e5c>] kernel_thread_helper+0x10/0x18

Code: 001188f8  00b1882d  de220000 <b2420007> b6420000  24120000  1640000c  00a0202d  8ca20120
Disabling lock debugging due to kernel taint
note: swapper[1] exited with preempt_count 1
Kernel panic - not syncing: Attempted to kill init!

This patch will keep the swap_get_cpu_var as the one before commit f8382688,
and put "(void)cpu;" to swap_put_cpu_var() to avoid warning about unused
variable.

Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
LKML-Reference: <1252034522-32653-1-git-send-email-wuzhangjin@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 mm/swap.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/mm/swap.c b/mm/swap.c
index 3f917bb..fbabfc3 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -96,12 +96,13 @@ static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
 	local_irq_restore(flags)
 
 #define swap_get_cpu_var(var, cpu)			\
-	({						\
-		(void)cpu;				\
-		&get_cpu_var(var);			\
-	 })
+	&get_cpu_var(var)			\
 
-#define swap_put_cpu_var(var, cpu)	put_cpu_var(var)
+#define swap_put_cpu_var(var, cpu)		\
+	({					\
+		(void)cpu;			\
+		put_cpu_var(var);		\
+	 })
 
 #define swap_per_cpu_lock(var, cpu)	&per_cpu(var, cpu)
 
-- 
1.7.0.4