Subject: Is there any way to tell if the current thread has a user context?
To: None <tech-kern@netbsd.org>
From: Alan Ritter <rittera@cc.wwu.edu>
List: tech-kern
Date: 08/31/2005 18:22:20
Hello all,

I'm working on porting the FreeBSD NDIS code to NetBSD, and trying to iron out all
the synchronization issues.  I have a driver for an Intel Pro/100 card that is
semi-functional (things like ssh work just fine, but transferring larger amounts of
data causes synchronization problems).

I think my problem is that there are numerous functions in the FreeBSD NDIS code
that are called from both the top and bottom half of the kernel.  In FreeBSD they
just use locks to synchronize access, as FreeBSD interrupts run in a thread context,
so the kernel can go to sleep in an interrupt (FreeBSD doesn't even halve the
splXXX() functions).  Anyway what I want to be able to do is raise the IPL and
acquire a lockmgr lock if I'm in the top half, but just raise the IPL if I'm in the
bottom.  I still need to raise the IPL in the bottom half because these functions
get called at multiple different priority interrupts in the bottom half, so for
instance I would need to raise the IPL in a function called from the callout
facility (IPL_SOFTCLOCK) to IPL_NET to block against device interrupts.  Anyway,
here's a general outline of what I've been doing so far:

s = splnet()
if(curlwp != NULL) {
    lockmgr(&lock, LK_EXCLUSIVE, NULL);
}

... critical section ...

if(curlwp != NULL) {
    lockmgr(&lock, LK_RELEASE, NULL);
}
splx(s);

but from running the kernel debugger it seems that sometimes while in my interrupt
handler curlwp points to a "struct lwp" from a thread that was previously running. 
I was thinking this was the way I could tell if I was in the top or bottom half of
the kernel, as I noticed that's what gets checked in the source for lockmgr (in
sys/kern/kern_lock.c) to see if there's no context.

Anyway, I'm just wondering if there's any way for me to check if there is a context,
and if so how to do it.  If not I may end up having to completely restructure a lot
of the FreeBSD code.

Thanks :-)