On 29-May-2002 Seigo Tanimura wrote:

>>> And the p4 depot
>>> //depot/user/tanimura/ippreempt/...
>>> The patch is for only i386 at the moment.
>>> The following is the brief description of the patch:
> jhb> I would prefer that this was hung off the preemption stuff I've already done
> jhb> rather than reinventing it.  I would also prefer that we get a preemptive
> jhb> kernel w/o this done stable before adding extra complication.
> Or I can integrate your work in //depot/user/jhb/preemption/... into
> //depot/user/tanimura/ippreempt/... .

I think we should do the more cautious step first.

>>> Miscellaneous stuff:
>>> If a thread spins for an adaptive mutex, propagate its priority to the
>>> owner thread of the mutex.  This prevents preemption of the owner
>>> thread by a thread with the priority in between the owner thread and
>>> the spinning thread.
> jhb> Ewww, I'd rather avoid this if possible.  This is just an optimization,
> jhb> but it would depend on how complicated this makes the mutex code to see
> jhb> if it's worth it or not.
> The owner thread of an adaptive mutex never lowers its priority until
> it releases the mutex.  We should thus bump the priority of the owner
> thread not during but just before spinning.  However, it is difficult
> to know if the current thread can spin prior to calling
> _obtain_lock().
> In addition, I would say that spinning can be done even more
> efficiently.  At the moment, we try an atomic test-and-set
> instruction in each spin.  As another thread holds the mutex, we are
> likely to execute an expensive test-and-set instruction quite a lot of
> times.
> Maybe we can solve both of the issues above by roughly checking if a
> thread can keep spinning without acquiring any locks, in the similar
> way as we do for a spin mutex.  First, test the following conditions:
> - The owner of the mutex has not changed.
> - The owner is on a processor.
> If both of the conditions satisfy, keep spinning.  Otherwise, try
> test-and-set.  The pseudo-code would look like this:
> while (!_obtain_lock(m, td)) {
>       mtx_lock_spin(&sched_lock);
>       if (unowned(m)) {
>               mutex_unlock_spin(&sched_lock);
>               continue;
>       }
>       owner = mtx_owner(m);
>       if (oncpu(owner)) {

You can not treat owner as valid unless you hold sched_lock() and
MTX_CONTESTED is set in m->mtx_lock.  Thus, the value can go stale
and you could potentially be dereferencing an invalid pointer below.

>               /* Spin without holding sched_lock. */
>               critical_enter();
>               mtx_unlock_spin(&sched_lock);

The critical section here would not be necessary I think, but you can't
read owner's value and know it is not stale if you don't hold sched_lock.
(Eventually to be replaced with a turnstile chain lock.)

One thing we might be able to do better is to change the code in the
adaptive spinning test to wait for mtx_lock to change before trying the
test-and-set again, this is a fairly simple change that isn't very hard
to do.


John Baldwin <[EMAIL PROTECTED]>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to