ted
ted

Reputation: 4985

Map several pages as large region into process memory space

I was wondering if there is an api to map multiple seperate pages as one continious region into a processes memory space. I.e. I allocated two pages a and b with alloc_pages(fags, 0) and now want to map them as a memory chunk of the size 2*PAGESIZE into the memory of current. According to LDD3 I can use remap_pfn_range to remap seperate pages, however there seems to be no interface to combine multiple pages.

What is the correct way to map multiple pages as one larege region into a processes Memory space?

Upvotes: 1

Views: 1614

Answers (1)

mauzel
mauzel

Reputation: 1636

Edit 2: I had different assumptions about the question.

With a better understanding, my suggestion is just:

  • Userspace process allocates memory (using mmap or such), passes the address range to the kernel OR use vmalloc() in kernel to allocate contiguous virtual memory.
  • alloc_pages(...) to allocate contiguous physical pages
  • Get vm_area_struct for the allocated memory ranges (allocated via mmap or valloc)
  • remap_pfn_range() to map those pages to the allocated contiguous space's vm_area_struct. Make sure to use the correct vm_flags. For multiple pages, you will need to invoke remap_pfn_range() multiple times for each page, and also you will need to change the addr offset input parameter each time.

Old info:

Edit: Sorry, I forgot to mention this:

Please see: http://lxr.free-electrons.com/source/mm/cma.c#L212

194 /**
195  * cma_declare_contiguous() - reserve custom contiguous area
196  * @base: Base address of the reserved area optional, use 0 for any
197  * @size: Size of the reserved area (in bytes),
198  * @limit: End address of the reserved memory (optional, 0 for any).
199  * @alignment: Alignment for the CMA area, should be power of 2 or zero
200  * @order_per_bit: Order of pages represented by one bit on bitmap.
201  * @fixed: hint about where to place the reserved area
202  * @res_cma: Pointer to store the created cma region.
203  *
204  * This function reserves memory from early allocator. It should be
205  * called by arch specific code once the early allocator (memblock or bootmem)
206  * has been activated and all other subsystems have already allocated/reserved
207  * memory. This function allows to create custom reserved areas.
208  *
209  * If @fixed is true, reserve contiguous area at exactly @base.  If false,
210  * reserve in range from @base to @limit.
211  */
212 int __init cma_declare_contiguous(phys_addr_t base,
213                         phys_addr_t size, phys_addr_t limit,
214                         phys_addr_t alignment, unsigned int order_per_bit,
215                         bool fixed, struct cma **res_cma)

You use this to reserve a contiguous area. Once you have the struct cma, you can use cma_alloc().

Please see: http://lxr.free-electrons.com/source/mm/cma.c#L329

This is the cma_alloc() function that can be used to allocate contiguous memory in an address space.

320 /**
321  * cma_alloc() - allocate pages from contiguous area
322  * @cma:   Contiguous memory region for which the allocation is performed.
323  * @count: Requested number of pages.
324  * @align: Requested alignment of pages (in PAGE_SIZE order).
325  *
326  * This function allocates part of contiguous memory on specific
327  * contiguous memory area.
328  */
329 struct page *cma_alloc(struct cma *cma, int count, unsigned int align)

Then you can use remap_pfn_range(), as you have mentioned in your question, to remap the memory to a process' address space.

Upvotes: 2

Related Questions