1- #include <linux/cpu.h>
2- #include <linux/cpuidle.h>
31#include <linux/kernel.h>
42#include <linux/sched.h>
5- #include <linux/tick.h>
63#include <asm/host_ops.h>
74#include <asm/cpu.h>
85#include <asm/thread_info.h>
@@ -52,12 +49,6 @@ struct lkl_cpu {
5249 lkl_thread_t owner ;
5350 /* semaphore for threads waiting the CPU */
5451 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 ;
6152 /* semaphore used for shutdown */
6253 struct lkl_sem * shutdown_sem ;
6354} cpu ;
@@ -134,7 +125,8 @@ void lkl_cpu_put(void)
134125 lkl_ops -> mutex_lock (cpu .lock );
135126 }
136127
137- if (need_resched () && cpu .count == 1 ) {
128+ if (test_ti_thread_flag (current_thread_info (), TIF_HOST_THREAD ) &&
129+ need_resched () && cpu .count == 1 ) {
138130 if (in_interrupt ())
139131 lkl_bug ("%s: in interrupt\n" , __func__ );
140132 lkl_ops -> mutex_unlock (cpu .lock );
@@ -191,8 +183,6 @@ static void lkl_cpu_cleanup(bool shutdown)
191183 lkl_ops -> sem_up (cpu .shutdown_sem );
192184 else if (cpu .shutdown_sem )
193185 lkl_ops -> sem_free (cpu .shutdown_sem );
194- if (cpu .idle_sem )
195- lkl_ops -> sem_free (cpu .idle_sem );
196186 if (cpu .sem )
197187 lkl_ops -> sem_free (cpu .sem );
198188 if (cpu .lock )
@@ -215,91 +205,20 @@ void arch_cpu_idle(void)
215205 /* enable irqs now to allow direct irqs to run */
216206 local_irq_enable ();
217207
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 ();
246210}
247211
248212int lkl_cpu_init (void )
249213{
250214 cpu .lock = lkl_ops -> mutex_alloc (0 );
251215 cpu .sem = lkl_ops -> sem_alloc (0 );
252- cpu .idle_sem = lkl_ops -> sem_alloc (0 );
253216 cpu .shutdown_sem = lkl_ops -> sem_alloc (0 );
254217
255- if (!cpu .lock || !cpu .sem || !cpu .idle_sem || ! cpu . shutdown_sem ) {
218+ if (!cpu .lock || !cpu .sem || !cpu .shutdown_sem ) {
256219 lkl_cpu_cleanup (false);
257220 return - ENOMEM ;
258221 }
259222
260223 return 0 ;
261224}
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