Motr  M0
Memory allocation handling functions

Macros

#define M0_TRACE_SUBSYSTEM   M0_TRACE_SUBSYS_MEMORY
 
#define DEV_MODE   (false)
 
#define m0_free0(pptr)
 
#define M0_ALLOC_ARR(arr, nr)
 
#define M0_ALLOC_PTR(ptr)   M0_ALLOC_ARR(ptr, 1)
 
#define M0_ALLOC_ARR_ALIGNED(arr, nr, shift)   ((arr) = m0_alloc_aligned((nr) * sizeof ((arr)[0]), (shift)))
 

Enumerations

enum  { U_POISON_BYTE = 0x5f }
 

Functions

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)
 

Variables

static struct m0_atomic64 allocated
 
static struct m0_atomic64 cumulative_alloc
 
static struct m0_atomic64 cumulative_free
 

Detailed Description

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.

Macro Definition Documentation

◆ DEV_MODE

#define DEV_MODE   (false)

Definition at line 44 of file memory.c.

◆ M0_ALLOC_ARR

#define M0_ALLOC_ARR (   arr,
  nr 
)
Value:
((arr) = M0_FI_ENABLED(#arr "-fail") ? NULL : \
m0_alloc((nr) * sizeof ((arr)[0])))
static size_t nr
Definition: dump.c:1505
#define NULL
Definition: misc.h:38
#define M0_FI_ENABLED(tag)
Definition: finject.h:231

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)))

Definition at line 88 of file memory.h.

◆ M0_ALLOC_PTR

#define M0_ALLOC_PTR (   ptr)    M0_ALLOC_ARR(ptr, 1)

Definition at line 86 of file memory.h.

◆ m0_free0

#define m0_free0 (   pptr)
Value:
do { \
typeof(pptr) __pptr = (pptr); \
m0_free(*__pptr); \
*__pptr = NULL; \
} while (0)
#define NULL
Definition: misc.h:38

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

Definition at line 30 of file memory.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
U_POISON_BYTE 

Definition at line 39 of file memory.c.

Function Documentation

◆ alloc_tail()

static void alloc_tail ( void *  area,
size_t  size 
)
static

Definition at line 105 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the caller graph for this function:

◆ 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
size- memory size
Return values
NULL- allocation failed
!NULL- allocated memory block

Definition at line 126 of file memory.c.

Here is the call graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
sizeMemory size.
shiftAlignment, ignored in kernel space.
Precondition
size <= PAGE_SIZE

Definition at line 202 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_allocated()

M0_INTERNAL size_t m0_allocated ( void  )

Return amount of memory currently allocated.

Definition at line 215 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the caller graph for this function:

◆ m0_arch_alloc_aligned()

M0_INTERNAL void * m0_arch_alloc_aligned ( size_t  alignment,
size_t  size 
)

Definition at line 88 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_alloc_nz()

M0_INTERNAL void * m0_arch_alloc_nz ( size_t  size)
See also
m0_arch_alloc()

Definition at line 72 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_alloc_size()

M0_INTERNAL size_t m0_arch_alloc_size ( void *  data)

Definition at line 83 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_alloc_wired()

M0_INTERNAL void * m0_arch_alloc_wired ( size_t  size,
unsigned  shift 
)

Definition at line 104 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_arch_allocated()

M0_INTERNAL size_t m0_arch_allocated ( void  )

Definition at line 114 of file memory.c.

◆ m0_arch_allocated_zero()

M0_INTERNAL void m0_arch_allocated_zero ( void *  data,
size_t  size 
)

Definition at line 67 of file memory.c.

Here is the caller graph for this function:

◆ 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.

Here is the caller graph for this function:

◆ m0_arch_free()

void m0_arch_free ( void *  data)

Definition at line 62 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_free_aligned()

M0_INTERNAL void m0_arch_free_aligned ( void *  addr,
size_t  size,
unsigned  shift 
)

Definition at line 98 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_free_wired()

M0_INTERNAL void m0_arch_free_wired ( void *  data,
size_t  size,
unsigned  shift 
)

Definition at line 109 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_arch_memory_fini()

M0_INTERNAL void m0_arch_memory_fini ( void  )

Definition at line 129 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_memory_init()

M0_INTERNAL int m0_arch_memory_init ( void  )

Definition at line 124 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_memory_pagein()

M0_INTERNAL void m0_arch_memory_pagein ( void *  addr,
size_t  size 
)

Definition at line 78 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_pageshift_get()

M0_INTERNAL int m0_arch_pageshift_get ( void  )

Definition at line 138 of file memory.c.

Here is the caller graph for this function:

◆ m0_arch_pagesize_get()

M0_INTERNAL int m0_arch_pagesize_get ( void  )

Definition at line 133 of file memory.c.

Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_free()

void m0_free ( void *  data)

Frees memory block

This function must be a no-op when called with NULL argument.

Parameters
datapointer to allocated block

Definition at line 146 of file memory.c.

Here is the call graph for this function:

◆ 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
datapointer to allocated block

Definition at line 192 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ m0_free_wired()

M0_INTERNAL void m0_free_wired ( void *  data,
size_t  size,
unsigned  shift 
)

Frees the memory allocated with m0_alloc_wired().

Definition at line 207 of file memory.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:

◆ 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.

Here is the caller graph for this function:

◆ m0_memory_fini()

M0_INTERNAL void m0_memory_fini ( void  )

Definition at line 259 of file memory.c.

Here is the call graph for this function:

◆ m0_memory_init()

M0_INTERNAL int m0_memory_init ( void  )

Definition at line 251 of file memory.c.

Here is the call graph for this function:

◆ 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.

Here is the call graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ poison_before_free()

static void poison_before_free ( void *  data,
size_t  size 
)
static

Definition at line 76 of file memory.c.

Here is the caller graph for this function:

Variable Documentation

◆ allocated

struct m0_atomic64 allocated
static

Definition at line 101 of file memory.c.

◆ cumulative_alloc

struct m0_atomic64 cumulative_alloc
static

Definition at line 102 of file memory.c.

◆ cumulative_free

struct m0_atomic64 cumulative_free
static

Definition at line 103 of file memory.c.