Re: copyin+copyout in one step ?
On 28 May 2013, at 05:56, Zaphod Beeblebrox zbee...@gmail.com wrote: Urm... Isn't the use of shared memory the more obvious way to transfer data between processes? Am I missing some nuance? I can't speak for Luigi's use-case, but the Binder APIs in BeOS and Android call for this kind of copy. The receiving process contains a ring buffer and the messages are pushed into it. You could implement this in shared memory, but only if you trusted the sender not to modify the data at incorrect times or write invalid values into the metadata (or, in the case of Binder, to forge the pid / uid of the sender, which it attached to each message). The kernel must act as an intermediary to enforce correct use of the buffer and also to allow the caller to block until space is available (perhaps by scheduling the receiver to run for a bit) without spinning and to allow multiple writers to be queued when there is no space, rather than have them racing. The buffers are in the receiver's memory space because it is designed for resource constrained environments and for malicious parties to communicate, so it avoids a potential DoS by filling up kmem with buffers - a process that c reate a load of receive ports will simply fill up its own address space and die. In the specific case of binder, you can avoid the overhead of extra VM lookups by mapping the buffer into the address space of every sender when you open the connection, but marking its access as privileged mode only. This means that you'll be doing a simple copy. You can also align the receive buffer in such a way that the consume counter is on a different page to the rest of the data structure, allowing you to get a page fault when the buffer transitions from full to non-full and there are messages waiting. David ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
Re: copyin+copyout in one step ?
On Tue, May 28, 2013 at 6:56 AM, Zaphod Beeblebrox zbee...@gmail.comwrote: On Mon, May 27, 2013 at 7:38 PM, Luigi Rizzo ri...@iet.unipi.it wrote: say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: Urm... Isn't the use of shared memory the more obvious way to transfer data between processes? Am I missing some nuance? see my other message about the use between VMs. I cannot simply share memory because otherwise the sender could alter the message while the receiver is playing with it, so at least one copy is needed (or page flipping, but that would be way more complex/wasteful/ expensive) . But also, in my case the source and destination buffers are chosen arbitrarily by the two VMs, and do not necessarily reside in the mmapped buffers that the kernel module provides. So at the moment I have three copies instead of one. cheers luigi ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
copyin+copyout in one step ?
Hi, say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: P1P2 +--+ ++ | SRC | | DST| +--v---+ +--^-+ ||-- ||kernel |^ || | ++| +-| tmpbuf ++ copyin|| copyout P1 ctx++ P2 ctx I guess the one above is the canonical way: P1 does a copyin() to a temporary buffer, then notifies P2 which can then issue or complete a syscall to do a copyout from tmpbuf to DST in P2's context. But I wonder, is it possible to do it as follows: P2 tells the kernel where the data should go (DST); later, P1 issues a system call and through a combined copyinout() moves data directly from SRC to DST, operating in the context of P1. | copyinout() ? | +---+ issued by P1 Is this doable at all ? I suspect that tell DST to the kernel might be especially expensive as it needs to pin the page so it is accessible while doing the syscall for P1 ? (the whole point for this optimization is saving the extra copy through the buffer, but it may be pointless if pinning the memory is more expensive than the copy) cheers luigi ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
Re: copyin+copyout in one step ?
On 5/27/13 4:38 PM, Luigi Rizzo wrote: Hi, say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: P1P2 +--+ ++ | SRC | | DST| +--v---+ +--^-+ ||-- ||kernel |^ || | ++| +-| tmpbuf ++ copyin|| copyout P1 ctx++ P2 ctx I guess the one above is the canonical way: P1 does a copyin() to a temporary buffer, then notifies P2 which can then issue or complete a syscall to do a copyout from tmpbuf to DST in P2's context. But I wonder, is it possible to do it as follows: P2 tells the kernel where the data should go (DST); later, P1 issues a system call and through a combined copyinout() moves data directly from SRC to DST, operating in the context of P1. | copyinout() ? | +---+ issued by P1 Is this doable at all ? I suspect that tell DST to the kernel might be especially expensive as it needs to pin the page so it is accessible while doing the syscall for P1 ? (the whole point for this optimization is saving the extra copy through the buffer, but it may be pointless if pinning the memory is more expensive than the copy) I suspect you'll want to use something like vslock(9) and sf_bufs. Have a look at vm/vm_glue.c - vslock() vm_imgact_hold_page(). On amd64, I *think* mapping an sfbuf or if you are really evil you can optimistically wire the page in the vm (cheap). If it's present then you can just use the direct map to access it. However, if it's not present, then fall back to another method, or maybe just fault it in (which will have to happen anyhow) and then retry. Sounds like a cool project! -Alfred ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
Re: copyin+copyout in one step ?
On 5/27/13 4:56 PM, Alfred Perlstein wrote: On 5/27/13 4:38 PM, Luigi Rizzo wrote: Hi, say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: P1P2 +--+ ++ | SRC | | DST| +--v---+ +--^-+ ||-- ||kernel |^ || | ++| +-| tmpbuf ++ copyin|| copyout P1 ctx++ P2 ctx I guess the one above is the canonical way: P1 does a copyin() to a temporary buffer, then notifies P2 which can then issue or complete a syscall to do a copyout from tmpbuf to DST in P2's context. But I wonder, is it possible to do it as follows: P2 tells the kernel where the data should go (DST); later, P1 issues a system call and through a combined copyinout() moves data directly from SRC to DST, operating in the context of P1. | copyinout() ? | +---+ issued by P1 Is this doable at all ? I suspect that tell DST to the kernel might be especially expensive as it needs to pin the page so it is accessible while doing the syscall for P1 ? (the whole point for this optimization is saving the extra copy through the buffer, but it may be pointless if pinning the memory is more expensive than the copy) I suspect you'll want to use something like vslock(9) and sf_bufs. Have a look at vm/vm_glue.c - vslock() vm_imgact_hold_page(). On amd64, I *think* mapping an sfbuf or if you are really evil you can optimistically wire the page in the vm (cheap). If it's present then you can just use the direct map to access it. However, if it's not present, then fall back to another method, or maybe just fault it in (which will have to happen anyhow) and then retry. Sounds like a cool project! -Alfred Oh, one other thing.. look at the pipe code. It used to do what you suggest, I think however it was driven by the READER pinning the WRITER's address space and doing a direct copy. However it may not be optimized for NOT-mapping into kva as I suggested doing. -Alfred ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
Re: copyin+copyout in one step ?
On Tue, May 28, 2013 at 01:38:01AM +0200, Luigi Rizzo wrote: Hi, say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: P1P2 +--+ ++ | SRC | | DST| +--v---+ +--^-+ ||-- ||kernel |^ || | ++| +-| tmpbuf ++ copyin|| copyout P1 ctx++ P2 ctx I guess the one above is the canonical way: P1 does a copyin() to a temporary buffer, then notifies P2 which can then issue or complete a syscall to do a copyout from tmpbuf to DST in P2's context. But I wonder, is it possible to do it as follows: P2 tells the kernel where the data should go (DST); later, P1 issues a system call and through a combined copyinout() moves data directly from SRC to DST, operating in the context of P1. | copyinout() ? | +---+ issued by P1 Is this doable at all ? I suspect that tell DST to the kernel might be especially expensive as it needs to pin the page so it is accessible while doing the syscall for P1 ? (the whole point for this optimization is saving the extra copy through the buffer, but it may be pointless if pinning the memory is more expensive than the copy) Yes, it is doable. If the copy can happen when either P1 or P2 are active context, then proc_rwmem() already perform exactly what you want. The virtual address in the address space of the 'other process' is specified as uio-uio_offset. The iov specifies the region(s) for the current process. If you want to perform the copy from P1 to P2 while some other context P3 is active, the same structure as proc_rwmem() would work, but you obviously would need to do vm_fault_hold() for both sides, and use pmap_copy_pages() instead of uiomove_fromphys(). In either case, you get copy without temporal buffer, but the setup cost could be non-trivial. You never know until measured. pgpTQLn3fMXt7.pgp Description: PGP signature
Re: copyin+copyout in one step ?
On Mon, May 27, 2013 at 7:38 PM, Luigi Rizzo ri...@iet.unipi.it wrote: say a process P1 wants to use the kernel to copy the content of a buffer SRC (in its user address space) to a buffer DST (in the address space of another process P2), and assume that P1 issues the request to the kernel when P2 has already told the kernel where the data should go: Urm... Isn't the use of shared memory the more obvious way to transfer data between processes? Am I missing some nuance? ___ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org