]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[iobuf] Limit automatic I/O buffer alignment to page size
authorMichael Brown <mcb30@ipxe.org>
Mon, 31 Mar 2025 12:33:44 +0000 (13:33 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 31 Mar 2025 12:39:58 +0000 (13:39 +0100)
Without any explicit alignment requirement, we will currently allocate
I/O buffers on their own size rounded up to the nearest power of two.
This is done to simplify driver transmit code paths, which can assume
that a standard Ethernet frame lies within a single physical page and
therefore does not need to be split even for devices with DMA engines
that cannot cross page boundaries.

Limit this automatic alignment to a maximum of the page size, to avoid
requiring excessive alignment for unusually large buffers (such as a
buffer allocated for an HTTP POST with a large parameter list).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/iobuf.c

index c9970bc7680f1c2a4f87cede921cb5b39b98ce8f..9f8a263d214c891ca5ea9223d0212c919d024482 100644 (file)
@@ -124,18 +124,24 @@ struct io_buffer * alloc_iob_raw ( size_t len, size_t align, size_t offset ) {
  * @ret iobuf  I/O buffer, or NULL if none available
  *
  * The I/O buffer will be physically aligned on its own size (rounded
- * up to the nearest power of two).
+ * up to the nearest power of two), up to a maximum of page-size
+ * alignment.
  */
 struct io_buffer * alloc_iob ( size_t len ) {
+       size_t align;
 
        /* Pad to minimum length */
        if ( len < IOB_ZLEN )
                len = IOB_ZLEN;
 
-       /* Align buffer on its own size to avoid potential problems
-        * with boundary-crossing DMA.
+       /* Align buffer on its own size (up to page size) to avoid
+        * potential problems with boundary-crossing DMA.
         */
-       return alloc_iob_raw ( len, len, 0 );
+       align = len;
+       if ( align > PAGE_SIZE )
+               align = PAGE_SIZE;
+
+       return alloc_iob_raw ( len, align, 0 );
 }
 
 /**