Linux Driver: mmap () kernel buffer into user space without using nopage

I am implementing a Linux device driver for a data collection device that constantly transfers data to a circular buffer that I allocated in the kernel (using __get_free_pages()). The circular buffer (which is written by the PCIe hardware) is in RAM, and I want the user space to have the mmap () RAM area so that the user space can read its contents.

According to LDD3:

An interesting limitation of remap_pfn_range is that it only gives access to reserved pages and physical addresses above the top of the physical memory .... Therefore, remap_pfn_range will not allow you to reassign regular addresses that include the ones you get by calling get_free_page .... Method mapping real RAM to user space is to use vm_ops->nopageto eliminate page crashes one at a time.

In my case, I know exactly which addresses will need to be mapped to the given VMA locations for the entire buffer at the time of the call mmap(), so why do I need to use the nopage()page crashes approach one at a time as they are accessed?

Why can't I configure my VMA so that my entire ring buffer is immediately mapped to the user's address space? Is there any way to do this?

I also expect the user space program to access my buffer sequentially, which will result in a result when my function nopage()is called every time the page border intersects. Does this mean significant performance in practice? (My buffer is large, say 16 MB.)

(It is noteworthy that I used remap_pfn_range()in the memory returned from __get_free_pages()in one of my previous device drivers, and I never had any problems, but I may have been lucky in this system.)

+3
source share
1 answer

, , LDD3 , ( ) LWN:

TL; DR: PG_reserved , kmalloc()/__get_free_pages(), remap_pfn_range(), vm_insert_page() .

vm_insert_page(), -, -0 (), , N , vm_insert_page() N .

Firewire: drivers/firewire/core-iso.c

, alloc_page() fw_iso_buffer_alloc(), VMA, vm_insert_page() fw_iso_buffer_map_vma(). (fw_iso_buffer_map_vma() mmap drivers/firewire/core-cdev.c.)

+3

All Articles