mmap only needed pages of kernel buffer to user space

Posted by axeoth on Stack Overflow See other posts from Stack Overflow or by axeoth
Published on 2013-06-28T22:19:35Z Indexed on 2013/06/28 22:21 UTC
Read the original article Hit count: 251

See also this answer: http://stackoverflow.com/a/10770582/1284631

I need something similar, but without having to allocate a buffer: the buffer is large, in theory, but the user space program only needs to access some parts of it (it mocks some registers of a hardware).

As I cannot allocate with vmalloc_user() such a large buffer (kernel 32 bit, in embedded environment, no swap...), I followed the same approach as in the quoted answer, trying to allocate only those pages that are really requested by the user space.

So: I use a my_mmap() function for the device file (actually, is the .mmap field of a struct uio_info) to set up the fields of the vma, then, in the vm_area_struct's .fault field (also named my_fault()), I should return a page.

except that:

In the my_fault() method of vm_area_struct, I cannot obtain a page through:

vmf->page=vmalloc_to_page(my_buf + (vmf->pgoff << PAGE_SHIFT));

since there is no allocated buffer: my_buf = vmalloc_user(MY_BUF_SIZE); fails with "allocation failed: out of vmalloc space - use vmalloc= to increase size." (and there is no room or swap to increase that vmalloc= parameter).

So, I would need to get a page from the kernel and fill the vmf->page field.

How to allocate a page (I assume that the offset of the page is known, as it is vm->pgoff). What base memory should I use instead of my_buf?

PS:

I also did set up the vma->flags |= VM_NORESERVE; (in the my_mmap()), but not sure if it helps. Is there any vmalloc_user_unreserved()-like function? (let's say, lazy allocation)

Also, writing 1 to /proc/sys/vm/overcommit_memory and large values (eg 500) to /proc/sys/vm/overcommit_ratio before trying to my_buf=vmalloc_user(<large_size>) didn't work.

© Stack Overflow or respective owner

Related posts about linux-kernel

Related posts about linux-device-driver