diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-06-29 16:07:12 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-06-29 16:07:12 +0100 |
commit | a5c016d93ee24e851cd8752b014170a308f231da (patch) | |
tree | 5dc41c4838463a891de906ac91c25917d32c5a73 /src/core/iobuf.c | |
parent | 9a8c6b00d4433eb5c24f50c0c4a93c127d77def0 (diff) | |
download | ipxe-a5c016d93ee24e851cd8752b014170a308f231da.tar.gz |
[iobuf] Relax alignment requirement for small I/O buffers
iPXE currently aligns all I/O buffers on a 2kB boundary. This is
overkill for transmitted packets, which are typically much smaller
than 2kB.
Align I/O buffers on their own size. This reduces the alignment
requirement for small buffers, while preserving the guarantee that I/O
buffers will never cross boundaries that might cause problems for some
DMA engines.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/iobuf.c')
-rw-r--r-- | src/core/iobuf.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/core/iobuf.c b/src/core/iobuf.c index d776d606..3dfaf18c 100644 --- a/src/core/iobuf.c +++ b/src/core/iobuf.c @@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stdint.h> +#include <strings.h> #include <errno.h> #include <ipxe/malloc.h> #include <ipxe/iobuf.h> @@ -40,18 +41,24 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ struct io_buffer * alloc_iob ( size_t len ) { struct io_buffer *iobuf = NULL; + size_t align; void *data; /* Pad to minimum length */ if ( len < IOB_ZLEN ) len = IOB_ZLEN; - /* Align buffer length */ - len = ( len + __alignof__( *iobuf ) - 1 ) & - ~( __alignof__( *iobuf ) - 1 ); - + /* Align buffer length to ensure that struct io_buffer is aligned */ + len = ( len + __alignof__ ( *iobuf ) - 1 ) & + ~( __alignof__ ( *iobuf ) - 1 ); + + /* Align buffer on its own size to avoid potential problems + * with boundary-crossing DMA. + */ + align = ( 1 << fls ( len - 1 ) ); + /* Allocate memory for buffer plus descriptor */ - data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN ); + data = malloc_dma ( len + sizeof ( *iobuf ), align ); if ( ! data ) return NULL; @@ -61,6 +68,7 @@ struct io_buffer * alloc_iob ( size_t len ) { return iobuf; } + /** * Free I/O buffer * |