Explorar el Código

[umalloc] Fail allocations when we run out of external memory

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown hace 12 años
padre
commit
920799a0ba
Se han modificado 1 ficheros con 22 adiciones y 7 borrados
  1. 22
    7
      src/arch/i386/interface/pcbios/memtop_umalloc.c

+ 22
- 7
src/arch/i386/interface/pcbios/memtop_umalloc.c Ver fichero

@@ -52,6 +52,9 @@ static userptr_t top = UNULL;
52 52
 /** Bottom of heap (current lowest allocated block) */
53 53
 static userptr_t bottom = UNULL;
54 54
 
55
+/** Remaining space on heap */
56
+static size_t heap_size;
57
+
55 58
 /**
56 59
  * Initialise external heap
57 60
  *
@@ -59,12 +62,12 @@ static userptr_t bottom = UNULL;
59 62
  */
60 63
 static int init_eheap ( void ) {
61 64
 	struct memory_map memmap;
62
-	unsigned long heap_size = 0;
63 65
 	unsigned int i;
64 66
 
65 67
 	DBG ( "Allocating external heap\n" );
66 68
 
67 69
 	get_memmap ( &memmap );
70
+	heap_size = 0;
68 71
 	for ( i = 0 ; i < memmap.count ; i++ ) {
69 72
 		struct memory_region *region = &memmap.regions[i];
70 73
 		unsigned long r_start, r_end;
@@ -99,8 +102,8 @@ static int init_eheap ( void ) {
99 102
 		return -ENOMEM;
100 103
 	}
101 104
 
102
-	DBG ( "External heap grows downwards from %lx\n",
103
-	      user_to_phys ( top, 0 ) );
105
+	DBG ( "External heap grows downwards from %lx (size %zx)\n",
106
+	      user_to_phys ( top, 0 ), heap_size );
104 107
 	return 0;
105 108
 }
106 109
 
@@ -110,6 +113,7 @@ static int init_eheap ( void ) {
110 113
  */
111 114
 static void ecollect_free ( void ) {
112 115
 	struct external_memory extmem;
116
+	size_t len;
113 117
 
114 118
 	/* Walk the free list and collect empty blocks */
115 119
 	while ( bottom != top ) {
@@ -119,8 +123,9 @@ static void ecollect_free ( void ) {
119 123
 			break;
120 124
 		DBG ( "EXTMEM freeing [%lx,%lx)\n", user_to_phys ( bottom, 0 ),
121 125
 		      user_to_phys ( bottom, extmem.size ) );
122
-		bottom = userptr_add ( bottom,
123
-				       ( extmem.size + sizeof ( extmem ) ) );
126
+		len = ( extmem.size + sizeof ( extmem ) );
127
+		bottom = userptr_add ( bottom, len );
128
+		heap_size += len;
124 129
 	}
125 130
 }
126 131
 
@@ -153,7 +158,12 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
153 158
 				 sizeof ( extmem ) );
154 159
 	} else {
155 160
 		/* Create a zero-length block */
161
+		if ( heap_size < sizeof ( extmem ) ) {
162
+			DBG ( "EXTMEM out of space\n" );
163
+			return UNULL;
164
+		}
156 165
 		ptr = bottom = userptr_add ( bottom, -sizeof ( extmem ) );
166
+		heap_size -= sizeof ( extmem );
157 167
 		DBG ( "EXTMEM allocating [%lx,%lx)\n",
158 168
 		      user_to_phys ( ptr, 0 ), user_to_phys ( ptr, 0 ) );
159 169
 		extmem.size = 0;
@@ -163,6 +173,10 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
163 173
 	/* Expand/shrink block if possible */
164 174
 	if ( ptr == bottom ) {
165 175
 		/* Update block */
176
+		if ( new_size > ( heap_size - extmem.size ) ) {
177
+			DBG ( "EXTMEM out of space\n" );
178
+			return UNULL;
179
+		}
166 180
 		new = userptr_add ( ptr, - ( new_size - extmem.size ) );
167 181
 		align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) );
168 182
 		new_size += align;
@@ -174,8 +188,9 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
174 188
 		      user_to_phys ( new, new_size ));
175 189
 		memmove_user ( new, 0, ptr, 0, ( ( extmem.size < new_size ) ?
176 190
 						 extmem.size : new_size ) );
177
-		extmem.size = new_size;
178 191
 		bottom = new;
192
+		heap_size -= ( new_size - extmem.size );
193
+		extmem.size = new_size;
179 194
 	} else {
180 195
 		/* Cannot expand; can only pretend to shrink */
181 196
 		if ( new_size > extmem.size ) {
@@ -193,7 +208,7 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
193 208
 
194 209
 	/* Collect any free blocks and update hidden memory region */
195 210
 	ecollect_free();
196
-	hide_umalloc ( user_to_phys ( bottom, -sizeof ( extmem ) ),
211
+	hide_umalloc ( user_to_phys ( bottom, 0 ),
197 212
 		       user_to_phys ( top, 0 ) );
198 213
 
199 214
 	return ( new_size ? new : UNOWHERE );

Loading…
Cancelar
Guardar