Переглянути джерело

[malloc] Allow allocation of memory with a specified alignment offset

Allow for allocation of memory blocks having a specified offset from a
specified physical alignment, such as being 12 bytes before a 2kB
boundary.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 роки тому
джерело
коміт
e2becce186
2 змінених файлів з 29 додано та 8 видалено
  1. 7
    5
      src/core/malloc.c
  2. 22
    3
      src/include/ipxe/malloc.h

+ 7
- 5
src/core/malloc.c Переглянути файл

@@ -220,6 +220,7 @@ static void discard_all_cache ( void ) {
220 220
  *
221 221
  * @v size		Requested size
222 222
  * @v align		Physical alignment
223
+ * @v offset		Offset from physical alignment
223 224
  * @ret ptr		Memory block, or NULL
224 225
  *
225 226
  * Allocates a memory block @b physically aligned as requested.  No
@@ -227,7 +228,7 @@ static void discard_all_cache ( void ) {
227 228
  *
228 229
  * @c align must be a power of two.  @c size may not be zero.
229 230
  */
230
-void * alloc_memblock ( size_t size, size_t align ) {
231
+void * alloc_memblock ( size_t size, size_t align, size_t offset ) {
231 232
 	struct memory_block *block;
232 233
 	size_t align_mask;
233 234
 	size_t pre_size;
@@ -244,12 +245,13 @@ void * alloc_memblock ( size_t size, size_t align ) {
244 245
 	size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
245 246
 	align_mask = ( align - 1 ) | ( MIN_MEMBLOCK_SIZE - 1 );
246 247
 
247
-	DBG ( "Allocating %#zx (aligned %#zx)\n", size, align );
248
+	DBG ( "Allocating %#zx (aligned %#zx+%zx)\n", size, align, offset );
248 249
 	while ( 1 ) {
249 250
 		/* Search through blocks for the first one with enough space */
250 251
 		list_for_each_entry ( block, &free_blocks, list ) {
251
-			pre_size = ( - virt_to_phys ( block ) ) & align_mask;
252
-			post_size = block->size - pre_size - size;
252
+			pre_size = ( ( offset - virt_to_phys ( block ) )
253
+				     & align_mask );
254
+			post_size = ( block->size - pre_size - size );
253 255
 			if ( post_size >= 0 ) {
254 256
 				/* Split block into pre-block, block, and
255 257
 				 * post-block.  After this split, the "pre"
@@ -418,7 +420,7 @@ void * realloc ( void *old_ptr, size_t new_size ) {
418 420
 	if ( new_size ) {
419 421
 		new_total_size = ( new_size +
420 422
 				   offsetof ( struct autosized_block, data ) );
421
-		new_block = alloc_memblock ( new_total_size, 1 );
423
+		new_block = alloc_memblock ( new_total_size, 1, 0 );
422 424
 		if ( ! new_block )
423 425
 			return NULL;
424 426
 		VALGRIND_MAKE_MEM_UNDEFINED ( new_block, offsetof ( struct autosized_block, data ) );

+ 22
- 3
src/include/ipxe/malloc.h Переглянути файл

@@ -23,7 +23,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
23 23
 
24 24
 extern size_t freemem;
25 25
 
26
-extern void * __malloc alloc_memblock ( size_t size, size_t align );
26
+extern void * __malloc alloc_memblock ( size_t size, size_t align,
27
+					size_t offset );
27 28
 extern void free_memblock ( void *ptr, size_t size );
28 29
 extern void mpopulate ( void *start, size_t len );
29 30
 extern void mdumpfree ( void );
@@ -33,19 +34,37 @@ extern void mdumpfree ( void );
33 34
  *
34 35
  * @v size		Requested size
35 36
  * @v align		Physical alignment
37
+ * @v offset		Offset from physical alignment
36 38
  * @ret ptr		Memory, or NULL
37 39
  *
38 40
  * Allocates physically-aligned memory for DMA.
39 41
  *
40 42
  * @c align must be a power of two.  @c size may not be zero.
41 43
  */
42
-static inline void * __malloc malloc_dma ( size_t size, size_t phys_align ) {
43
-	void * ptr = alloc_memblock ( size, phys_align );
44
+static inline void * __malloc malloc_dma_offset ( size_t size,
45
+						  size_t phys_align,
46
+						  size_t offset ) {
47
+	void * ptr = alloc_memblock ( size, phys_align, offset );
44 48
 	if ( ptr && size )
45 49
 		VALGRIND_MALLOCLIKE_BLOCK ( ptr, size, 0, 0 );
46 50
 	return ptr;
47 51
 }
48 52
 
53
+/**
54
+ * Allocate memory for DMA
55
+ *
56
+ * @v size		Requested size
57
+ * @v align		Physical alignment
58
+ * @ret ptr		Memory, or NULL
59
+ *
60
+ * Allocates physically-aligned memory for DMA.
61
+ *
62
+ * @c align must be a power of two.  @c size may not be zero.
63
+ */
64
+static inline void * __malloc malloc_dma ( size_t size, size_t phys_align ) {
65
+	return malloc_dma_offset ( size, phys_align, 0 );
66
+}
67
+
49 68
 /**
50 69
  * Free memory allocated with malloc_dma()
51 70
  *

Завантаження…
Відмінити
Зберегти