david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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>
This commit is contained in:
Michael Brown 2012-06-29 16:07:12 +01:00
parent 9a8c6b00d4
commit a5c016d93e
2 changed files with 13 additions and 16 deletions

View File

@ -19,6 +19,7 @@
FILE_LICENCE ( GPL2_OR_LATER ); FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h> #include <stdint.h>
#include <strings.h>
#include <errno.h> #include <errno.h>
#include <ipxe/malloc.h> #include <ipxe/malloc.h>
#include <ipxe/iobuf.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 * alloc_iob ( size_t len ) {
struct io_buffer *iobuf = NULL; struct io_buffer *iobuf = NULL;
size_t align;
void *data; void *data;
/* Pad to minimum length */ /* Pad to minimum length */
if ( len < IOB_ZLEN ) if ( len < IOB_ZLEN )
len = IOB_ZLEN; len = IOB_ZLEN;
/* Align buffer length */ /* Align buffer length to ensure that struct io_buffer is aligned */
len = ( len + __alignof__( *iobuf ) - 1 ) & len = ( len + __alignof__ ( *iobuf ) - 1 ) &
~( __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 */ /* Allocate memory for buffer plus descriptor */
data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN ); data = malloc_dma ( len + sizeof ( *iobuf ), align );
if ( ! data ) if ( ! data )
return NULL; return NULL;
@ -61,6 +68,7 @@ struct io_buffer * alloc_iob ( size_t len ) {
return iobuf; return iobuf;
} }
/** /**
* Free I/O buffer * Free I/O buffer
* *

View File

@ -13,17 +13,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <assert.h> #include <assert.h>
#include <ipxe/list.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 * Minimum I/O buffer length
* *