From owner-freebsd-hackers Mon Dec 1 12:48:11 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id MAA15155 for hackers-outgoing; Mon, 1 Dec 1997 12:48:11 -0800 (PST) (envelope-from owner-freebsd-hackers) Received: from dyson.iquest.net (dyson.iquest.net [198.70.144.127]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id MAA15040 for ; Mon, 1 Dec 1997 12:47:18 -0800 (PST) (envelope-from toor@dyson.iquest.net) Received: (from root@localhost) by dyson.iquest.net (8.8.7/8.8.8) id PAA00811; Mon, 1 Dec 1997 15:42:35 -0500 (EST) (envelope-from toor) From: "John S. Dyson" Message-Id: <199712012042.PAA00811@dyson.iquest.net> Subject: Re: copyout()/copyin() In-Reply-To: <199712011952.LAA10723@grayling.erg.sri.com> from "Fred L. Templin" at "Dec 1, 97 11:52:28 am" To: templin@erg.sri.com (Fred L. Templin) Date: Mon, 1 Dec 1997 15:42:35 -0500 (EST) Cc: freebsd-hackers@freebsd.org, templin@erg.sri.com X-Mailer: ELM [version 2.4ME+ PL31 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Fred L. Templin said: > Hi, > > I'm designing an interface in which I need to move data directly between > user and kernel buffers using copyout() and copyin(). The interface works > fine when called synchronously within process context (e.g. the user process > calls ioctl(), giving the address of a buffer, and the kernel calls copyout() > or copyin() to move the data). But, what I really want is an *asynchronous* > interface in which the kernel can move data to/from the user buffers from > within an interrupt service routine - and it's my understanding that copyout() > and copyin() aren't suited for this. Am I wrong about this? If not, are there > alternatives to copyout()/copyin() which can be used to implement such an > interface? > Two ways (off the top of my head) to do it: 1) Queue it to a buffer representation while a process is waiting for the I/O to complete. Transfer the data using read or somesuch in process context, after waking the process up. (This is how read generally works.) One usually ends up using copyin/copyout here directly or indirectly by using uiomove. You have to have a process context active for copyin or copyout to work. (That includes their friends suword, fuword, etc.) 2) Lock the process virtual memory into physical space. Then, map that memory into kernel space. (This is how raw I/O generally works.) Once the memory is wired and mapped into the kernel, no special copyin/copyout is needed, you can just bcopy or use the virtual memory for anything. (Look at kern_physio.c.) Each of the schemes has it's own set of problems. There are probably other ways, I just haven't thought of them here and now. -- John dyson@freebsd.org jdyson@nc.com