iPXE
Data Structures | Macros | Functions | Variables
malloc.c File Reference

Dynamic memory allocation. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <ipxe/io.h>
#include <ipxe/list.h>
#include <ipxe/init.h>
#include <ipxe/refcnt.h>
#include <ipxe/malloc.h>
#include <valgrind/memcheck.h>

Go to the source code of this file.

Data Structures

struct  memory_block
 A free block of memory. More...
 
struct  autosized_block
 A block of allocated memory complete with size information. More...
 

Macros

#define MIN_MEMBLOCK_ALIGN   ( 4 * sizeof ( void * ) )
 Physical address alignment maintained for free blocks of memory. More...
 
#define HEAP_SIZE   ( 4096 * 1024 )
 Heap area size. More...
 
#define HEAP_ALIGN   MIN_MEMBLOCK_ALIGN
 Heap area alignment. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static void valgrind_make_blocks_defined (struct heap *heap)
 Mark all blocks in free list as defined. More...
 
static void valgrind_make_blocks_noaccess (struct heap *heap)
 Mark all blocks in free list as inaccessible. More...
 
static void check_blocks (struct heap *heap)
 Check integrity of the blocks in the free list. More...
 
static unsigned int discard_cache (size_t size __unused)
 Discard some cached data. More...
 
static void discard_all_cache (void)
 Discard all cached data. More...
 
static void * heap_alloc_block (struct heap *heap, size_t size, size_t align, size_t offset)
 Allocate a memory block. More...
 
static void heap_free_block (struct heap *heap, void *ptr, size_t size)
 Free a memory block. More...
 
void * heap_realloc (struct heap *heap, void *old_ptr, size_t new_size)
 Reallocate memory. More...
 
void * realloc (void *old_ptr, size_t new_size)
 Reallocate memory. More...
 
void * malloc (size_t size)
 Allocate memory. More...
 
void free (void *ptr)
 Free memory. More...
 
void * zalloc (size_t size)
 Allocate cleared memory. More...
 
void * malloc_phys_offset (size_t size, size_t phys_align, size_t offset)
 Allocate memory with specified physical alignment and offset. More...
 
void * malloc_phys (size_t size, size_t phys_align)
 Allocate memory with specified physical alignment. More...
 
void free_phys (void *ptr, size_t size)
 Free memory allocated with malloc_phys() More...
 
void heap_populate (struct heap *heap, void *start, size_t len)
 Add memory to allocation pool. More...
 
static void init_heap (void)
 Initialise the heap. More...
 
struct init_fn heap_init_fn __init_fn (INIT_EARLY)
 Memory allocator initialisation function. More...
 
static void shutdown_cache (int booting __unused)
 Discard all cached data on shutdown. More...
 
struct startup_fn heap_startup_fn __startup_fn (STARTUP_EARLY)
 Memory allocator shutdown function. More...
 
void heap_dump (struct heap *heap)
 Dump free block list (for debugging) More...
 

Variables

static char heap_area [HEAP_SIZE]
 The heap area. More...
 
static struct heap heap
 The global heap. More...
 

Detailed Description

Dynamic memory allocation.

Definition in file malloc.c.

Macro Definition Documentation

◆ MIN_MEMBLOCK_ALIGN

#define MIN_MEMBLOCK_ALIGN   ( 4 * sizeof ( void * ) )

Physical address alignment maintained for free blocks of memory.

We keep memory blocks aligned on a power of two that is at least large enough to hold a struct memory_block.

Definition at line 67 of file malloc.c.

◆ HEAP_SIZE

#define HEAP_SIZE   ( 4096 * 1024 )

Heap area size.

Currently fixed at 4MB.

Definition at line 82 of file malloc.c.

◆ HEAP_ALIGN

#define HEAP_ALIGN   MIN_MEMBLOCK_ALIGN

Heap area alignment.

Definition at line 85 of file malloc.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ valgrind_make_blocks_defined()

static void valgrind_make_blocks_defined ( struct heap heap)
inlinestatic

Mark all blocks in free list as defined.

Parameters
heapHeap

Definition at line 95 of file malloc.c.

95  {
96  struct memory_block *block;
97 
98  /* Do nothing unless running under Valgrind */
99  if ( RUNNING_ON_VALGRIND <= 0 )
100  return;
101 
102  /* Traverse free block list, marking each block structure as
103  * defined. Some contortions are necessary to avoid errors
104  * from list_check().
105  */
106 
107  /* Mark block list itself as defined */
108  VALGRIND_MAKE_MEM_DEFINED ( &heap->blocks, sizeof ( heap->blocks ) );
109 
110  /* Mark areas accessed by list_check() as defined */
112  sizeof ( heap->blocks.prev->next ) );
114  sizeof ( *heap->blocks.next ) );
116  sizeof ( heap->blocks.next->next->prev ) );
117 
118  /* Mark each block in list as defined */
120 
121  /* Mark block as defined */
122  VALGRIND_MAKE_MEM_DEFINED ( block, sizeof ( *block ) );
123 
124  /* Mark areas accessed by list_check() as defined */
125  VALGRIND_MAKE_MEM_DEFINED ( block->list.next,
126  sizeof ( *block->list.next ) );
127  VALGRIND_MAKE_MEM_DEFINED ( &block->list.next->next->prev,
128  sizeof ( block->list.next->next->prev ) );
129  }
130 }
struct list_head * next
Next list entry.
Definition: list.h:21
#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
Definition: memcheck.h:132
#define RUNNING_ON_VALGRIND
Definition: valgrind.h:4176
struct list_head list
List of free blocks.
Definition: malloc.c:59
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
struct list_head * prev
Previous list entry.
Definition: list.h:23
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45

References block, heap::blocks, memory_block::list, list_for_each_entry, list_head::next, list_head::prev, RUNNING_ON_VALGRIND, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by heap_alloc_block(), and heap_free_block().

◆ valgrind_make_blocks_noaccess()

static void valgrind_make_blocks_noaccess ( struct heap heap)
inlinestatic

Mark all blocks in free list as inaccessible.

Parameters
heapHeap

Definition at line 137 of file malloc.c.

137  {
138  struct memory_block *block;
139  struct memory_block *prev = NULL;
140 
141  /* Do nothing unless running under Valgrind */
142  if ( RUNNING_ON_VALGRIND <= 0 )
143  return;
144 
145  /* Traverse free block list, marking each block structure as
146  * inaccessible. Some contortions are necessary to avoid
147  * errors from list_check().
148  */
149 
150  /* Mark each block in list as inaccessible */
152 
153  /* Mark previous block (if any) as inaccessible. (Current
154  * block will be accessed by list_check().)
155  */
156  if ( prev )
157  VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) );
158  prev = block;
159 
160  /* At the end of the list, list_check() will end up
161  * accessing the first list item. Temporarily mark
162  * this area as defined.
163  */
165  sizeof ( heap->blocks.next->prev ));
166  }
167  /* Mark last block (if any) as inaccessible */
168  if ( prev )
169  VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) );
170 
171  /* Mark as inaccessible the area that was temporarily marked
172  * as defined to avoid errors from list_check().
173  */
175  sizeof ( heap->blocks.next->prev ) );
176 
177  /* Mark block list itself as inaccessible */
178  VALGRIND_MAKE_MEM_NOACCESS ( &heap->blocks, sizeof ( heap->blocks ) );
179 }
struct list_head * next
Next list entry.
Definition: list.h:21
#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
Definition: memcheck.h:132
#define RUNNING_ON_VALGRIND
Definition: valgrind.h:4176
struct list_head list
List of free blocks.
Definition: malloc.c:59
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition: memcheck.h:112
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
struct list_head * prev
Previous list entry.
Definition: list.h:23
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References block, heap::blocks, memory_block::list, list_for_each_entry, list_head::next, NULL, list_head::prev, RUNNING_ON_VALGRIND, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by heap_alloc_block(), and heap_free_block().

◆ check_blocks()

static void check_blocks ( struct heap heap)
inlinestatic

Check integrity of the blocks in the free list.

Parameters
heapHeap

Definition at line 186 of file malloc.c.

186  {
187  struct memory_block *block;
188  struct memory_block *prev = NULL;
189 
190  if ( ! ASSERTING )
191  return;
192 
194 
195  /* Check alignment */
196  assert ( ( virt_to_phys ( block ) &
197  ( heap->align - 1 ) ) == 0 );
198 
199  /* Check that list structure is intact */
200  list_check ( &block->list );
201 
202  /* Check that block size is not too small */
203  assert ( block->size >= sizeof ( *block ) );
204  assert ( block->size >= heap->align );
205 
206  /* Check that block does not wrap beyond end of address space */
207  assert ( ( ( void * ) block + block->size ) >
208  ( ( void * ) block ) );
209 
210  /* Check that blocks remain in ascending order, and
211  * that adjacent blocks have been merged.
212  */
213  if ( prev ) {
214  assert ( ( ( void * ) block ) > ( ( void * ) prev ) );
215  assert ( ( ( void * ) block ) >
216  ( ( ( void * ) prev ) + prev->size ) );
217  }
218  prev = block;
219  }
220 }
struct list_head list
List of free blocks.
Definition: malloc.c:59
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
#define ASSERTING
Definition: assert.h:20
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
#define list_check(list)
Check a list entry or list head is valid.
Definition: list.h:56
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45
size_t align
Alignment for free memory blocks.
Definition: malloc.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References heap::align, assert(), ASSERTING, block, heap::blocks, memory_block::list, list_check, list_for_each_entry, and NULL.

Referenced by heap_alloc_block(), and heap_free_block().

◆ discard_cache()

static unsigned int discard_cache ( size_t size  __unused)
static

Discard some cached data.

Parameters
sizeFailed allocation size
Return values
discardedNumber of cached items discarded

Definition at line 228 of file malloc.c.

228  {
229  struct cache_discarder *discarder;
230  unsigned int discarded;
231 
232  for_each_table_entry ( discarder, CACHE_DISCARDERS ) {
233  discarded = discarder->discard();
234  if ( discarded )
235  return discarded;
236  }
237  return 0;
238 }
#define CACHE_DISCARDERS
Cache discarder table.
Definition: malloc.h:103
unsigned int(* discard)(void)
Discard some cached data.
Definition: malloc.h:99
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
A cache discarder.
Definition: malloc.h:93

References CACHE_DISCARDERS, cache_discarder::discard, and for_each_table_entry.

Referenced by discard_all_cache().

◆ discard_all_cache()

static void discard_all_cache ( void  )
static

Discard all cached data.

Definition at line 244 of file malloc.c.

244  {
245  unsigned int discarded;
246 
247  do {
248  discarded = discard_cache ( 0 );
249  } while ( discarded );
250 }
static unsigned int discard_cache(size_t size __unused)
Discard some cached data.
Definition: malloc.c:228

References discard_cache().

Referenced by shutdown_cache().

◆ heap_alloc_block()

static void* heap_alloc_block ( struct heap heap,
size_t  size,
size_t  align,
size_t  offset 
)
static

Allocate a memory block.

Parameters
heapHeap
sizeRequested size
alignPhysical alignment
offsetOffset from physical alignment
Return values
ptrMemory block, or NULL

Allocates a memory block physically aligned as requested. No guarantees are provided for the alignment of the virtual address.

align must be a power of two. size may not be zero.

Definition at line 266 of file malloc.c.

267  {
268  struct memory_block *block;
269  size_t actual_offset;
270  size_t align_mask;
271  size_t actual_size;
272  size_t pre_size;
273  size_t post_size;
274  struct memory_block *pre;
275  struct memory_block *post;
276  unsigned int grown;
277  void *ptr;
278 
279  /* Sanity checks */
280  assert ( size != 0 );
281  assert ( ( align == 0 ) || ( ( align & ( align - 1 ) ) == 0 ) );
283  check_blocks ( heap );
284 
285  /* Limit offset to requested alignment */
286  offset &= ( align ? ( align - 1 ) : 0 );
287 
288  /* Calculate offset of memory block */
289  actual_offset = ( offset & ~( heap->align - 1 ) );
290  assert ( actual_offset <= offset );
291 
292  /* Calculate size of memory block */
293  actual_size = ( ( size + offset - actual_offset + heap->align - 1 )
294  & ~( heap->align - 1 ) );
295  if ( ! actual_size ) {
296  /* The requested size is not permitted to be zero. A
297  * zero result at this point indicates that either the
298  * original requested size was zero, or that unsigned
299  * integer overflow has occurred.
300  */
301  ptr = NULL;
302  goto done;
303  }
304  assert ( actual_size >= size );
305 
306  /* Calculate alignment mask */
307  align_mask = ( ( align - 1 ) | ( heap->align - 1 ) );
308 
309  DBGC2 ( heap, "HEAP allocating %#zx (aligned %#zx+%#zx)\n",
310  size, align, offset );
311  while ( 1 ) {
312  /* Search through blocks for the first one with enough space */
314  pre_size = ( ( actual_offset - virt_to_phys ( block ) )
315  & align_mask );
316  if ( ( block->size < pre_size ) ||
317  ( ( block->size - pre_size ) < actual_size ) )
318  continue;
319  post_size = ( block->size - pre_size - actual_size );
320  /* Split block into pre-block, block, and
321  * post-block. After this split, the "pre"
322  * block is the one currently linked into the
323  * free list.
324  */
325  pre = block;
326  block = ( ( ( void * ) pre ) + pre_size );
327  post = ( ( ( void * ) block ) + actual_size );
328  DBGC2 ( heap, "HEAP splitting [%p,%p) -> [%p,%p) "
329  "+ [%p,%p)\n", pre,
330  ( ( ( void * ) pre ) + pre->size ), pre, block,
331  post, ( ( ( void * ) pre ) + pre->size ) );
332  /* If there is a "post" block, add it in to
333  * the free list.
334  */
335  if ( post_size ) {
336  assert ( post_size >= sizeof ( *block ) );
337  assert ( ( post_size &
338  ( heap->align - 1 ) ) == 0 );
340  sizeof ( *post ));
341  post->size = post_size;
342  list_add ( &post->list, &pre->list );
343  }
344  /* Shrink "pre" block, leaving the main block
345  * isolated and no longer part of the free
346  * list.
347  */
348  pre->size = pre_size;
349  /* If there is no "pre" block, remove it from
350  * the list.
351  */
352  if ( ! pre_size ) {
353  list_del ( &pre->list );
355  sizeof ( *pre ) );
356  } else {
357  assert ( pre_size >= sizeof ( *block ) );
358  assert ( ( pre_size &
359  ( heap->align - 1 ) ) == 0 );
360  }
361  /* Update memory usage statistics */
362  heap->freemem -= actual_size;
363  heap->usedmem += actual_size;
364  if ( heap->usedmem > heap->maxusedmem )
366  /* Return allocated block */
367  ptr = ( ( ( void * ) block ) + offset - actual_offset );
368  DBGC2 ( heap, "HEAP allocated [%p,%p) within "
369  "[%p,%p)\n", ptr, ( ptr + size ), block,
370  ( ( ( void * ) block ) + actual_size ) );
372  goto done;
373  }
374 
375  /* Attempt to grow heap to satisfy allocation */
376  DBGC ( heap, "HEAP attempting to grow for %#zx (aligned "
377  "%#zx+%zx), used %zdkB\n", size, align, offset,
378  ( heap->usedmem >> 10 ) );
380  grown = ( heap->grow ? heap->grow ( actual_size ) : 0 );
382  check_blocks ( heap );
383  if ( ! grown ) {
384  /* Heap did not grow: fail allocation */
385  DBGC ( heap, "HEAP failed to allocate %#zx (aligned "
386  "%#zx)\n", size, align );
387  ptr = NULL;
388  goto done;
389  }
390  }
391 
392  done:
393  check_blocks ( heap );
395  return ptr;
396 }
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
struct list_head list
List of free blocks.
Definition: malloc.c:59
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
unsigned int(* grow)(size_t size)
Attempt to grow heap (optional)
Definition: malloc.h:67
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void valgrind_make_blocks_noaccess(struct heap *heap)
Mark all blocks in free list as inaccessible.
Definition: malloc.c:137
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
static void valgrind_make_blocks_defined(struct heap *heap)
Mark all blocks in free list as defined.
Definition: malloc.c:95
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition: memcheck.h:112
size_t maxusedmem
Maximum amount of used memory.
Definition: malloc.h:59
size_t freemem
Total amount of free memory.
Definition: malloc.h:55
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
size_t usedmem
Total amount of used memory.
Definition: malloc.h:57
static void check_blocks(struct heap *heap)
Check integrity of the blocks in the free list.
Definition: malloc.c:186
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45
size_t size
Size of this block.
Definition: malloc.c:46
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
Definition: memcheck.h:122
size_t align
Alignment for free memory blocks.
Definition: malloc.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct bofm_section_header done
Definition: bofm_test.c:46

References heap::align, assert(), block, heap::blocks, check_blocks(), DBGC, DBGC2, done, heap::freemem, heap::grow, memory_block::list, list_add, list_del, list_for_each_entry, heap::maxusedmem, NULL, offset, size, memory_block::size, heap::usedmem, valgrind_make_blocks_defined(), valgrind_make_blocks_noaccess(), VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MAKE_MEM_UNDEFINED.

Referenced by heap_realloc(), and malloc_phys_offset().

◆ heap_free_block()

static void heap_free_block ( struct heap heap,
void *  ptr,
size_t  size 
)
static

Free a memory block.

Parameters
heapHeap
ptrMemory allocated by heap_alloc_block(), or NULL
sizeSize of the memory

If ptr is NULL, no action is taken.

Definition at line 407 of file malloc.c.

407  {
408  struct memory_block *freeing;
409  struct memory_block *block;
410  struct memory_block *tmp;
411  size_t sub_offset;
412  size_t actual_size;
413  ssize_t gap_before;
414  ssize_t gap_after = -1;
415 
416  /* Allow for ptr==NULL */
417  if ( ! ptr )
418  return;
420 
421  /* Sanity checks */
423  check_blocks ( heap );
424 
425  /* Round up to match actual block that heap_alloc_block() would
426  * have allocated.
427  */
428  assert ( size != 0 );
429  sub_offset = ( virt_to_phys ( ptr ) & ( heap->align - 1 ) );
430  freeing = ( ptr - sub_offset );
431  actual_size = ( ( size + sub_offset + heap->align - 1 ) &
432  ~( heap->align - 1 ) );
433  DBGC2 ( heap, "HEAP freeing [%p,%p) within [%p,%p)\n",
434  ptr, ( ptr + size ), freeing,
435  ( ( ( void * ) freeing ) + actual_size ) );
436  VALGRIND_MAKE_MEM_UNDEFINED ( freeing, sizeof ( *freeing ) );
437 
438  /* Check that this block does not overlap the free list */
439  if ( ASSERTING ) {
441  if ( ( ( ( void * ) block ) <
442  ( ( void * ) freeing + actual_size ) ) &&
443  ( ( void * ) freeing <
444  ( ( void * ) block + block->size ) ) ) {
445  assert ( 0 );
446  DBGC ( heap, "HEAP double free of [%p,%p) "
447  "overlapping [%p,%p) detected from %p\n",
448  freeing,
449  ( ( ( void * ) freeing ) + size ), block,
450  ( ( void * ) block + block->size ),
451  __builtin_return_address ( 0 ) );
452  }
453  }
454  }
455 
456  /* Insert/merge into free list */
457  freeing->size = actual_size;
459  /* Calculate gaps before and after the "freeing" block */
460  gap_before = ( ( ( void * ) freeing ) -
461  ( ( ( void * ) block ) + block->size ) );
462  gap_after = ( ( ( void * ) block ) -
463  ( ( ( void * ) freeing ) + freeing->size ) );
464  /* Merge with immediately preceding block, if possible */
465  if ( gap_before == 0 ) {
466  DBGC2 ( heap, "HEAP merging [%p,%p) + [%p,%p) -> "
467  "[%p,%p)\n", block,
468  ( ( ( void * ) block ) + block->size ), freeing,
469  ( ( ( void * ) freeing ) + freeing->size ),
470  block,
471  ( ( ( void * ) freeing ) + freeing->size ) );
472  block->size += actual_size;
473  list_del ( &block->list );
474  VALGRIND_MAKE_MEM_NOACCESS ( freeing,
475  sizeof ( *freeing ) );
476  freeing = block;
477  }
478  /* Stop processing as soon as we reach a following block */
479  if ( gap_after >= 0 )
480  break;
481  }
482 
483  /* Insert before the immediately following block. If
484  * possible, merge the following block into the "freeing"
485  * block.
486  */
487  DBGC2 ( heap, "HEAP freed [%p,%p)\n",
488  freeing, ( ( ( void * ) freeing ) + freeing->size ) );
489  list_add_tail ( &freeing->list, &block->list );
490  if ( gap_after == 0 ) {
491  DBGC2 ( heap, "HEAP merging [%p,%p) + [%p,%p) -> [%p,%p)\n",
492  freeing, ( ( ( void * ) freeing ) + freeing->size ),
493  block, ( ( ( void * ) block ) + block->size ), freeing,
494  ( ( ( void * ) block ) + block->size ) );
495  freeing->size += block->size;
496  list_del ( &block->list );
497  VALGRIND_MAKE_MEM_NOACCESS ( block, sizeof ( *block ) );
498  }
499 
500  /* Update memory usage statistics */
501  heap->freemem += actual_size;
502  heap->usedmem -= actual_size;
503 
504  /* Allow heap to shrink */
505  if ( heap->shrink && heap->shrink ( freeing, freeing->size ) ) {
506  list_del ( &freeing->list );
507  heap->freemem -= freeing->size;
508  VALGRIND_MAKE_MEM_UNDEFINED ( freeing, freeing->size );
509  }
510 
511  /* Sanity checks */
512  check_blocks ( heap );
514 }
unsigned int(* shrink)(void *ptr, size_t size)
Allow heap to shrink (optional)
Definition: malloc.h:79
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned long tmp
Definition: linux_pci.h:65
struct list_head list
List of free blocks.
Definition: malloc.c:59
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void valgrind_make_blocks_noaccess(struct heap *heap)
Mark all blocks in free list as inaccessible.
Definition: malloc.c:137
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
#define ASSERTING
Definition: assert.h:20
static void valgrind_make_blocks_defined(struct heap *heap)
Mark all blocks in free list as defined.
Definition: malloc.c:95
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:459
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition: memcheck.h:112
size_t freemem
Total amount of free memory.
Definition: malloc.h:55
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
size_t usedmem
Total amount of used memory.
Definition: malloc.h:57
static void check_blocks(struct heap *heap)
Check integrity of the blocks in the free list.
Definition: malloc.c:186
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45
size_t size
Size of this block.
Definition: malloc.c:46
signed long ssize_t
Definition: stdint.h:7
#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
Definition: memcheck.h:122
size_t align
Alignment for free memory blocks.
Definition: malloc.h:50

References heap::align, assert(), ASSERTING, block, heap::blocks, check_blocks(), DBGC, DBGC2, heap::freemem, memory_block::list, list_add_tail, list_del, list_for_each_entry, list_for_each_entry_safe, heap::shrink, size, tmp, heap::usedmem, valgrind_make_blocks_defined(), valgrind_make_blocks_noaccess(), VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MAKE_MEM_UNDEFINED.

Referenced by free_phys(), heap_populate(), and heap_realloc().

◆ heap_realloc()

void* heap_realloc ( struct heap heap,
void *  old_ptr,
size_t  new_size 
)

Reallocate memory.

Parameters
heapHeap
old_ptrMemory previously allocated by heap_realloc(), or NULL
new_sizeRequested size
Return values
new_ptrAllocated memory, or NULL

Allocates memory with no particular alignment requirement. new_ptr will be aligned to at least a multiple of sizeof(void*). If old_ptr is non-NULL, then the contents of the newly allocated memory will be the same as the contents of the previously allocated memory, up to the minimum of the old and new sizes. The old memory will be freed.

If allocation fails the previously allocated block is left untouched and NULL is returned.

Calling heap_realloc() with a new size of zero is a valid way to free a memory block.

Definition at line 537 of file malloc.c.

537  {
538  struct autosized_block *old_block;
539  struct autosized_block *new_block;
540  size_t old_total_size;
541  size_t new_total_size;
542  size_t old_size;
543  size_t offset = offsetof ( struct autosized_block, data );
544  void *new_ptr = NOWHERE;
545 
546  /* Allocate new memory if necessary. If allocation fails,
547  * return without touching the old block.
548  */
549  if ( new_size ) {
550  new_total_size = ( new_size + offset );
551  if ( new_total_size < new_size )
552  return NULL;
553  new_block = heap_alloc_block ( heap, new_total_size,
554  heap->ptr_align, -offset );
555  if ( ! new_block )
556  return NULL;
557  new_block->size = new_total_size;
558  VALGRIND_MAKE_MEM_NOACCESS ( &new_block->size,
559  sizeof ( new_block->size ) );
560  new_ptr = &new_block->data;
561  VALGRIND_MALLOCLIKE_BLOCK ( new_ptr, new_size, 0, 0 );
562  assert ( ( ( ( intptr_t ) new_ptr ) &
563  ( heap->ptr_align - 1 ) ) == 0 );
564  }
565 
566  /* Copy across relevant part of the old data region (if any),
567  * then free it. Note that at this point either (a) new_ptr
568  * is valid, or (b) new_size is 0; either way, the memcpy() is
569  * valid.
570  */
571  if ( old_ptr && ( old_ptr != NOWHERE ) ) {
572  old_block = container_of ( old_ptr, struct autosized_block,
573  data );
574  VALGRIND_MAKE_MEM_DEFINED ( &old_block->size,
575  sizeof ( old_block->size ) );
576  old_total_size = old_block->size;
577  assert ( old_total_size != 0 );
578  old_size = ( old_total_size - offset );
579  memcpy ( new_ptr, old_ptr,
580  ( ( old_size < new_size ) ? old_size : new_size ) );
581  VALGRIND_FREELIKE_BLOCK ( old_ptr, 0 );
582  heap_free_block ( heap, old_block, old_total_size );
583  }
584 
585  if ( ASSERTED ) {
586  DBGC ( heap, "HEAP detected possible memory corruption "
587  "from %p\n", __builtin_return_address ( 0 ) );
588  }
589  return new_ptr;
590 }
#define NOWHERE
Address for zero-length memory blocks.
Definition: malloc.h:42
#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
Definition: memcheck.h:132
char data[0]
Remaining data.
Definition: malloc.c:74
#define DBGC(...)
Definition: compiler.h:505
static void * heap_alloc_block(struct heap *heap, size_t size, size_t align, size_t offset)
Allocate a memory block.
Definition: malloc.c:266
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
unsigned long intptr_t
Definition: stdint.h:21
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
size_t ptr_align
Alignment for size-tracked allocations.
Definition: malloc.h:52
size_t size
Size of this block.
Definition: malloc.c:72
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
Definition: valgrind.h:4412
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition: memcheck.h:112
#define ASSERTED
Definition: assert.h:26
A heap.
Definition: malloc.h:45
A block of allocated memory complete with size information.
Definition: malloc.c:70
static void heap_free_block(struct heap *heap, void *ptr, size_t size)
Free a memory block.
Definition: malloc.c:407
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
Definition: valgrind.h:4422
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), ASSERTED, container_of, data, autosized_block::data, DBGC, heap_alloc_block(), heap_free_block(), memcpy(), NOWHERE, NULL, offset, offsetof, heap::ptr_align, autosized_block::size, VALGRIND_FREELIKE_BLOCK, VALGRIND_MAKE_MEM_DEFINED, VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MALLOCLIKE_BLOCK.

Referenced by realloc(), and uheap_realloc().

◆ realloc()

void* realloc ( void *  old_ptr,
size_t  new_size 
)

Reallocate memory.

Parameters
old_ptrMemory previously allocated by malloc(), or NULL
new_sizeRequested size
Return values
new_ptrAllocated memory, or NULL

Definition at line 607 of file malloc.c.

607  {
608 
609  return heap_realloc ( &heap, old_ptr, new_size );
610 }
A heap.
Definition: malloc.h:45
void * heap_realloc(struct heap *heap, void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:537

References heap_realloc().

Referenced by __attribute__(), asn1_grow(), bitmap_resize(), cachedhcp_record(), dhcpopt_init(), efi_ifr_op(), efi_ifr_string(), efivars_find(), free(), ibft_alloc_string(), ibft_install(), line_buffer(), malloc(), nvo_realloc(), process_script(), and xferbuf_malloc_realloc().

◆ malloc()

void* malloc ( size_t  size)

Allocate memory.

Parameters
sizeRequested size
Return values
ptrMemory, or NULL

Allocates memory with no particular alignment requirement. ptr will be aligned to at least a multiple of sizeof(void*).

Definition at line 621 of file malloc.c.

621  {
622  void *ptr;
623 
624  ptr = realloc ( NULL, size );
625  if ( ASSERTED ) {
626  DBGC ( &heap, "HEAP detected possible memory corruption "
627  "from %p\n", __builtin_return_address ( 0 ) );
628  }
629  return ptr;
630 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
#define ASSERTED
Definition: assert.h:26
A heap.
Definition: malloc.h:45
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:607
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References ASSERTED, DBGC, NULL, realloc(), and size.

Referenced by add_tls(), aes_unwrap(), aes_wrap(), alloc_iob_raw(), apply_dns_search(), ath5k_hw_rfregs_init(), chap_init(), deflate_test_exec(), der_asn1(), derwin(), dhcpv6_rx(), dhe_key(), dupwin(), eap_rx_mschapv2_request(), eap_tx_response(), ecdsa_alloc(), efi_block_label(), efi_boot_path(), efi_cacert_all(), efi_cmdline_init(), efi_download_start(), efi_load_path(), efi_local_check_volume_name(), efi_local_len(), efi_locate_device(), efi_vasprintf(), efivars_fetch(), eisabus_probe(), fc_ulp_login(), fetch_setting_copy(), format_uri_alloc(), http_format_ntlm_auth(), icert_encode(), int13_hook(), ipair_rx_pubkey(), ipoib_map_remac(), ipv4_add_miniroute(), isabus_probe(), isapnpbus_probe(), iscsi_handle_chap_c_value(), iscsi_handle_chap_r_value(), iscsi_rx_buffered_data(), iscsi_scsi_command(), jme_alloc_rx_resources(), jme_alloc_tx_resources(), lldp_rx(), loopback_test(), mcabus_probe(), memcpy_test_speed(), mlx_memory_alloc_priv(), net80211_probe_start(), net80211_register(), newwin(), nfs_uri_symlink(), ntlm_authenticate_okx(), ocsp_response(), ocsp_uri_string(), parse_kv(), parse_net_args(), pci_vpd_resize(), pcibus_probe(), peerblk_decrypt(), peerblk_parse_header(), pem_asn1(), rsa_alloc(), sandev_parse_iso9660(), storef_setting(), storen_setting(), strndup(), t509bus_probe(), tls_new_server_key_exchange(), tls_new_session_ticket(), tls_select_handshake(), tls_send_client_key_exchange_dhe(), uhci_enqueue(), usb_config_descriptor(), usb_get_string_descriptor(), usbio_config(), usbio_path(), vasprintf(), vesafb_mode_list(), vmbus_open(), wpa_make_rsn_ie(), wpa_start(), and zalloc().

◆ free()

void free ( void *  ptr)

Free memory.

Parameters
ptrMemory allocated by malloc(), or NULL

Memory allocated with malloc_phys() cannot be freed with free(); it must be freed with free_phys() instead.

If ptr is NULL, no action is taken.

Definition at line 642 of file malloc.c.

642  {
643 
644  realloc ( ptr, 0 );
645  if ( ASSERTED ) {
646  DBGC ( &heap, "HEAP detected possible memory corruption "
647  "from %p\n", __builtin_return_address ( 0 ) );
648  }
649 }
#define DBGC(...)
Definition: compiler.h:505
#define ASSERTED
Definition: assert.h:26
A heap.
Definition: malloc.h:45
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition: malloc.c:607

References ASSERTED, DBGC, and realloc().

◆ zalloc()

void* zalloc ( size_t  size)

Allocate cleared memory.

Parameters
sizeRequested size
Return values
ptrAllocated memory

Allocate memory as per malloc(), and zero it.

This function name is non-standard, but pretty intuitive. zalloc(size) is always equivalent to calloc(1,size)

Definition at line 662 of file malloc.c.

662  {
663  void *data;
664 
665  data = malloc ( size );
666  if ( data )
667  memset ( data, 0, size );
668  if ( ASSERTED ) {
669  DBGC ( &heap, "HEAP detected possible memory corruption "
670  "from %p\n", __builtin_return_address ( 0 ) );
671  }
672  return data;
673 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
#define ASSERTED
Definition: assert.h:26
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
A heap.
Definition: malloc.h:45
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void * memset(void *dest, int character, size_t len) __nonnull

References ASSERTED, data, DBGC, malloc(), memset(), and size.

Referenced by add_dynui_item(), add_parameter(), alloc_form(), alloc_gpios(), alloc_ibdev(), alloc_image(), alloc_netdev(), alloc_pixbuf(), alloc_sandev(), alloc_uart(), alloc_usb(), alloc_usb_bus(), alloc_usb_hub(), aoecmd_create(), aoedev_open(), ar9300_eeprom_restore_internal(), arbel_alloc(), arbel_create_cq(), arbel_create_qp(), ata_open(), atadev_command(), ath5k_hw_attach(), ath5k_probe(), ath9k_init_softc(), ath_descdma_setup(), atl1e_setup_ring_resources(), autovivify_child_settings(), block_translate(), cachedhcp_record(), calloc(), cms_message(), cms_parse_participants(), concat_args(), cpio_okx(), create_downloader(), create_dynui(), create_parameters(), create_pinger(), create_validator(), dhcp_deliver(), dhcpv6_register(), dns_resolv(), dt_probe_node(), dwgpio_group_probe(), dwusb_probe(), efi_block_exec(), efi_block_install(), efi_fcp_path(), efi_file_open_image(), efi_ib_srp_path(), efi_image_path(), efi_iscsi_path(), efi_local_open(), efi_netdev_path(), efi_path_uri(), efi_paths(), efi_pxe_install(), efi_snp_hii_fetch(), efi_snp_hii_install(), efi_snp_hii_process(), efi_snp_hii_store(), efi_snp_probe(), efi_uri_path(), efi_usb_install(), efi_usb_open(), efi_usb_path(), efi_usb_probe(), efidev_alloc(), efipci_start(), efivars_find(), ehci_endpoint_open(), ehci_probe(), ehci_ring_alloc(), eoib_create_peer(), exanic_probe(), fc_els_create(), fc_ns_query(), fc_peer_create(), fc_port_open(), fc_ulp_create(), fc_xchg_create(), fcpdev_open(), fcpdev_scsi_command(), fetch_string_setting_copy_alloc(), fetchf_setting_copy(), flexboot_nodnic_create_cq(), flexboot_nodnic_create_qp(), flexboot_nodnic_eth_open(), flexboot_nodnic_probe(), fragment_reassemble(), ftp_open(), generic_settings_store(), golan_alloc(), golan_create_cq(), golan_create_qp_aux(), guestinfo_fetch_type(), hermon_alloc(), hermon_create_cq(), hermon_create_qp(), http_connect(), http_open(), http_open_uri(), hub_probe(), hv_probe(), hvm_probe(), hw_open(), ib_cmrc_open(), ib_create_conn(), ib_create_cq(), ib_create_madx(), ib_create_mi(), ib_create_path(), ib_create_qp(), ib_mcast_attach(), ib_srp_open(), ibft_install(), icert_certs(), imux_probe(), init_mlx_utils(), ipair_create(), ipv6_add_miniroute(), iscsi_open(), linda_create_send_wq(), mlx_memory_zalloc_priv(), ndp_register_settings(), neighbour_create(), net80211_handle_mgmt(), net80211_prepare_assoc(), net80211_probe_start(), net80211_probe_step(), net80211_step_associate(), nfs_open(), nii_map(), numeric_resolv(), ocsp_check(), ocsp_uri_string(), open(), parse_uri(), pcibridge_probe(), peerblk_open(), peerdisc_create(), peerdisc_discovered(), peermux_filter(), ping_open(), png_pixbuf(), pxe_menu_parse(), qib7322_create_send_bufs(), qib7322_create_send_wq(), qib7322_probe(), rc80211_init(), resolv(), resolv_setting(), rtl818x_probe(), scsi_open(), scsidev_command(), sec80211_install(), sis190_mii_probe(), skge_probe(), skge_ring_alloc(), sky2_probe(), sky2_up(), slam_open(), srp_open(), srpdev_scsi_command(), start_dhcp(), start_dhcpv6(), start_ipv6conf(), start_ntp(), start_pxebs(), tcp_open(), tftp_core_open(), tg3_alloc_consistent(), tls_session(), tls_set_cipher(), txnic_bgx_probe(), txnic_pf_probe(), ucode_exec(), udp_open_common(), uhci_endpoint_open(), uhci_probe(), undipci_probe(), undirom_probe(), uri_dup(), usb_probe_all(), usbblk_probe(), usbio_endpoint_open(), usbio_interfaces(), usbio_interrupt_open(), usbio_start(), usbkbd_probe(), validator_start_download(), virtnet_open_legacy(), virtnet_open_modern(), vmbus_probe(), vmbus_probe_channels(), vxge_hw_device_initialize(), x509_alloc_chain(), x509_append(), x509_certificate(), xcm_create(), xenbus_probe_device(), xenstore_response(), xfer_open_named_socket(), xhci_bus_open(), xhci_device_open(), xhci_endpoint_open(), xhci_probe(), xhci_ring_alloc(), xsigo_ib_probe(), xve_create(), and zlib_deflate().

◆ malloc_phys_offset()

void* malloc_phys_offset ( size_t  size,
size_t  phys_align,
size_t  offset 
)

Allocate memory with specified physical alignment and offset.

Parameters
sizeRequested size
alignPhysical alignment
offsetOffset from physical alignment
Return values
ptrMemory, or NULL

align must be a power of two. size may not be zero.

Definition at line 685 of file malloc.c.

685  {
686  void * ptr;
687 
688  ptr = heap_alloc_block ( &heap, size, phys_align, offset );
689  if ( ptr && size ) {
690  assert ( ( phys_align == 0 ) ||
691  ( ( ( virt_to_phys ( ptr ) ^ offset ) &
692  ( phys_align - 1 ) ) == 0 ) );
693  VALGRIND_MALLOCLIKE_BLOCK ( ptr, size, 0, 0 );
694  }
695  return ptr;
696 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
static void * heap_alloc_block(struct heap *heap, size_t size, size_t align, size_t offset)
Allocate a memory block.
Definition: malloc.c:266
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
Definition: valgrind.h:4412
A heap.
Definition: malloc.h:45
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References assert(), heap_alloc_block(), offset, size, and VALGRIND_MALLOCLIKE_BLOCK.

Referenced by alloc_iob_raw(), and malloc_phys().

◆ malloc_phys()

void* malloc_phys ( size_t  size,
size_t  phys_align 
)

Allocate memory with specified physical alignment.

Parameters
sizeRequested size
alignPhysical alignment
Return values
ptrMemory, or NULL

align must be a power of two. size may not be zero.

Definition at line 707 of file malloc.c.

707  {
708 
709  return malloc_phys_offset ( size, phys_align, 0 );
710 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
void * malloc_phys_offset(size_t size, size_t phys_align, size_t offset)
Allocate memory with specified physical alignment and offset.
Definition: malloc.c:685

References malloc_phys_offset(), and size.

Referenced by __vxge_hw_fifo_create(), __vxge_hw_ring_create(), a3c90x_setup_rx_ring(), a3c90x_setup_tx_ring(), arbel_alloc(), arbel_alloc_icm(), arbel_create_cq(), arbel_create_eq(), arbel_create_recv_wq(), arbel_create_send_wq(), ath5k_desc_alloc(), ath_descdma_setup(), atl1e_setup_ring_resources(), b44_init_rx_ring(), b44_init_tx_ring(), efx_hunt_alloc_special_buffer(), ehci_bus_open(), ehci_ring_alloc(), ena_create_admin(), ena_create_async(), ena_create_cq(), ena_create_sq(), ena_probe(), exanic_probe(), falcon_alloc_special_buffer(), golan_cmd_init(), golan_create_cq(), golan_create_eq(), golan_create_qp_aux(), hermon_alloc(), hermon_create_cq(), hermon_create_eq(), hermon_create_qp(), hv_alloc_message(), hv_alloc_pages(), hvm_map_hypercall(), icplus_create_ring(), ifec_net_open(), ifec_tx_setup(), igbvf_setup_rx_resources(), igbvf_setup_tx_resources(), jme_alloc_rx_resources(), jme_alloc_tx_resources(), legacy_probe(), linda_create_recv_wq(), linda_init_send(), mlx_memory_alloc_dma_priv(), myri10ge_net_open(), myson_create_ring(), natsemi_create_ring(), netfront_create_ring(), nv_init_rings(), pcnet32_setup_rx_resources(), pcnet32_setup_tx_resources(), phantom_create_rx_ctx(), phantom_create_tx_ctx(), phantom_open(), qib7322_create_recv_wq(), qib7322_init_send(), rhine_create_ring(), rtl818x_init_rx_ring(), rtl818x_init_tx_ring(), sis190_open(), skge_up(), sky2_probe(), sky2_up(), tg3_alloc_consistent(), tg3_test_dma(), uhci_bus_open(), uhci_enqueue(), uhci_ring_alloc(), velocity_alloc_rings(), vmbus_open(), and vmxnet3_open().

◆ free_phys()

void free_phys ( void *  ptr,
size_t  size 
)

Free memory allocated with malloc_phys()

Parameters
ptrMemory allocated by malloc_phys(), or NULL
sizeSize of memory, as passed to malloc_phys()

Memory allocated with malloc_phys() can only be freed with free_phys(); it cannot be freed with the standard free().

If ptr is NULL, no action is taken.

Definition at line 723 of file malloc.c.

723  {
724 
725  VALGRIND_FREELIKE_BLOCK ( ptr, 0 );
726  heap_free_block ( &heap, ptr, size );
727 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
A heap.
Definition: malloc.h:45
static void heap_free_block(struct heap *heap, void *ptr, size_t size)
Free a memory block.
Definition: malloc.c:407
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
Definition: valgrind.h:4422

References heap_free_block(), size, and VALGRIND_FREELIKE_BLOCK.

Referenced by __vxge_hw_fifo_delete(), __vxge_hw_ring_delete(), a3c90x_free_rx_ring(), a3c90x_free_tx_ring(), alloc_iob_raw(), arbel_alloc(), arbel_alloc_icm(), arbel_create_cq(), arbel_create_eq(), arbel_create_qp(), arbel_create_recv_wq(), arbel_destroy_cq(), arbel_destroy_eq(), arbel_destroy_qp(), arbel_free(), arbel_free_icm(), ath5k_desc_alloc(), ath5k_desc_free(), ath_descdma_cleanup(), ath_descdma_setup(), atl1e_free_ring_resources(), b44_free_rx_ring(), b44_free_tx_ring(), b44_init_rx_ring(), b44_init_tx_ring(), efx_hunt_free_special_buffer(), ehci_bus_close(), ehci_bus_open(), ehci_ring_alloc(), ehci_ring_free(), ena_create_admin(), ena_create_async(), ena_create_cq(), ena_create_sq(), ena_destroy_admin(), ena_destroy_async(), ena_destroy_cq(), ena_destroy_sq(), ena_probe(), ena_remove(), exanic_probe(), exanic_remove(), falcon_free_special_buffer(), free_iob(), golan_cmd_init(), golan_cmd_uninit(), golan_create_cq(), golan_create_eq(), golan_create_qp_aux(), golan_destory_eq(), golan_destroy_cq(), golan_destroy_qp(), hermon_alloc(), hermon_create_cq(), hermon_create_eq(), hermon_create_qp(), hermon_destroy_cq(), hermon_destroy_eq(), hermon_destroy_qp(), hermon_free(), hv_alloc_pages(), hv_free_message(), hv_free_pages(), hvm_unmap_hypercall(), icplus_create_ring(), icplus_destroy_ring(), ifec_free(), ifec_net_open(), igbvf_free_rx_resources(), igbvf_free_tx_resources(), jme_free_rx_resources(), jme_free_tx_resources(), legacy_probe(), legacy_remove(), linda_create_recv_wq(), linda_destroy_recv_wq(), linda_fini_send(), linda_init_send(), mlx_memory_free_dma_priv(), myri10ge_net_close(), myri10ge_net_open(), myson_create_ring(), myson_destroy_ring(), natsemi_create_ring(), natsemi_destroy_ring(), netfront_create_ring(), netfront_destroy_ring(), nv_free_rxtx_resources(), pcnet32_free_rx_resources(), pcnet32_free_tx_resources(), phantom_close(), phantom_create_rx_ctx(), phantom_create_tx_ctx(), phantom_open(), qib7322_create_recv_wq(), qib7322_destroy_recv_wq(), qib7322_fini_send(), qib7322_init_send(), rhine_destroy_ring(), rtl818x_free_rx_ring(), rtl818x_free_tx_ring(), sis190_free(), skge_free(), sky2_free_rings(), sky2_probe(), sky2_remove(), tg3_free_consistent(), tg3_rx_prodring_fini(), tg3_test_dma(), uhci_bus_close(), uhci_bus_open(), uhci_dequeue(), uhci_enqueue(), uhci_ring_alloc(), uhci_ring_free(), velocity_alloc_rings(), velocity_close(), vmbus_close(), vmbus_open(), vmxnet3_close(), and vmxnet3_open().

◆ heap_populate()

void heap_populate ( struct heap heap,
void *  start,
size_t  len 
)

Add memory to allocation pool.

Parameters
heapHeap
startStart address
lenLength of memory

Adds a block of memory to the allocation pool. The memory must be aligned to the heap's required free memory block alignment.

Definition at line 739 of file malloc.c.

739  {
740 
741  /* Sanity checks */
742  assert ( ( virt_to_phys ( start ) & ( heap->align - 1 ) ) == 0 );
743  assert ( ( len & ( heap->align - 1 ) ) == 0 );
744 
745  /* Add to allocation pool */
747 
748  /* Fix up memory usage statistics */
749  heap->usedmem += len;
750 }
uint32_t start
Starting offset.
Definition: netvsc.h:12
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
size_t usedmem
Total amount of used memory.
Definition: malloc.h:57
A heap.
Definition: malloc.h:45
static void heap_free_block(struct heap *heap, void *ptr, size_t size)
Free a memory block.
Definition: malloc.c:407
size_t align
Alignment for free memory blocks.
Definition: malloc.h:50

References heap::align, assert(), heap_free_block(), len, start, and heap::usedmem.

Referenced by init_heap(), and uheap_grow().

◆ init_heap()

static void init_heap ( void  )
static

Initialise the heap.

Definition at line 756 of file malloc.c.

756  {
757 
758  /* Sanity check */
759  build_assert ( MIN_MEMBLOCK_ALIGN >= sizeof ( struct memory_block ) );
760 
761  /* Populate heap */
764  heap_populate ( &heap, heap_area, sizeof ( heap_area ) );
765 }
static char heap_area[HEAP_SIZE]
The heap area.
Definition: malloc.c:88
void heap_populate(struct heap *heap, void *start, size_t len)
Add memory to allocation pool.
Definition: malloc.c:739
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:77
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition: memcheck.h:112
#define MIN_MEMBLOCK_ALIGN
Physical address alignment maintained for free blocks of memory.
Definition: malloc.c:67
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
A heap.
Definition: malloc.h:45

References heap::blocks, build_assert, heap_area, heap_populate(), MIN_MEMBLOCK_ALIGN, and VALGRIND_MAKE_MEM_NOACCESS.

◆ __init_fn()

struct init_fn heap_init_fn __init_fn ( INIT_EARLY  )

Memory allocator initialisation function.

◆ shutdown_cache()

static void shutdown_cache ( int booting  __unused)
static

Discard all cached data on shutdown.

Definition at line 777 of file malloc.c.

777  {
779  DBGC ( &heap, "HEAP maximum usage %zdkB\n",
780  ( heap.maxusedmem >> 10 ) );
781 }
#define DBGC(...)
Definition: compiler.h:505
static void discard_all_cache(void)
Discard all cached data.
Definition: malloc.c:244
size_t maxusedmem
Maximum amount of used memory.
Definition: malloc.h:59
A heap.
Definition: malloc.h:45

References DBGC, discard_all_cache(), and heap::maxusedmem.

◆ __startup_fn()

struct startup_fn heap_startup_fn __startup_fn ( STARTUP_EARLY  )

Memory allocator shutdown function.

◆ heap_dump()

void heap_dump ( struct heap heap)

Dump free block list (for debugging)

Definition at line 793 of file malloc.c.

793  {
794  struct memory_block *block;
795 
796  dbg_printf ( "HEAP free block list:\n" );
798  dbg_printf ( "...[%p,%p] (size %#zx)\n", block,
799  ( ( ( void * ) block ) + block->size ),
800  block->size );
801  }
802 }
struct list_head list
List of free blocks.
Definition: malloc.c:59
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
A free block of memory.
Definition: malloc.c:44
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
A heap.
Definition: malloc.h:45
void dbg_printf(const char *fmt,...)
Print debug message.
Definition: debug.c:39

References block, heap::blocks, dbg_printf(), memory_block::list, and list_for_each_entry.

Variable Documentation

◆ heap_area

char heap_area[HEAP_SIZE]
static

The heap area.

Definition at line 88 of file malloc.c.

Referenced by init_heap().

◆ heap

struct heap heap
static
Initial value:
= {
.blocks = LIST_HEAD_INIT ( heap.blocks ),
.ptr_align = sizeof ( void * ),
.grow = discard_cache,
}
static unsigned int discard_cache(size_t size __unused)
Discard some cached data.
Definition: malloc.c:228
#define MIN_MEMBLOCK_ALIGN
Physical address alignment maintained for free blocks of memory.
Definition: malloc.c:67
struct list_head blocks
List of free memory blocks.
Definition: malloc.h:47
A heap.
Definition: malloc.h:45
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31

The global heap.

Definition at line 593 of file malloc.c.