-------------------------------------------- On Thu, 7/30/15, John Baldwin <j...@freebsd.org> wrote:
Subject: Re: Locking Memory Question To: "K. Macy" <km...@freebsd.org> Cc: "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>, "John-Mark Gurney" <j...@funkthat.com>, "Laurie Jennings" <laurie_jennings_1...@yahoo.com> Date: Thursday, July 30, 2015, 10:16 AM On Wednesday, July 29, 2015 11:28:03 PM K. Macy wrote: > >> > >> Im not clear how I'd do that. the data being passed up from the kernel is a variable size. To use copyout I'd have to pass a > >> pointer with a static buffer, right? > > > > Correct, you can pass along the size, and if it's not large enough > > try again... Less than ideal... > > > >> Is there a way to malloc user space memory from within an ioctl call? > > > > Well, it is possible that you could do the equivalent of mmap, and pass > > the address back along w/ a length, and leave it up to the user to > > munmap it... This is probably the nicest method if you the size is > > really largely variable, and it's expensive if the userland process > > allocated too much memory... The down side is that this is more > > complex to code... > > > > > Mach has the ability to send large "out of line messages". For smaller > messages where it doesn't do VM tricks to avoid copying it does > exactly this. In the receive path the kernel calls vm_allocate (which > is essentially just a wrapper for mmap) then copies the buffer in to > the newly allocated address space. The message itself contains the > allocated address and size of the allocation. The receiver is expected > to call vm_deallocate (munmap) when it's done with the data. > > The implementation is mixed in with enough other code that it may not > be a useful reference. Nonetheless, I wanted to point at that this > isn't as strange as it might sound. You can do this in FreeBSD by calling vm_mmap() with a NULL handle pointer to simulate a MAP_ANON mapping. Something like this: vm_mmap(&curproc->p_vmspace->vm_map, &addr, <size>, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, MAP_SHARED, OBJT_DEFAULT, NULL, 0); It's not great for a true shared memory buffer, but is fine for a one-time copy. -- ------------ Thanks everyone for the help on this. I decided to implement it with copyout(), mainly for maintainability going forward. I only have a couple of commands that require a larger than normal buffer, and I can always do a double fetch if the initial buffer is too small. the big problem with the VM stuff (aside from making my head spin around) is that it's not documented, so it's difficult to debug and someone else working on the code will have no idea what's going on. Thank again, Laurie _______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"