|
M0_INTERNAL void * | m0_arch_alloc (size_t size) |
|
M0_INTERNAL void | m0_arch_free (void *data) |
|
M0_INTERNAL void | m0_arch_allocated_zero (void *data, size_t size) |
|
M0_INTERNAL void * | m0_arch_alloc_nz (size_t size) |
|
M0_INTERNAL void | m0_arch_memory_pagein (void *addr, size_t size) |
|
M0_INTERNAL size_t | m0_arch_alloc_size (void *data) |
|
M0_INTERNAL void * | m0_arch_alloc_aligned (size_t alignment, size_t size) |
|
M0_INTERNAL void | m0_arch_free_aligned (void *addr, size_t size, unsigned shift) |
|
M0_INTERNAL void * | m0_arch_alloc_wired (size_t size, unsigned shift) |
|
M0_INTERNAL void | m0_arch_free_wired (void *data, size_t size, unsigned shift) |
|
M0_INTERNAL size_t | m0_arch_allocated (void) |
|
M0_INTERNAL int | m0_arch_dont_dump (void *p, size_t size) |
|
M0_INTERNAL int | m0_arch_memory_init (void) |
|
M0_INTERNAL void | m0_arch_memory_fini (void) |
|
M0_INTERNAL int | m0_arch_pagesize_get (void) |
|
M0_INTERNAL int | m0_arch_pageshift_get (void) |
|
static void | poison_before_free (void *data, size_t size) |
|
M0_INTERNAL bool | m0_is_poisoned (const void *ptr) |
|
static void | alloc_tail (void *area, size_t size) |
|
M0_INTERNAL void * | m0_alloc_nz (size_t size) |
|
void * | m0_alloc (size_t size) |
|
void | m0_free (void *data) |
|
M0_INTERNAL void | m0_memory_pagein (void *addr, size_t size) |
|
M0_INTERNAL void * | m0_alloc_aligned (size_t size, unsigned shift) |
|
M0_INTERNAL void | m0_free_aligned (void *data, size_t size, unsigned shift) |
|
M0_INTERNAL void * | m0_alloc_wired (size_t size, unsigned shift) |
|
M0_INTERNAL void | m0_free_wired (void *data, size_t size, unsigned shift) |
|
M0_INTERNAL size_t | m0_allocated (void) |
|
M0_INTERNAL size_t | m0_allocated_total (void) |
|
M0_INTERNAL size_t | m0_freed_total (void) |
|
M0_INTERNAL int | m0_pagesize_get (void) |
|
M0_INTERNAL int | m0_pageshift_get (void) |
|
M0_INTERNAL int | m0_dont_dump (void *p, size_t size) |
|
M0_INTERNAL int | m0_memory_init (void) |
|
M0_INTERNAL void | m0_memory_fini (void) |
|
static bool | m0_addr_is_aligned (const void *addr, unsigned shift) |
|
Linux kernel kmalloc based allocator.
User level malloc(3) based implementation.
The only interesting detail is implementation of m0_allocated(). No standard function returns the amount of memory allocated in the arena.
GNU Libc defines mallinfo() function, returning the amount of allocated memory among other things. In OS X (of all places) there is malloc_size() function that, given a pointer to an allocated block of memory, returns its size. On other platforms m0_allocates() is always 0.
◆ DEV_MODE
◆ M0_ALLOC_ARR
#define M0_ALLOC_ARR |
( |
|
arr, |
|
|
|
nr |
|
) |
| |
Value: m0_alloc((
nr) *
sizeof ((arr)[0])))
#define M0_FI_ENABLED(tag)
Definition at line 84 of file memory.h.
◆ M0_ALLOC_ARR_ALIGNED
#define M0_ALLOC_ARR_ALIGNED |
( |
|
arr, |
|
|
|
nr, |
|
|
|
shift |
|
) |
| ((arr) = m0_alloc_aligned((nr) * sizeof ((arr)[0]), (shift))) |
◆ M0_ALLOC_PTR
◆ m0_free0
Value:do { \
typeof(pptr) __pptr = (pptr); \
m0_free(*__pptr); \
} while (0)
Frees memory and unsets the pointer.
Definition at line 77 of file memory.h.
◆ M0_TRACE_SUBSYSTEM
#define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_MEMORY |
◆ anonymous enum
◆ alloc_tail()
static void alloc_tail |
( |
void * |
area, |
|
|
size_t |
size |
|
) |
| |
|
static |
◆ m0_addr_is_aligned()
static bool m0_addr_is_aligned |
( |
const void * |
addr, |
|
|
unsigned |
shift |
|
) |
| |
|
inlinestatic |
It returns true when addr is aligned by value shift.
Definition at line 107 of file memory.h.
◆ m0_alloc()
void * m0_alloc |
( |
size_t |
size | ) |
|
Allocates zero-filled memory. The memory allocated is guaranteed to be suitably aligned for any kind of variable.
- Parameters
-
- Return values
-
NULL | - allocation failed |
!NULL | - allocated memory block |
Definition at line 126 of file memory.c.
◆ m0_alloc_aligned()
M0_INTERNAL void * m0_alloc_aligned |
( |
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
Allocates zero-filled memory, aligned on (2^shift)-byte boundary. In kernel mode due to the usage of __GFP_ZERO, it can't be used from hard or soft interrupt context.
Definition at line 168 of file memory.c.
◆ m0_alloc_nz()
M0_INTERNAL void * m0_alloc_nz |
( |
size_t |
size | ) |
|
Allocates memory without explicit zeroing.
Everything else is the same as in m0_alloc().
Definition at line 115 of file memory.c.
◆ m0_alloc_wired()
M0_INTERNAL void * m0_alloc_wired |
( |
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
Allocates the memory suitable for DMA, DIRECT_IO or sharing between user and kernel spaces.
- Note
- not tested/used in kernel space for now.
- Parameters
-
size | Memory size. |
shift | Alignment, ignored in kernel space. |
- Precondition
- size <= PAGE_SIZE
Definition at line 202 of file memory.c.
◆ m0_allocated()
M0_INTERNAL size_t m0_allocated |
( |
void |
| ) |
|
Return amount of memory currently allocated.
Definition at line 215 of file memory.c.
◆ m0_allocated_total()
M0_INTERNAL size_t m0_allocated_total |
( |
void |
| ) |
|
Returns cumulative amount of memory allocated so far since libmotr library loading.
Definition at line 221 of file memory.c.
◆ m0_arch_alloc()
void * m0_arch_alloc |
( |
size_t |
size | ) |
|
GFP_NOFS is used here to avoid deadlocks.
Normal kernel allocation mode (GFP_KERNEL) allows kernel memory allocator to call file-system to free some cached objects (pages, inodes, etc.). This introduces a danger of deadlock when a memory allocation is done under a lock and to free cached object the same lock has to be taken.
m0t1fs liberally allocated memory under critical locks (e.g., rpc machine lock), which is inherently dead-lock prone.
Using GFP_NOFS disabled re-entering file systems from the allocator, eliminating dead-locks at the risk of getting -ENOMEM earlier than necessary.
- Todo:
- The proper solution is to introduce an additional interface m0_alloc_safe(), to be called outside of critical locks and using GFP_KERNEL.
Definition at line 37 of file memory.c.
◆ m0_arch_alloc_aligned()
M0_INTERNAL void * m0_arch_alloc_aligned |
( |
size_t |
alignment, |
|
|
size_t |
size |
|
) |
| |
◆ m0_arch_alloc_nz()
M0_INTERNAL void * m0_arch_alloc_nz |
( |
size_t |
size | ) |
|
◆ m0_arch_alloc_size()
M0_INTERNAL size_t m0_arch_alloc_size |
( |
void * |
data | ) |
|
◆ m0_arch_alloc_wired()
M0_INTERNAL void * m0_arch_alloc_wired |
( |
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
◆ m0_arch_allocated()
M0_INTERNAL size_t m0_arch_allocated |
( |
void |
| ) |
|
◆ m0_arch_allocated_zero()
M0_INTERNAL void m0_arch_allocated_zero |
( |
void * |
data, |
|
|
size_t |
size |
|
) |
| |
◆ m0_arch_dont_dump()
M0_INTERNAL int m0_arch_dont_dump |
( |
void * |
p, |
|
|
size_t |
size |
|
) |
| |
sysctl vm.max_map_count default value is 65530. Half of this value can be marked as MADV_DONTDUMP. We need to set it to a larger number in our production system with large memory, e.g.: sysctl -w vm.max_map_count=30000000
Definition at line 119 of file memory.c.
◆ m0_arch_free()
void m0_arch_free |
( |
void * |
data | ) |
|
◆ m0_arch_free_aligned()
M0_INTERNAL void m0_arch_free_aligned |
( |
void * |
addr, |
|
|
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
◆ m0_arch_free_wired()
M0_INTERNAL void m0_arch_free_wired |
( |
void * |
data, |
|
|
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
◆ m0_arch_memory_fini()
M0_INTERNAL void m0_arch_memory_fini |
( |
void |
| ) |
|
◆ m0_arch_memory_init()
M0_INTERNAL int m0_arch_memory_init |
( |
void |
| ) |
|
◆ m0_arch_memory_pagein()
M0_INTERNAL void m0_arch_memory_pagein |
( |
void * |
addr, |
|
|
size_t |
size |
|
) |
| |
◆ m0_arch_pageshift_get()
M0_INTERNAL int m0_arch_pageshift_get |
( |
void |
| ) |
|
◆ m0_arch_pagesize_get()
M0_INTERNAL int m0_arch_pagesize_get |
( |
void |
| ) |
|
◆ m0_dont_dump()
M0_INTERNAL int m0_dont_dump |
( |
void * |
p, |
|
|
size_t |
size |
|
) |
| |
Mark this memory region to be excluded from core dump. see madvise(2).
Definition at line 243 of file memory.c.
◆ m0_free()
void m0_free |
( |
void * |
data | ) |
|
Frees memory block
This function must be a no-op when called with NULL argument.
- Parameters
-
data | pointer to allocated block |
Definition at line 146 of file memory.c.
◆ m0_free_aligned()
M0_INTERNAL void m0_free_aligned |
( |
void * |
data, |
|
|
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
Frees aligned memory block This function must be a no-op when called with NULL argument.
- Parameters
-
data | pointer to allocated block |
Definition at line 192 of file memory.c.
◆ m0_free_wired()
M0_INTERNAL void m0_free_wired |
( |
void * |
data, |
|
|
size_t |
size, |
|
|
unsigned |
shift |
|
) |
| |
◆ m0_freed_total()
M0_INTERNAL size_t m0_freed_total |
( |
void |
| ) |
|
Returns cumulative amount of memory freed so far since libmotr library loading.
Definition at line 227 of file memory.c.
◆ m0_is_poisoned()
M0_INTERNAL bool m0_is_poisoned |
( |
const void * |
p | ) |
|
Returns true iff "p" points to a freed and poisoned (with ENABLE_FREE_POISON) memory area.
If memory poisoning is disabled, this always returns true.
This function is not absolutely reliable. m0_arch_free() can overwrite parts of freed memory region. Specifically, libc free(3) uses first 8 bytes of the memory region for its internal purposes.
Definition at line 79 of file memory.c.
◆ m0_memory_fini()
M0_INTERNAL void m0_memory_fini |
( |
void |
| ) |
|
◆ m0_memory_init()
M0_INTERNAL int m0_memory_init |
( |
void |
| ) |
|
◆ m0_memory_pagein()
M0_INTERNAL void m0_memory_pagein |
( |
void * |
addr, |
|
|
size_t |
size |
|
) |
| |
Forces page faults for the memory block [addr, addr + size).
Usually it is done with writing at least one byte on each page of the allocated block.
It is intented to use in conjunction with m0_alloc_nz().
- Note
- It doesn't guarantee to preserve the data in the memory block.
-
Kernel version of the function does nothing.
Definition at line 163 of file memory.c.
◆ m0_pageshift_get()
M0_INTERNAL int m0_pageshift_get |
( |
void |
| ) |
|
Returns page shift. Used in the code shared between user and kernel.
Definition at line 238 of file memory.c.
◆ m0_pagesize_get()
M0_INTERNAL int m0_pagesize_get |
( |
void |
| ) |
|
Same as system getpagesize(3). Used in the code shared between user and kernel.
Definition at line 233 of file memory.c.
◆ poison_before_free()
static void poison_before_free |
( |
void * |
data, |
|
|
size_t |
size |
|
) |
| |
|
static |
◆ allocated
◆ cumulative_alloc
◆ cumulative_free