AR71XX RTC
Attilio Rao
attilio at freebsd.org
Tue Jan 26 09:54:11 UTC 2010
2010/1/25 Neelkanth Natu <neelnatu at yahoo.com>:
> Hi Randall,
>
> --- On Mon, 1/25/10, Randall Stewart <rrs at lakerest.net> wrote:
>
>> From: Randall Stewart <rrs at lakerest.net>
>> Subject: Re: AR71XX RTC
>> To: "Neelkanth Natu" <neelnatu at yahoo.com>
>> Cc: "M. Warner Losh" <imp at bsdimp.com>, freebsd-mips at freebsd.org
>> Date: Monday, January 25, 2010, 12:51 PM
>> Neil:
>>
>> Thanks for the patch.. it does look good since the old
>> code was tromping part of the old threads PCB which is
>> definitely not right ;-0 .. I do have a question for you..
>> forgive my ignorance..
>>
>> What exactly are we trying to switch here. It seems
>> that cpu_switch(...) is now being called with
>> oldtd, newtd and mtx...
>>
>> I see that the thread structure has a struct mutex *td_lock
>> as
>> its first member. But what is this supposed to be pointing
>> to?
>> And when we switch are we trying to take the
>>
>> oldtd->td_lock and place it into the newtd->td_lock
>>
>> Or?
>>
>> What... I guess I just don't have any context for whats
>> going on..
>>
>
> I am not very sure about this myself so take this with a grain of salt:
>
> When a thread is being switched out because it is on a sleep queue the
> intent is that some other thread running on a different cpu should not be
> allowed to muck with this thread's state. To make this happen the 'td_lock'
> of 'oldtd' is switched from what it was originally (viz. the sleep queue
> chain lock) to 'blocked_lock'. The 'blocked_lock' is special because
> it is always locked. This all happens in sched_switch().
>
> cpu_switch() is passed the original value of 'oldtd->td_lock'
> as the third argument. When the context is switched to 'newtd' we will
> switch back the 'oldtd->td_lock' from 'blocked_lock' to its original
> value. And this way we don't lose any wakeups that may happen while we
> are in sched_switch().
>
> At least that is my very naive understanding of it. CCing Attilio to
> shed more light on this.
Hope this little explanation may give more guidance:
http://lists.freebsd.org/pipermail/svn-src-head/2010-January/014038.html
anyways, the interesting bits in, eg. i386 are:
#if defined(SMP) && defined(SCHED_ULE)
#define SETOP xchgl
#define BLOCK_SPIN(reg) \
movl $blocked_lock,%eax ; \
100: ; \
lock ; \
cmpxchgl %eax,TD_LOCK(reg) ; \
jne 101f ; \
pause ; \
jmp 100b ; \
101:
#else
#define SETOP movl
#define BLOCK_SPIN(reg)
#endif
The difference with SETOP is just for providing a rel memory barriers
vs. not providing a rel memory barrier (thus be careful, if you want
to support ULE, to follow the same logic), while BLOCK_SPIN() does:
while (oldtd->td_lock == &blocked_lock) cpu_spinwait();
still enforcing an acq memory barrier on it.
Then you may see when these functions are used, but that should be
very MD specific.
Attilio
--
Peace can only be achieved by understanding - A. Einstein
More information about the freebsd-mips
mailing list