]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0292-kernel-stop_machine-partly-revert-stop_machine-Use-r.patch
rt_patches: required rebase due to printk change
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0292-kernel-stop_machine-partly-revert-stop_machine-Use-r.patch
1 From 1250e418e935851b501b7bda93e05a837fdd8448 Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Wed, 10 Feb 2016 18:25:16 +0100
4 Subject: [PATCH 292/366] kernel/stop_machine: partly revert "stop_machine: Use
5  raw spinlocks"
6
7 With completion using swait and so rawlocks we don't need this anymore.
8 Further, bisect thinks this patch is responsible for:
9
10 |BUG: unable to handle kernel NULL pointer dereference at           (null)
11 |IP: [<ffffffff81082123>] sched_cpu_active+0x53/0x70
12 |PGD 0
13 |Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
14 |Dumping ftrace buffer:
15 |   (ftrace buffer empty)
16 |Modules linked in:
17 |CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.4.1+ #330
18 |Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Debian-1.8.2-1 04/01/2014
19 |task: ffff88013ae64b00 ti: ffff88013ae74000 task.ti: ffff88013ae74000
20 |RIP: 0010:[<ffffffff81082123>]  [<ffffffff81082123>] sched_cpu_active+0x53/0x70
21 |RSP: 0000:ffff88013ae77eb8  EFLAGS: 00010082
22 |RAX: 0000000000000001 RBX: ffffffff81c2cf20 RCX: 0000001050fb52fb
23 |RDX: 0000001050fb52fb RSI: 000000105117ca1e RDI: 00000000001c7723
24 |RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000001
25 |R10: 0000000000000000 R11: 0000000000000001 R12: 00000000ffffffff
26 |R13: ffffffff81c2cee0 R14: 0000000000000000 R15: 0000000000000001
27 |FS:  0000000000000000(0000) GS:ffff88013b200000(0000) knlGS:0000000000000000
28 |CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
29 |CR2: 0000000000000000 CR3: 0000000001c09000 CR4: 00000000000006e0
30 |Stack:
31 | ffffffff810c446d ffff88013ae77f00 ffffffff8107d8dd 000000000000000a
32 | 0000000000000001 0000000000000000 0000000000000000 0000000000000000
33 | 0000000000000000 ffff88013ae77f10 ffffffff8107d90e ffff88013ae77f20
34 |Call Trace:
35 | [<ffffffff810c446d>] ? debug_lockdep_rcu_enabled+0x1d/0x20
36 | [<ffffffff8107d8dd>] ? notifier_call_chain+0x5d/0x80
37 | [<ffffffff8107d90e>] ? __raw_notifier_call_chain+0xe/0x10
38 | [<ffffffff810598a3>] ? cpu_notify+0x23/0x40
39 | [<ffffffff8105a7b8>] ? notify_cpu_starting+0x28/0x30
40
41 during hotplug. The rawlocks need to remain however.
42
43 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
44 ---
45  kernel/stop_machine.c | 40 ++++++++--------------------------------
46  1 file changed, 8 insertions(+), 32 deletions(-)
47
48 diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
49 index 2c5acc8..f84d3b4 100644
50 --- a/kernel/stop_machine.c
51 +++ b/kernel/stop_machine.c
52 @@ -30,7 +30,7 @@ struct cpu_stop_done {
53         atomic_t                nr_todo;        /* nr left to execute */
54         bool                    executed;       /* actually executed? */
55         int                     ret;            /* collected return value */
56 -       struct task_struct      *waiter;        /* woken when nr_todo reaches 0 */
57 +       struct completion       completion;     /* fired if nr_todo reaches 0 */
58  };
59  
60  /* the actual stopper, one per every possible cpu, enabled on online cpus */
61 @@ -59,7 +59,7 @@ static void cpu_stop_init_done(struct cpu_stop_done *done, unsigned int nr_todo)
62  {
63         memset(done, 0, sizeof(*done));
64         atomic_set(&done->nr_todo, nr_todo);
65 -       done->waiter = current;
66 +       init_completion(&done->completion);
67  }
68  
69  /* signal completion unless @done is NULL */
70 @@ -68,10 +68,8 @@ static void cpu_stop_signal_done(struct cpu_stop_done *done, bool executed)
71         if (done) {
72                 if (executed)
73                         done->executed = true;
74 -               if (atomic_dec_and_test(&done->nr_todo)) {
75 -                       wake_up_process(done->waiter);
76 -                       done->waiter = NULL;
77 -               }
78 +               if (atomic_dec_and_test(&done->nr_todo))
79 +                       complete(&done->completion);
80         }
81  }
82  
83 @@ -96,22 +94,6 @@ static void cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work)
84         raw_spin_unlock_irqrestore(&stopper->lock, flags);
85  }
86  
87 -static void wait_for_stop_done(struct cpu_stop_done *done)
88 -{
89 -       set_current_state(TASK_UNINTERRUPTIBLE);
90 -       while (atomic_read(&done->nr_todo)) {
91 -               schedule();
92 -               set_current_state(TASK_UNINTERRUPTIBLE);
93 -       }
94 -       /*
95 -        * We need to wait until cpu_stop_signal_done() has cleared
96 -        * done->waiter.
97 -        */
98 -       while (done->waiter)
99 -               cpu_relax();
100 -       set_current_state(TASK_RUNNING);
101 -}
102 -
103  /**
104   * stop_one_cpu - stop a cpu
105   * @cpu: cpu to stop
106 @@ -143,7 +125,7 @@ int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
107  
108         cpu_stop_init_done(&done, 1);
109         cpu_stop_queue_work(cpu, &work);
110 -       wait_for_stop_done(&done);
111 +       wait_for_completion(&done.completion);
112         return done.executed ? done.ret : -ENOENT;
113  }
114  
115 @@ -302,7 +284,7 @@ int stop_two_cpus(unsigned int cpu1, unsigned int cpu2, cpu_stop_fn_t fn, void *
116  
117         preempt_enable_nort();
118  
119 -       wait_for_stop_done(&done);
120 +       wait_for_completion(&done.completion);
121  
122         return done.executed ? done.ret : -ENOENT;
123  }
124 @@ -364,7 +346,7 @@ static int __stop_cpus(const struct cpumask *cpumask,
125  
126         cpu_stop_init_done(&done, cpumask_weight(cpumask));
127         queue_stop_cpus_work(cpumask, fn, arg, &done, false);
128 -       wait_for_stop_done(&done);
129 +       wait_for_completion(&done.completion);
130         return done.executed ? done.ret : -ENOENT;
131  }
132  
133 @@ -495,13 +477,7 @@ repeat:
134                           kallsyms_lookup((unsigned long)fn, NULL, NULL, NULL,
135                                           ksym_buf), arg);
136  
137 -               /*
138 -                * Make sure that the wakeup and setting done->waiter
139 -                * to NULL is atomic.
140 -                */
141 -               local_irq_disable();
142                 cpu_stop_signal_done(done, true);
143 -               local_irq_enable();
144                 goto repeat;
145         }
146  }
147 @@ -663,7 +639,7 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
148         ret = multi_cpu_stop(&msdata);
149  
150         /* Busy wait for completion. */
151 -       while (atomic_read(&done.nr_todo))
152 +       while (!completion_done(&done.completion))
153                 cpu_relax();
154  
155         mutex_unlock(&stop_cpus_mutex);
156 -- 
157 1.9.1
158