From: Darren Hart on
Thomas Gleixner wrote:
> On Tue, 6 Apr 2010, Ulrich Drepper wrote:
>
>> On Tue, Apr 6, 2010 at 12:31, Thomas Gleixner <tglx(a)linutronix.de> wrote:
>>> We need to figure out a more efficient way to
>>> do the spinning in the kernel where we have all the necessary
>>> information already.
>> Really? The owner information isn't in general available in the
>> kernel. Futex operation doesn't require the value used to be the PID
>> (or negative of the PID). That is a dramatic limitation of the
>> usefulness of futexes.
>
> I know that you can do any weird stuff with the futex value, but I
> don't see the "dramatic" limitation. Care to elaborate ?
>
>> At userlevel there is access to other fields of the data structure
>> which can contain the owner information.
>>
>> I would like to see the method using a per-thread pinned page and an
>> update of a memory location on scheduling. For benchmarking at least.
>
> The per thread pinned page would be unconditional, right ?
>
> I agree that benchmarking would be interesting, but OTOH I fear that
> we open up a huge can of worms with exposing scheduler details and the
> related necessary syscalls like sys_yield_to: User space thread
> management/scheduling comes to my mind and I hope we agree that we do
> not want to revisit that.
>
>> I agree that a sys_yield_to() syscall would be at the very least
>> useful as well. But it's useful for other things already.
>
> Useful for what ?
>
> What are the exact semantics of such a syscall ?
>
> How does that fit into the various scheduling constraints ?


I believe this comes back to the discussions of a directed yield. The
idea being that a thread yields its remaining timeslice to a thread of
it's choosing - usually because the target thread holds a resource the
yielding thread needs access to. This makes the yield more explicit so
the yielding thread is more likely to get some benefit out of yielding.

I believe the arguments would be either a TID or a thread group -
however that is specified. I believe the KVM guys would like to see
something like this as well - which might be the "other things" referred
to above.

--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Avi Kivity on
On 04/06/2010 10:31 PM, Thomas Gleixner wrote:
>
>> That gives you something along the lines of
>>
>> runaddr = find_run_flag(lock);
>> do {
>> while(*runaddr == RUNNING) {
>> if (trylock(lock))
>> return WHOOPEE;
>> cpu relax
>> }
>> yield (_on(thread));
>>
> That would require a new yield_to_target() syscall, which either
> blocks the caller when the target thread is not runnable or returns an
> error code which signals to go into the slow path.
>

Note, directed yield is something that kvm wants for its own ends. As
an internal kernel api, not a syscall, but it's apparently useful.

--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: john cooper on
Avi Kivity wrote:
> On 04/06/2010 07:14 PM, Thomas Gleixner wrote:
>>
>>> IMO the best solution is to spin in userspace while the lock holder is
>>> running, fall into the kernel when it is scheduled out.
>>>
>> That's just not realistic as user space has no idea whether the lock
>> holder is running or not and when it's scheduled out without a syscall :)
>>
>
> The kernel could easily expose this information by writing into the
> thread's TLS area.
>
> So:
>
> - the kernel maintains a current_cpu field in a thread's tls
> - lock() atomically writes a pointer to the current thread's current_cpu
> when acquiring
> - the kernel writes an invalid value to current_cpu when switching out
> - a contended lock() retrieves the current_cpu pointer, and spins as
> long as it is a valid cpu

There are certainly details to sort through in the packaging
of the mechanism but conceptually that should do the job.
So here the application has chosen a blocking lock as being
the optimal synchronization operation and we're detecting a
scenario where we can factor out the aggregate overhead of two
context switch operations.

There is also the case where the application requires a
polled lock with the rational being the assumed lock
hold/wait time is substantially less than the above context
switch overhead. But here we're otherwise completely
open to indiscriminate scheduling preemption even though
we may be holding a userland lock.

The adaptive mutex above is an optimization beyond what
is normally expected for the associated model. The preemption
of a polled lock OTOH can easily inflict latency several orders
of magnitude beyond what is expected in that model. Two use
cases exist here which IMO aren't related except for the latter
unintentionally degenerating into the former.

-john

--
john.cooper(a)third-harmonic.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Darren Hart on
john cooper wrote:
> Avi Kivity wrote:
>> On 04/06/2010 07:14 PM, Thomas Gleixner wrote:
>>>> IMO the best solution is to spin in userspace while the lock holder is
>>>> running, fall into the kernel when it is scheduled out.
>>>>
>>> That's just not realistic as user space has no idea whether the lock
>>> holder is running or not and when it's scheduled out without a syscall :)
>>>
>> The kernel could easily expose this information by writing into the
>> thread's TLS area.
>>
>> So:
>>
>> - the kernel maintains a current_cpu field in a thread's tls
>> - lock() atomically writes a pointer to the current thread's current_cpu
>> when acquiring
>> - the kernel writes an invalid value to current_cpu when switching out
>> - a contended lock() retrieves the current_cpu pointer, and spins as
>> long as it is a valid cpu
>
> There are certainly details to sort through in the packaging
> of the mechanism but conceptually that should do the job.
> So here the application has chosen a blocking lock as being
> the optimal synchronization operation and we're detecting a
> scenario where we can factor out the aggregate overhead of two
> context switch operations.

I didn't intend to change the behavior of an existing blocking call with
adaptive spinning if that is what you are getting at here. Initially
there would be a new futex op, something like FUTEX_LOCK_ADAPTIVE or
maybe just FUTEX_WAIT_ADAPTIVE. Applications can use this directly to
implement adaptive spinlocks. Ideally glibc would make use of this via
either the existing adaptive spinning NP API or via a new one. Before we
even go there, we need to see if this can provide a real benefit.

>
> There is also the case where the application requires a
> polled lock with the rational being the assumed lock
> hold/wait time is substantially less than the above context
> switch overhead.

Polled lock == userspace spinlock?

> But here we're otherwise completely
> open to indiscriminate scheduling preemption even though
> we may be holding a userland lock.

That's true with any userland lock.

> The adaptive mutex above is an optimization beyond what
> is normally expected for the associated model. The preemption
> of a polled lock OTOH can easily inflict latency several orders
> of magnitude beyond what is expected in that model. Two use
> cases exist here which IMO aren't related except for the latter
> unintentionally degenerating into the former.

Again, my intention is not to replace any existing functionality, so
applications would have to explicitly request this behavior.

If I'm missing your point, please elaborate.

Thanks,

--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Darren Hart on
drepper(a)gmail.com wrote:
> On Tue, Apr 6, 2010 at 16:16, Thomas Gleixner <tglx(a)linutronix.de> wrote:
>> I know that you can do any weird stuff with the futex value, but I
>> don't see the "dramatic" limitation. Care to elaborate ?
>
> If we have to fill in the PID we can represent only three states in a
> futex: 0, PID, -PID. Today we can represent 2^32 states. Quite a
> difference.

For general futexes sure, but not for robust or PI mutexes. Having
adaptive futexes be based on the TID|WAITERS_FLAG policy certainly isn't
breaking new ground, and is consistent with the other kernel-side futex
locking implementations.

However, I agree that a FUTEX_SET_WAIT_ADAPTIVE sort of call might be
very powerful. However, that might be just academic until I can show an
improvement with adaptive futexes.

>> The per thread pinned page would be unconditional, right ?
>
> Only if the process would be using these adaptive mutexes. It could be
> conditional.

What about the concern of this TLS approach only working for process
private locks? I would very much like to make this work for both shared
and private locks.

Thanks,

--
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/