On Thu, Jan 13, 2022 at 03:39:40PM -0800, Peter Oskolkov wrote: > --- > include/uapi/linux/umcg.h | 10 ++++++++++ > kernel/sched/umcg.c | 7 +++++-- > 2 files changed, 15 insertions(+), 2 deletions(-) > > diff --git a/include/uapi/linux/umcg.h b/include/uapi/linux/umcg.h > index 93fccb44283b..a29e5e91a251 100644 > --- a/include/uapi/linux/umcg.h > +++ b/include/uapi/linux/umcg.h > @@ -148,4 +148,14 @@ enum umcg_ctl_flag { > UMCG_CTL_WORKER = 0x10000, > }; > > +/** > + * enum umcg_kick_flag - flags to pass to sys_umcg_kick > + * @UMCG_KICK_RESCHED: reschedule the task; used for worker preemption > + * @UMCG_KICK_TTWU: wake the task; used to wake servers > + */ > +enum umcg_kick_flag { > + UMCG_KICK_RESCHED = 0x001, > + UMCG_KICK_TTWU = 0x002, > +}; > + > #endif /* _UAPI_LINUX_UMCG_H */ > diff --git a/kernel/sched/umcg.c b/kernel/sched/umcg.c > index b85dec6b82e4..e33ec9eddc3e 100644 > --- a/kernel/sched/umcg.c > +++ b/kernel/sched/umcg.c > @@ -669,12 +669,15 @@ SYSCALL_DEFINE2(umcg_kick, u32, flags, pid_t, tid) > if (!task) > return -ESRCH; > > - if (flags) > + if (flags != UMCG_KICK_RESCHED && flags != UMCG_KICK_TTWU) > return -EINVAL; > > #ifdef CONFIG_SMP > - smp_send_reschedule(task_cpu(task)); > + if (flags == UMCG_KICK_RESCHED) > + smp_send_reschedule(task_cpu(task)); > #endif > + if (flags == UMCG_KICK_TTWU) > + try_to_wake_up(task, TASK_NORMAL, 0); > > return 0; > } I'm thinking the simpler thing is this.. (also note the task ref leak fixed) --- a/kernel/sched/umcg.c +++ b/kernel/sched/umcg.c @@ -719,16 +719,22 @@ void umcg_notify_resume(struct pt_regs * */ SYSCALL_DEFINE2(umcg_kick, u32, flags, pid_t, tid) { - struct task_struct *task = umcg_get_task(tid); - if (!task) - return -ESRCH; + struct task_struct *task; if (flags) return -EINVAL; + + task = umcg_get_task(tid); + if (!task) + return -ESRCH; + if (!try_to_wake_up(task, TASK_NORMAL, WF_CURRENT_CPU)) { #ifdef CONFIG_SMP - smp_send_reschedule(task_cpu(task)); + smp_send_reschedule(task_cpu(task)); #endif + } + + put_task_struct(task); return 0; }