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