]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[iobuf] Relax alignment requirement for small I/O buffers
authorMichael Brown <mcb30@ipxe.org>
Fri, 29 Jun 2012 15:07:12 +0000 (16:07 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 29 Jun 2012 15:07:12 +0000 (16:07 +0100)
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>
src/core/iobuf.c
src/include/ipxe/iobuf.h

index d776d606e890ad40123cbe423c95ff51a49e00ac..3dfaf18c2f12d8d25b621c13af0344a4c52ab619 100644 (file)
@@ -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
  *
index 82c8b8896f6bb8983f95e59f9879ed57e3c3e7e9..8134ae76a859fe292d8a5603a4a847ff0560cf10 100644 (file)
@@ -13,17 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <assert.h>
 #include <ipxe/list.h>
 
-/**
- * I/O buffer alignment
- *
- * I/O buffers allocated via alloc_iob() are guaranteed to be
- * physically aligned to this boundary.  Some cards cannot DMA across
- * a 4kB boundary.  With a standard Ethernet MTU, aligning to a 2kB
- * boundary is sufficient to guarantee no 4kB boundary crossings.  For
- * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
- */
-#define IOB_ALIGN 2048
-
 /**
  * Minimum I/O buffer length
  *