On Fri, Nov 26, 2021 at 10:59:44PM +0100, Peter Zijlstra wrote: > That seems to loose the freezable crud.. then again, since we're > interruptible, that shouldn't matter. Lemme go do that. --- --- a/kernel/sched/umcg.c +++ b/kernel/sched/umcg.c @@ -52,7 +52,7 @@ static int umcg_pin_pages(void) server = umcg_get_task(server_tid); if (!server) - return -EINVAL; + return -ESRCH; if (pin_user_pages_fast((unsigned long)self, 1, 0, &tsk->umcg_worker_page) != 1) @@ -358,18 +358,10 @@ int umcg_wait(u64 timo) { struct task_struct *tsk = current; struct umcg_task __user *self = tsk->umcg_task; - struct hrtimer_sleeper timeout; struct page *page = NULL; u32 state; int ret; - if (timo) { - hrtimer_init_sleeper_on_stack(&timeout, tsk->umcg_clock, - HRTIMER_MODE_ABS); - hrtimer_set_expires_range_ns(&timeout.timer, (s64)timo, - tsk->timer_slack_ns); - } - for (;;) { set_current_state(TASK_INTERRUPTIBLE); @@ -415,22 +407,16 @@ int umcg_wait(u64 timo) break; } - if (timo) - hrtimer_sleeper_start_expires(&timeout, HRTIMER_MODE_ABS); - - freezable_schedule(); - - ret = -ETIMEDOUT; - if (timo && !timeout.task) + if (!schedule_hrtimeout_range_clock(timo ? &timo : NULL, + tsk->timer_slack_ns, + HRTIMER_MODE_ABS, + tsk->umcg_clock)) { + ret = -ETIMEDOUT; break; + } } __set_current_state(TASK_RUNNING); - if (timo) { - hrtimer_cancel(&timeout.timer); - destroy_hrtimer_on_stack(&timeout.timer); - } - return ret; } @@ -515,7 +501,8 @@ void umcg_notify_resume(struct pt_regs * goto done; if (state & UMCG_TF_PREEMPT) { - umcg_pin_pages(); + if (umcg_pin_pages()) + goto die; if (umcg_update_state(tsk, UMCG_TASK_RUNNING, UMCG_TASK_RUNNABLE, &next_tid)) @@ -586,7 +573,9 @@ SYSCALL_DEFINE2(umcg_wait, u32, flags, u tsk->flags &= ~PF_UMCG_WORKER; /* see umcg_sys_{enter,exit}() */ - umcg_pin_pages(); + ret = umcg_pin_pages(); + if (ret) + return ret; ret = umcg_update_state(tsk, UMCG_TASK_RUNNING, UMCG_TASK_RUNNABLE, &next_tid); if (ret)