[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YCuKJEvcoXjgaNsb@hirez.programming.kicks-ass.net>
Date: Tue, 16 Feb 2021 10:02:28 +0100
From: Peter Zijlstra <peterz@...radead.org>
To: André Almeida <andrealmeid@...labora.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
Darren Hart <dvhart@...radead.org>,
linux-kernel@...r.kernel.org, Steven Rostedt <rostedt@...dmis.org>,
Sebastian Andrzej Siewior <bigeasy@...utronix.de>,
kernel@...labora.com, krisman@...labora.com,
pgriffais@...vesoftware.com, z.figura12@...il.com,
joel@...lfernandes.org, malteskarupke@...tmail.fm,
linux-api@...r.kernel.org, fweimer@...hat.com,
libc-alpha@...rceware.org, linux-kselftest@...r.kernel.org,
shuah@...nel.org, acme@...nel.org, corbet@....net
Subject: Re: [RFC PATCH 01/13] futex2: Implement wait and wake functions
On Mon, Feb 15, 2021 at 12:23:52PM -0300, André Almeida wrote:
> +static int __futex_wait(struct futexv_head *futexv, unsigned int nr_futexes,
> + struct hrtimer_sleeper *timeout)
> +{
> + int ret;
> +
> + while (1) {
> + int awakened = -1;
> +
Might be easier to understand if the set_current_state() is here,
instead of squirreled away in futex_enqueue().
> + ret = futex_enqueue(futexv, nr_futexes, &awakened);
> +
> + if (ret) {
> + if (awakened >= 0)
> + return awakened;
> + return ret;
> + }
> +
> + /* Before sleeping, check if someone was woken */
> + if (!futexv->hint && (!timeout || timeout->task))
> + freezable_schedule();
> +
> + __set_current_state(TASK_RUNNING);
This is typically after the loop.
> +
> + /*
> + * One of those things triggered this wake:
> + *
> + * * We have been removed from the bucket. futex_wake() woke
> + * us. We just need to dequeue and return 0 to userspace.
> + *
> + * However, if no futex was dequeued by a futex_wake():
> + *
> + * * If the there's a timeout and it has expired,
> + * return -ETIMEDOUT.
> + *
> + * * If there is a signal pending, something wants to kill our
> + * thread, return -ERESTARTSYS.
> + *
> + * * If there's no signal pending, it was a spurious wake
> + * (scheduler gave us a change to do some work, even if we
chance?
> + * don't want to). We need to remove ourselves from the
> + * bucket and add again, to prevent losing wakeups in the
> + * meantime.
> + */
Anyway, doing a dequeue and enqueue for spurious wakes is a bit of an
anti-pattern that can lead to starvation. I've not actually looked at
much detail yet as this is my first read-through, but did figure I'd
mention it.
> +
> + ret = futex_dequeue_multiple(futexv, nr_futexes);
> +
> + /* Normal wake */
> + if (ret >= 0)
> + return ret;
> +
> + if (timeout && !timeout->task)
> + return -ETIMEDOUT;
> +
> + if (signal_pending(current))
> + return -ERESTARTSYS;
> +
> + /* Spurious wake, do everything again */
> + }
> +}
Powered by blists - more mailing lists