From owner-freebsd-hackers Wed Jul 25 0:16:32 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from avocet.mail.pas.earthlink.net (avocet.mail.pas.earthlink.net [207.217.121.50]) by hub.freebsd.org (Postfix) with ESMTP id 1BC5D37B401 for ; Wed, 25 Jul 2001 00:16:26 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from mindspring.com (dialup-209.245.141.74.Dial1.SanJose1.Level3.net [209.245.141.74]) by avocet.mail.pas.earthlink.net (EL-8_9_3_3/8.9.3) with ESMTP id AAA09848; Wed, 25 Jul 2001 00:15:54 -0700 (PDT) Message-ID: <3B5E7251.CCECCCC4@mindspring.com> Date: Wed, 25 Jul 2001 00:16:33 -0700 From: Terry Lambert Reply-To: tlambert2@mindspring.com X-Mailer: Mozilla 4.7 [en]C-CCK-MCD {Sony} (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: y-carden@uniandes.edu.co Cc: hackers@FreeBSD.ORG, gvega@uniandes.edu.co Subject: Re: Invoking a userland function from kernel References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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