summaryrefslogtreecommitdiffstats
path: root/src/core/iobuf.c
diff options
context:
space:
mode:
authorMichael Brown2012-06-29 17:07:12 +0200
committerMichael Brown2012-06-29 17:07:12 +0200
commita5c016d93ee24e851cd8752b014170a308f231da (patch)
tree5dc41c4838463a891de906ac91c25917d32c5a73 /src/core/iobuf.c
parent[tls] Request a maximum fragment length of 2048 bytes (diff)
downloadipxe-a5c016d93ee24e851cd8752b014170a308f231da.tar.gz
ipxe-a5c016d93ee24e851cd8752b014170a308f231da.tar.xz
ipxe-a5c016d93ee24e851cd8752b014170a308f231da.zip
[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.c18
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
*