1
- #include <linux/cpu.h>
2
- #include <linux/cpuidle.h>
3
1
#include <linux/kernel.h>
4
2
#include <linux/sched.h>
5
- #include <linux/tick.h>
6
3
#include <asm/host_ops.h>
7
4
#include <asm/cpu.h>
8
5
#include <asm/thread_info.h>
@@ -52,12 +49,6 @@ struct lkl_cpu {
52
49
lkl_thread_t owner ;
53
50
/* semaphore for threads waiting the CPU */
54
51
struct lkl_sem * sem ;
55
- /* semaphore for the idle thread */
56
- struct lkl_sem * idle_sem ;
57
- /* if the idle thread is pending */
58
- bool idle_pending ;
59
- /* jmp_buf used for idle thread to restart */
60
- struct lkl_jmp_buf idle_jb ;
61
52
/* semaphore used for shutdown */
62
53
struct lkl_sem * shutdown_sem ;
63
54
} cpu ;
@@ -134,7 +125,8 @@ void lkl_cpu_put(void)
134
125
lkl_ops -> mutex_lock (cpu .lock );
135
126
}
136
127
137
- if (need_resched () && cpu .count == 1 ) {
128
+ if (test_ti_thread_flag (current_thread_info (), TIF_HOST_THREAD ) &&
129
+ !single_task_running () && cpu .count == 1 ) {
138
130
if (in_interrupt ())
139
131
lkl_bug ("%s: in interrupt\n" , __func__ );
140
132
lkl_ops -> mutex_unlock (cpu .lock );
@@ -191,8 +183,6 @@ static void lkl_cpu_cleanup(bool shutdown)
191
183
lkl_ops -> sem_up (cpu .shutdown_sem );
192
184
else if (cpu .shutdown_sem )
193
185
lkl_ops -> sem_free (cpu .shutdown_sem );
194
- if (cpu .idle_sem )
195
- lkl_ops -> sem_free (cpu .idle_sem );
196
186
if (cpu .sem )
197
187
lkl_ops -> sem_free (cpu .sem );
198
188
if (cpu .lock )
@@ -215,91 +205,20 @@ void arch_cpu_idle(void)
215
205
/* enable irqs now to allow direct irqs to run */
216
206
local_irq_enable ();
217
207
218
- if (need_resched ())
219
- return ;
220
-
221
- cpu .idle_pending = true;
222
- lkl_cpu_put ();
223
-
224
- lkl_ops -> sem_down (cpu .idle_sem );
225
-
226
- cpu .idle_pending = false;
227
- /* to match that of schedule_preempt_disabled() */
228
- preempt_disable ();
229
- lkl_ops -> jmp_buf_longjmp (& cpu .idle_jb , 1 );
230
- }
231
-
232
- void arch_cpu_idle_prepare (void )
233
- {
234
- set_ti_thread_flag (current_thread_info (), TIF_IDLE );
235
- /*
236
- * We hijack the idle loop here so that we can let the idle thread
237
- * jump back to the beginning.
238
- */
239
- while (1 )
240
- lkl_ops -> jmp_buf_set (& cpu .idle_jb , do_idle );
241
- }
242
-
243
- void lkl_cpu_wakeup_idle (void )
244
- {
245
- lkl_ops -> sem_up (cpu .idle_sem );
208
+ /* switch to idle_host_task */
209
+ wakeup_idle_host_task ();
246
210
}
247
211
248
212
int lkl_cpu_init (void )
249
213
{
250
214
cpu .lock = lkl_ops -> mutex_alloc (0 );
251
215
cpu .sem = lkl_ops -> sem_alloc (0 );
252
- cpu .idle_sem = lkl_ops -> sem_alloc (0 );
253
216
cpu .shutdown_sem = lkl_ops -> sem_alloc (0 );
254
217
255
- if (!cpu .lock || !cpu .sem || !cpu .idle_sem || ! cpu . shutdown_sem ) {
218
+ if (!cpu .lock || !cpu .sem || !cpu .shutdown_sem ) {
256
219
lkl_cpu_cleanup (false);
257
220
return - ENOMEM ;
258
221
}
259
222
260
223
return 0 ;
261
224
}
262
-
263
- /*
264
- * Simulate the exit path of idle loop so that we can schedule when LKL is
265
- * in idle.
266
- * It's just a duplication of those in idle.c so a better way is to refactor
267
- * idle.c to expose such function.
268
- */
269
- void lkl_idle_tail_schedule (void )
270
- {
271
-
272
- if (!cpu .idle_pending ||
273
- !test_bit (TIF_IDLE , & current_thread_info ()-> flags ))
274
- lkl_bug ("%s: not in idle\n" , __func__ );
275
-
276
- start_critical_timings ();
277
- __current_set_polling ();
278
-
279
- if (WARN_ON_ONCE (irqs_disabled ()))
280
- local_irq_enable ();
281
-
282
- rcu_idle_exit ();
283
- arch_cpu_idle_exit ();
284
- preempt_set_need_resched ();
285
- tick_nohz_idle_exit ();
286
- __current_clr_polling ();
287
-
288
- /*
289
- * memory barrier copied from idle.c
290
- */
291
- smp_mb__after_atomic ();
292
-
293
- /*
294
- * Didn't find a way to include kernel/sched/sched.h for
295
- * sched_ttwu_pending().
296
- * Anyway, it's no op when not CONFIG_SMP.
297
- */
298
-
299
- schedule_preempt_disabled ();
300
- }
301
-
302
- int lkl_cpu_idle_pending (void )
303
- {
304
- return cpu .idle_pending ;
305
- }
0 commit comments