how do we use kmalloc in linux driver code - linux-kernel

How will I come to know that where exactly or at what point I should use the kmalloc() to allocate a memory to the device in the device driver?
Is it during initialization or during open? As in malloc,wil kmalloc allocates memory dynamically?

In general, you can use kmalloc() when you need physically contigous memory in kernel space.
You can use this during init/open depending on your use case.
If you kmalloc in init() but never use the device, then memory allocated is waste.
If kmalloc is used in open(), memory allocated is actually used because memory is allocated only if device is used.
Also, note that you can use vmalloc() in kernel in case you are not in need of physically contigous memory allocation.

It depends on when you need it. There is no hard and fast rule.
For eg, in the i2c driver in linux kernel, there are two kmalloc calls and none in initialization or any specific function.
And yes, it acts similar to user space malloc call and allocates memory dynamically.

Related

Contiguous physical memory using kmalloc on Guest

I am implementing a device driver in guest OS. For this I need to allocate a buffer space which is required to be contiguous physical memory. Does allocating buffer using kmalloc in guest OS guarantee contiguous physical address? If not, how can I achieve this?
kmalloc() will guarantee contiguous physical memory, and is supposed to be used for small objects, as stated in the function documentation:
* kmalloc is the normal method of allocating memory
* for objects smaller than page size in the kernel.
For bigger physically contiguous allocations, you should use alloc_pages() instead.
However, since you are in a guest OS, the physical memory you will be allocating is the one seen by the guest, not by the hypervisor (the "real" one). Whether the memory allocated is actually physically contiguous depends on how your hypervisor exposes memory to the guest OS.

Do built-in kernel drivers need kfree?

For a device driver that is compiled into the Linux kernel, should kmalloc'ed memory be freed with corresponding kfree() calls?
I am talking about memory that's allocated on initialization once and not something that is continuously allocated during the driver's lifespan. I assume that freeing the allocated memory is not necessary because the built-in driver lifespan is the lifespan of the kernel. Yes, the allocated memory is necessary for driver operation and cannot be freed after driver init; i.e. no __init macro possible.
I have not seen the above stated explicitly, and want to be sure.
It depends. But very few modules (which are drivers) can't be compiled as such. Moreover it's a good programming style.
By the way, you may consider to use device managed resources, like memory allocated via devm_kzalloc. It will take care of the allocated resources on probe stage and allows you to clean up an error path there as well.

Allocating a physical memory buffer in linux

I have an SoC which has both DSP and ARM cores on it and I would like to create a section of shared memory that both my userspace software, and DSP software are able to access. What would be the best way to allocate a buffer like this in Linux? Here is a little background, right now what I have is a kernel module in which I use kmalloc() to get a kernel buffer, I then use the __pa() macro from asm/page.h to get the physical address of my kernel buffer. I save this address as a sysfs entry so that my userspace code can get the physical address of this buffer. I can then write this address to the DSP so it knows where the shared memory location is, and I can also mmap /dev/mem or my own kernel module so that I can access this buffer from userspace (I could also use the read/write fileops).
For some reason I feel like this is overboard but I cannot find the best way to do what I am trying to do.
Would it be possible to just mmap \dev\mem a section of memory and just read and write to this section? My feeling is that this would not 'lock' this section of memory from the kernel, thus the kernel could still read/write to this memory without me knowing. Is this the case. After reading the memory management chapter of LDD3 I see that mmap creates a new VMA of the mapping. Would this lock this area of memory so that other processes would not get allocated this section of memory?
Any and all help is appreciated
Depending on the kind of DMA you're using, you need to allocate the buffer with dma_alloc_coherent(), or use standard allocations and the dma_map_* functions.
(You must not use __pa(); physical addresses are not necessarily the same as DMA bus addresses.)
To map the buffers to user space, use dma_mmap_coherent() for coherent buffers, or map the memory pages manually for streaming buffers.
For a similar requirement of mine, I had reserved about 16 MB of memory towards the end of ram and used it in both kernel and user space. Suppose you have 128 MB ram, you can set BOOTMEM argument as 112 MB in your boot loader. I am assuming you are using uboot. This will reserve 16 MB towards the end of the ram. Now in kernel and user space you can map this area and use it as shared memory.

Linux page allocation

In linux if malloc can't allocate data chunk from preallocated page. it uses mmap() or brk() to assign new pages. I wanted to clarify a few things :
I don't understand the following statment , I thought that when I use mmap() or brk() the kernel maps me a whole page. but the allocator alocates me only what I asked for from that new page? In this case trying to access unallocated space (In the newly mapped page) will not cause a page fault? (I understand that its not recommended )
The libc allocator manages each page: slicing them into smaller blocks, assigning them to processes, freeing them, and so on. For example, if your program uses 4097 bytes total, you need to use two pages, even though in reality the allocator gives you somewhere between 4105 to 4109 bytes
How does the allocator knows the VMA bounders ?(I assume no system call used) because the VMA struct that hold that information can only get accessed from kernel mode?
The system-level memory allocation (via mmap and brk) is all page-aligned and page-sized. This means if you use malloc (or other libc API that allocates memory) some small amount of memory (say 10 bytes), you are guaranteed that all the other bytes on that page of memory are readable without triggering a page fault.
Malloc and family do their own bookkeeping within the pages returned from the OS, so the mmap'd pages used by libc also contain a bunch of malloc metadata, in addition to whatever space you've allocated.
The libc allocator knows where everything is because it invokes the brk() and mmap() calls. If it invokes mmap() it passes in a size, and the kernel returns a start address. Then the libc allocator just stores those values in its metadata.
Doug Lea's malloc implementation is a very, very well documented memory allocator implementation and its comments will shed a lot of light on how allocators work in general:
http://g.oswego.edu/dl/html/malloc.html

DMA cache coherent contiguous allocation

I was looking at allocating a buffer for a DMA transaction. I read that there are two ways of doing this - coherent mappings or streaming mappings.
Now, we want cache coherent buffers. However, we are not doing any scatter/gather so we want the benefits of the dma_map_single call. We have set aside some contiguous memory in the bootargs so we always have enough contiguous memory available.
So I was wondering, can we call dma_alloc_coherent and then dma_map_single after it with the virtual address that dma_alloc_coherent returns? The returned physical address of the map single would then be set as the dma handle that dma_alloc_coherent returned in its call.
Does this make sense? Or is it superfluous/incorrect to do it this way?
You can't use both. But you're also trying to solve a nonexistent problem. Just use dma_alloc_coherent(), which gives you a contiguous DMA memory buffer with both virtual and physical addresses. DMA to the physical address, access it from the CPU with the virtual address. What's the issue?

Resources