#include <limits.h>
#include <errno.h>
#include <gpxe/uaccess.h>
#include <gpxe/hidemem.h>
#include <gpxe/memmap.h>
#include <gpxe/umalloc.h>
Go to the source code of this file.
Data Structures | |
| struct | external_memory |
| An external memory block. More... | |
Defines | |
| #define | EM_ALIGN ( 4 * 1024 ) |
| Alignment of external allocated memory. | |
| #define | UNOWHERE ( ~UNULL ) |
| Equivalent of NOWHERE for user pointers. | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static int | init_eheap (void) |
| Initialise external heap. | |
| static void | ecollect_free (void) |
| Collect free blocks. | |
| static userptr_t | memtop_urealloc (userptr_t ptr, size_t new_size) |
| Reallocate external memory. | |
| PROVIDE_UMALLOC (memtop, urealloc, memtop_urealloc) | |
Variables | |
| static userptr_t | top = UNULL |
| Top of heap. | |
| static userptr_t | bottom = UNULL |
| Bottom of heap (current lowest allocated block). | |
Definition in file memtop_umalloc.c.
| #define EM_ALIGN ( 4 * 1024 ) |
Alignment of external allocated memory.
Definition at line 36 of file memtop_umalloc.c.
Referenced by memtop_urealloc().
| #define UNOWHERE ( ~UNULL ) |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static int init_eheap | ( | void | ) | [static] |
Initialise external heap.
| rc | Return status code |
Definition at line 60 of file memtop_umalloc.c.
References bottom, memory_map::count, DBG, memory_region::end, ENOMEM, get_memmap(), phys_to_user(), memory_map::regions, memory_region::start, top, UINT_MAX, and user_to_phys().
Referenced by memtop_urealloc().
00060 { 00061 struct memory_map memmap; 00062 unsigned long heap_size = 0; 00063 unsigned int i; 00064 00065 DBG ( "Allocating external heap\n" ); 00066 00067 get_memmap ( &memmap ); 00068 for ( i = 0 ; i < memmap.count ; i++ ) { 00069 struct memory_region *region = &memmap.regions[i]; 00070 unsigned long r_start, r_end; 00071 unsigned long r_size; 00072 00073 DBG ( "Considering [%llx,%llx)\n", region->start, region->end); 00074 00075 /* Truncate block to 4GB */ 00076 if ( region->start > UINT_MAX ) { 00077 DBG ( "...starts after 4GB\n" ); 00078 continue; 00079 } 00080 r_start = region->start; 00081 if ( region->end > UINT_MAX ) { 00082 DBG ( "...end truncated to 4GB\n" ); 00083 r_end = 0; /* =4GB, given the wraparound */ 00084 } else { 00085 r_end = region->end; 00086 } 00087 00088 /* Use largest block */ 00089 r_size = ( r_end - r_start ); 00090 if ( r_size > heap_size ) { 00091 DBG ( "...new best block found\n" ); 00092 top = bottom = phys_to_user ( r_end ); 00093 heap_size = r_size; 00094 } 00095 } 00096 00097 if ( ! heap_size ) { 00098 DBG ( "No external heap available\n" ); 00099 return -ENOMEM; 00100 } 00101 00102 DBG ( "External heap grows downwards from %lx\n", 00103 user_to_phys ( top, 0 ) ); 00104 return 0; 00105 }
| static void ecollect_free | ( | void | ) | [static] |
Collect free blocks.
Definition at line 111 of file memtop_umalloc.c.
References bottom, copy_from_user(), DBG, external_memory::size, top, external_memory::used, user_to_phys(), and userptr_add().
Referenced by memtop_urealloc().
00111 { 00112 struct external_memory extmem; 00113 00114 /* Walk the free list and collect empty blocks */ 00115 while ( bottom != top ) { 00116 copy_from_user ( &extmem, bottom, -sizeof ( extmem ), 00117 sizeof ( extmem ) ); 00118 if ( extmem.used ) 00119 break; 00120 DBG ( "EXTMEM freeing [%lx,%lx)\n", user_to_phys ( bottom, 0 ), 00121 user_to_phys ( bottom, extmem.size ) ); 00122 bottom = userptr_add ( bottom, 00123 ( extmem.size + sizeof ( extmem ) ) ); 00124 } 00125 }
Reallocate external memory.
| old_ptr | Memory previously allocated by umalloc(), or UNULL | |
| new_size | Requested size |
| new_ptr | Allocated memory, or UNULL |
Definition at line 137 of file memtop_umalloc.c.
References bottom, copy_from_user(), copy_to_user(), DBG, ecollect_free(), EM_ALIGN, hide_umalloc(), init_eheap(), memmove_user(), external_memory::size, top, UNOWHERE, UNULL, external_memory::used, user_to_phys(), and userptr_add().
00137 { 00138 struct external_memory extmem; 00139 userptr_t new = ptr; 00140 size_t align; 00141 int rc; 00142 00143 /* Initialise external memory allocator if necessary */ 00144 if ( bottom == top ) { 00145 if ( ( rc = init_eheap() ) != 0 ) 00146 return UNULL; 00147 } 00148 00149 /* Get block properties into extmem */ 00150 if ( ptr && ( ptr != UNOWHERE ) ) { 00151 /* Determine old size */ 00152 copy_from_user ( &extmem, ptr, -sizeof ( extmem ), 00153 sizeof ( extmem ) ); 00154 } else { 00155 /* Create a zero-length block */ 00156 ptr = bottom = userptr_add ( bottom, -sizeof ( extmem ) ); 00157 DBG ( "EXTMEM allocating [%lx,%lx)\n", 00158 user_to_phys ( ptr, 0 ), user_to_phys ( ptr, 0 ) ); 00159 extmem.size = 0; 00160 } 00161 extmem.used = ( new_size > 0 ); 00162 00163 /* Expand/shrink block if possible */ 00164 if ( ptr == bottom ) { 00165 /* Update block */ 00166 new = userptr_add ( ptr, - ( new_size - extmem.size ) ); 00167 align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) ); 00168 new_size += align; 00169 new = userptr_add ( new, -align ); 00170 DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n", 00171 user_to_phys ( ptr, 0 ), 00172 user_to_phys ( ptr, extmem.size ), 00173 user_to_phys ( new, 0 ), 00174 user_to_phys ( new, new_size )); 00175 memmove_user ( new, 0, ptr, 0, ( ( extmem.size < new_size ) ? 00176 extmem.size : new_size ) ); 00177 extmem.size = new_size; 00178 bottom = new; 00179 } else { 00180 /* Cannot expand; can only pretend to shrink */ 00181 if ( new_size > extmem.size ) { 00182 /* Refuse to expand */ 00183 DBG ( "EXTMEM cannot expand [%lx,%lx)\n", 00184 user_to_phys ( ptr, 0 ), 00185 user_to_phys ( ptr, extmem.size ) ); 00186 return UNULL; 00187 } 00188 } 00189 00190 /* Write back block properties */ 00191 copy_to_user ( new, -sizeof ( extmem ), &extmem, 00192 sizeof ( extmem ) ); 00193 00194 /* Collect any free blocks and update hidden memory region */ 00195 ecollect_free(); 00196 hide_umalloc ( user_to_phys ( bottom, -sizeof ( extmem ) ), 00197 user_to_phys ( top, 0 ) ); 00198 00199 return ( new_size ? new : UNOWHERE ); 00200 }
| PROVIDE_UMALLOC | ( | memtop | , | |
| urealloc | , | |||
| memtop_urealloc | ||||
| ) |
Top of heap.
Definition at line 50 of file memtop_umalloc.c.
Referenced by ecollect_free(), init_eheap(), and memtop_urealloc().
Bottom of heap (current lowest allocated block).
Definition at line 53 of file memtop_umalloc.c.
Referenced by ecollect_free(), init_eheap(), and memtop_urealloc().
1.5.7.1