tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Reviving SA: what is up with preempt() generating BLOCKED upcalls?

On May 10, 2008, at 9:40 PM, Bill Stouder-Studenmund wrote:

As part of reviving SA, I'm re-adding all of the kernel infrastructure we
ripped out.

In doing this, I looked at re-adding the preempt(int more) code we had.
However, I have serious questions about it. Like why do it?

We call preempt() when we want to give the scheduler a convenient moment
to run something else. In -current, we do this at some times when we
realize another thread/sub-system has requested we do this
(curcpu()->ci_want_resched set for instance).

I believe we send a BLOCKED upcall to the process because this thread of
execution has stopped. The thing however is we send the upcall when
mi_switch() returns (and in the case when we actually ran a different
thread). So we send the BLOCKED upcall _after_ we were blocked, not
before/durring like we do for blocking. Among other things, we send the BLOCKED upcall after we not only hop away, but after we hop back. So we
have in effect UNBLOCKED at the time when we send the BLOCKED upcall.

Further, we aren't blocked. I understand the BLOCKED upcall to be a way for libpthread to schedule something else on the virtual CPU that we were running on. However a call to mi_switch() does not represent a point at
which libpthread can schedule something else on our virtual CPU - our
thread is still runable in the eyes of the kernel scheduler, so it will
hop back to it when it decides to. And we generate an UNBLOCKED upcall
when we get back to userland. Most importantly, we don't offer a new lwp
to userland on which it can run threads.

So the net effect will be we pull the user thread that triggered code that blocked off of the (front of the) run queue, put it on the back of the run
queue, then go back to running.

I note that there are/were only two places in the code that call
preempt(0), sys_sched_yield() and midiwrite(). I really don't understand why midiwrite() calls preempt(0) other than probably the fact that chap
wasn't sure what to do when he added the code in 2006.

I think sched_yield is the one place where we would want to do this
rescheduling. However I think it's much cleaner on the whole kernel to
just have sched_yield just manually inject a BLOCKED upcall. When we get back to userland we will auto-generate an unblocked upcall too, so we will
rattle the userland run queues.

Intercepting sched_yield() in userland is a better way to go, but this
branch is about compatability at this point. :-)

I realize I have been somewhat thinking out loud; I now better understand the problem than I did when i started writing this EMail. However anyone
have any thoughts on this?

Take care,

You went from LSONPROC to LSRUN and that's shouldn't cause an BLOCKED upcall. I think a BLOCKED upcall should be sent iff the state changed to LSSLEEP. I also think if a change to LSSTOP or LSSUSPENDED happens an upcall should not be sent since an external party want the lwp/proc to stop execution and
switching to a new one to continue execution just seems wrong.

Home | Main Index | Thread Index | Old Index