Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 01 Dec 1997 13:13:57 -0800
From:      "Fred L. Templin" <templin@erg.sri.com>
To:        "John S. Dyson" <toor@dyson.iquest.net>
Cc:        freebsd-hackers@freebsd.org, templin@erg.sri.com
Subject:   Re: copyout()/copyin() 
Message-ID:  <199712012114.NAA10819@grayling.erg.sri.com>
In-Reply-To: Your message of "Mon, 01 Dec 1997 15:42:35 EST." <199712012042.PAA00811@dyson.iquest.net> 

next in thread | previous in thread | raw e-mail | index | archive | help

John,

> 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.)

This is essentially what I'm doing right now; I basically only copy the data
when driven by the process - either as the result of a synchronous syscall or
after the kernel wakes the process up after an asynchronous event. The
disadvantage is that I'd really like to move the data directly between the
user buffers and device memory; bypassing kernel memory altogether (I know; I
failed to mention this in my original message!) Which brings us to:
  
> 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.)

I was actually checking into physio() when your message arrived. physio()
seems to be appropriate for "semi-synchronous" activities like reading/writing
from a raw tape device. The process calling physio() basically posts a raw
buffer to the device then sleeps until the device driver calls "iodone" which
issues the wakeup(). My scenario calls for the process to post many buffers to
the kernel; each of which will be serviced asynchronously. I'm fine with
locking the process virtual memory (by setting the "P_PHYSIO" flag?) but
am I asking for trouble trying to manage multiple small buffers this way
rather than one monolithic buffer as is done for physio()? Also, what happens
if my process crashes after I've mapped the pages into kernel space? 

> 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.

I searched the archives and noticed that a similar discussion to this took
place back in the July '97 timeframe. One of the correspondents (David 
Greenman, I think?) alluded to the possibility of mapping user buffers into
kernel space, but I didn't see any specific suggestions such as the good ones 
you've given here. Does anyone else have ideas on this?

> -- 
> John
> dyson@freebsd.org
> jdyson@nc.com

Thanks,

Fred
templin@erg.sri.com





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