tech-kern archive

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

Re: 4.x -> 5.x locking?



On Nov,Wednesday 9 2011, at 8:40 AM, Mouse wrote:

> I've got some questions about locking.
> 
> I've got some kernel code to move from 4.x to 5.x.  Looking at it, I
> can see it effectively assumes the kernel is giantlocked: it assumes
> that at most one CPU is executing in the kernel.  (This particular code
> never runs in device interrupt context, though it may get called from
> callouts and the like.)  I seem to recall being told, when I asked more
> or less this question on the lists some time back, that this was a safe
> assumption under 4.x - and, indeed the thing seems to work on 4.x.

You can still have non MP-SAFE drivers in netbsd-5 these days. If you do not 
set D_MPSAFE flag they will be giant-locked[1], [2], [3].

Most benefit in moving from 4->5 is that in 5 you can have MPSAFE drivers which 
was not possible in 4.

[1] http://nxr.netbsd.org/source/xref/src/sys/sys/conf.h#D_MPSAFE
[2] http://nxr.netbsd.org/xref/src/sys/dev/dm/device-mapper.c#87
[3] http://nxr.netbsd.org/xref/src/sys/kern/subr_devsw.c#682


> 
> Thus, my first question: is this also true of 5.x?
> 
> I found mutex(9), condvar(9), and the like.  But it is not clear to me
> what I need to do to be MP-ready.  Do I need to use the stuff from
> mb(9), or membar_ops(3), or what?  It's not clear from the manpages
> whether, for example, membar_enter is usable within the kernel; the
> reference from mutex(9) seems to imply so, but I've been surprised
> before.  It's also not clear whether it would even work; I see no
> statements promising that if I, for example, do
> 

Typical locking algorithm might look like this 

Worker(aka consumer):

mutex_enter(mtx)
        workers++;
mutext_exit(mtx)
        Do very important consumer job..
        ....
mutex_enter(mtx)
        workers--;
        if (workers == 0)
                cv_wakeup(cv)
mutext_exit(mtx)

a) workers keep info about amount of threads inside your kernel 
   doing some job if we get to zero we trry to wakeup all waiters 
   which are sitting on cv while there are workers in driver.

b) we do as less work inside of mutex covered area as possible.

Producer:

mutex_enter(mtx)

if (workers != 0)
        cv_wait(cv, mtx);

Do very important producer stuff;
....

mutex_exit(mtx)

a) Producer needs to wait on cv until there is no consumer in 
   kernel, then it can do it's job.

b) In cv_wait mtx is used this mutex is released before thread 
   went to sleep and acquired before it's woken up, which means 
   that you can safely do required work in side mtx guarded 
   producer area.  


Regards

Adam.



Home | Main Index | Thread Index | Old Index