Suppose we want to maintain a pool of memory in a device driver or module. How can that pool be created and be available to multiple processes lets say 4 processes, accessing this driver/module.
Assume 1 MB of memory in the pool.
When I was reading LDD I came across api's mempool_create() but then there's also kmalloc.
If someone has done such a thing kindly share the knowledge.
My initial approach is to allocate using kmalloc() and then maintain start and end pointers in the private object for each process that opens the module.
EDIT: Thanks @kikigood for spending some time on this. So based on your comments, I do something like this.
Lets say I allocated 1MB of mempool during init. And I want to restrict the count of processes to 4, so I keep a count. Increment this count at every
atomic_t count =0;
open()
{
if(count >4)
return -ENOMEM;
count++;
}
Also I maintain a buffer within my private device structure per process.
How to assign some memory from pool to this buffer.
The kernel should allocate memory dynamically to other kernel subsystems and to user processes. The KMA (kernel memory allocation) API usually consists of two functions: void* malloc(size_t nbytes); void free(void* ptr); There are various issues associated with allocation of memory.
The maximum size allocatable by kmalloc() is 1024 pages, or 4MB on x86. Generally for requests larger than 64kB, one should use __get_free_page() functions to ensure inter-platform compatibility.
The kmalloc() function guarantees that the pages are physically contiguous (and virtually contiguous). The vmalloc() function works in a similar fashion to kmalloc() , except it allocates memory that is only virtually contiguous and not necessarily physically contiguous.
This memory is located with the system space region of the virtual address space. Thus, kernel dynamic memory is accessible to all processes when they are executing in kernel mode. On some systems, this dynamic memory is further broken down into "paged" and "non-paged".
In order to create a memory pool, you need to use the kernel's slab allocator, or by maintaining the memory pool by yourself like what you did (kmalloc
). By using kernel's slab allocator, you can use one of those:
kmem_cache_create()
mempool_create()
I think the key problem for you to maintain a pool by yourself is a risk of creating memory fragmentation issue which will quickly run out of your memory or you can't allocate a large memory block even if there are lots of free memory.
Another benefit of using kernel's slab allocator is you can easily monitor the memory usage by looking into your /proc/slab
entries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With