diff --git a/repos/dde_linux/src/include/lx_emul/time.h b/repos/dde_linux/src/include/lx_emul/time.h index 7f560b75c0..dabd2e43df 100644 --- a/repos/dde_linux/src/include/lx_emul/time.h +++ b/repos/dde_linux/src/include/lx_emul/time.h @@ -28,6 +28,8 @@ unsigned long long lx_emul_time_counter(void); void lx_emul_time_handle(void); +void lx_emul_time_update_jiffies(void); + #ifdef __cplusplus } #endif diff --git a/repos/dde_linux/src/lib/lx_emul/clocksource.c b/repos/dde_linux/src/lib/lx_emul/clocksource.c index fe6cbedcc2..5ddc520d8a 100644 --- a/repos/dde_linux/src/lib/lx_emul/clocksource.c +++ b/repos/dde_linux/src/lib/lx_emul/clocksource.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -109,6 +111,24 @@ void lx_emul_time_handle(void) } +extern ktime_t tick_next_period; +void lx_emul_time_update_jiffies(void) +{ + /* check if jiffies need an update */ + if (ktime_before(ktime_get(), tick_next_period)) + return; + + /* tick_nohz_idle_stop_tick breaks with error if softirq is pending */ + if (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK) + return; + + tick_nohz_idle_enter(); + tick_nohz_idle_stop_tick(); + tick_nohz_idle_restart_tick(); + tick_nohz_idle_exit(); +} + + enum { LX_EMUL_MAX_OF_CLOCK_PROVIDERS = 256 }; diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/kernel/sched/core.c b/repos/dde_linux/src/lib/lx_emul/shadow/kernel/sched/core.c index 8ea839d7d3..a9ee03858a 100644 --- a/repos/dde_linux/src/lib/lx_emul/shadow/kernel/sched/core.c +++ b/repos/dde_linux/src/lib/lx_emul/shadow/kernel/sched/core.c @@ -103,14 +103,12 @@ static void __schedule(void) asmlinkage __visible void __sched schedule(void) { + lx_emul_time_update_jiffies(); + if (current->__state) { unsigned int task_flags = current->flags; - if (task_flags & PF_WQ_WORKER) { - tick_nohz_idle_enter(); - lx_emul_time_handle(); - tick_nohz_idle_exit(); + if (task_flags & PF_WQ_WORKER) wq_worker_sleeping(current); - } } __schedule(); @@ -141,6 +139,7 @@ asmlinkage __visible void __sched notrace preempt_schedule(void) if (likely(!preemptible())) return; + lx_emul_time_update_jiffies(); __schedule(); } @@ -150,6 +149,7 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) if (likely(!preemptible())) return; + lx_emul_time_update_jiffies(); __schedule(); }