Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jul 2001 00:16:33 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        y-carden@uniandes.edu.co
Cc:        hackers@FreeBSD.ORG, gvega@uniandes.edu.co
Subject:   Re: Invoking a userland function from kernel
Message-ID:  <3B5E7251.CCECCCC4@mindspring.com>
References:  <M2001072407265003947@vaca.uniandes.edu.co>

next in thread | previous in thread | raw e-mail | index | archive | help
y-carden@uniandes.edu.co wrote:
> 
> I need pass asynchronously data from kernel
> to a userland process, include a quantity variable of
> data (void *opaque).

The easiest way to do this is to have the user space process
register a kevent, and then KNOTE() in the kernel when the
event takes place.

Another way to do this is to create a pseduo device driver,
and read the data in user space.

What it really sounds like you want is callbacks into user
space from the kernel, a la VMS AST's (Asynchornous System
Traps).  To implement true AST's, you need to know that the
kernel runs in supervisor mode, and the user space runs in
user mode, and that these correspond to "rong 0" and "ring 3"
protection domains for protected mode Intel processors,
respectively.  To implement AST's correctly, you would need
to run them in "system mode", which in the Intel processor
vernacular, would be "ring 2".

I recommend against doing this.


An alternate method of doing this would be to use a signal;
if that doesn't provide a general enough call context for
"making calls to user space", then you probably need to wedge
your code into the singla trampoline, and deal with it that
way, instead.

Finally, you may want to use a FIFO or SYSV IPC endpoints in
user space, written from kernel space.  This can be done, but
it will end up taking some work on your part, since the send
and write routines were never designed properly to be called
from kernel space.


> I think that this is similar to upward flow data mechanism in the
> network subsystem.  The data received at a network interface
> flow upward through communications protocols until they are placed
> in receive  queue of  destination socket, the system schedules
> protocol processing from the network interface layer by marking a
> bit assigned to the protocol in the system's network
> interrupt status, and posting a software interrupt reserved
> for triggering network activity. Software interrupts are used to
> schedule asynchronous network activity.

No.  This is not how software interrupts work.  Software
interrupts work by calling them when the splx() call is
executed, causing them to be unblocked.  Look at the splz()
code in the assmebler source files in /sys/i386/i386/.

In the netowrk case, a hardware interrupt is taken which
causes mbuf's to be queued for processing at non-interrupt
time.  When the hardware interrupt completes, and splx()
is later called within the kernel (the interrupt could have
interrupted a user space process, not just a kernel space
procedure), then the unmasking of the splnet() interrupt
level results in the software interrupt list being called
for newly unmasked software interrupts, including NETISR.

The NETISR outcall is established with interrupt registration
via sysctl (grep for ipintr), which dequeues the mbuf off
the queue, and passes it to ip_input() -- or whatever protocol
software interrupt handler is appropriate.  This in turn
pushes it up to the point where no more processing can occur
outside the context of a user process, and puts the mbuf,
socket, or whatever other result onto a queue.  When the
process runs, it harvests the queue via a system call.

In other words, it all occurs in kernel space.

For a good grounding in how this works, look at how the
bind(2) call results in connection events as a result of
incoming syn/synack/ack events, and how the "accept" call
"reaps" these throu sooaccept and the code path in the
/sys/kern/uipc_socket*.c code.


> But I don't know how I can trigger this software interrupts
> from my code into the FreeBSD kernel.

You can't; at least, you can't do exactly that.  As others
have pointed out, you would have better luck telling us what
problem it is you are trying to solve, and then letting
people suggest solutions, instead of picking "the one true
solution", and then asking us how to implement it.

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3B5E7251.CCECCCC4>