Browse Source

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
920799a0ba
1 changed files with 22 additions and 7 deletions
  1. 22
    7
      src/arch/i386/interface/pcbios/memtop_umalloc.c

+ 22
- 7
src/arch/i386/interface/pcbios/memtop_umalloc.c View File

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

Loading…
Cancel
Save