fghoussen
fghoussen

Reputation: 565

Linux Kernel Module: how to allocate a buffer (meant to be used by mmap) with kzalloc and GFP_DMA?

Linux Kernel Module: how to allocate a buffer (meant to be used by mmap) with kzalloc and GFP_DMA?

On kzalloc, the doc is skinny: https://www.kernel.org/doc/html/v5.0/core-api/mm-api.html#c.kzalloc.

I know GFP_DMA must be used to insure continuous memory in both physical and virtual spaces (which is mandatory for later use with mmap).

Here https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch13s02.html, one can read "Another limitation of mmap is that mapping is PAGE_SIZE grained. The kernel can dispose of virtual addresses only at the level of page tables; therefore, the mapped area must be a multiple of PAGE_SIZE and must live in physical memory starting at an address that is a multiple of PAGE_SIZE."

In all examples of use of mmap in a Linux Kernel Module I have searched / seen, I have found stuffs like:

mmap_buffer = kzalloc(PAGE_SIZE, GFP_DMA);

or

mmap_buffer = kzalloc(4*PAGE_SIZE, GFP_DMA);

It seems, there is always a fixed number of PAGE_SIZE allocated.

Now, in my case, I need mmap_buffer to represent a struct. Question: is this correct?

struct s {
  uint16_t a;
  uint16_t b;
}
...
mmap_buffer = kzalloc(sizeof(struct s), GFP_DMA); /* Is this correct? */

In the end, I have 2 questions:

  1. Is mmap_buffer = kzalloc(sizeof(struct s), GFP_DMA); correct? Putting this question another way: for the allocation to be correct, am I compelled to allocate a fixed number of pages like so?
   size_t N = sizeof(struct s) / PAGE_SIZE + 1; /* exact count of PAGE_SIZE for s */
   mmap_buffer = kzalloc(N*PAGE_SIZE, GFP_DMA);
  1. How can I make sure "the mapped area must live in physical memory starting at an address that is a multiple of PAGE_SIZE" as mentionned above? Does kzalloc already insure this for me? Am I supposed to force alignment by myself and if so how?

Upvotes: 1

Views: 63

Answers (0)

Related Questions