Download raw body.
mbuf dma 64 bit
Hi,
Allow to allocate mbufs with physical address above 4 GB. If any
network driver does not support 64 bit dma, the existing restrictions
are used.
I have added the IFXF_MBUF_64BIT flag to all drivers I could test.
There is no solution for hotplug devices yet. And I have not tested
USB network.
Is this diff the right direction?
bluhm
Index: arch/amd64/amd64/autoconf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/autoconf.c,v
diff -u -p -r1.59 autoconf.c
--- arch/amd64/amd64/autoconf.c 12 Nov 2025 10:00:27 -0000 1.59
+++ arch/amd64/amd64/autoconf.c 11 Feb 2026 21:19:45 -0000
@@ -108,6 +108,23 @@ unmap_startup(void)
} while (p < (vaddr_t)endboot);
}
+void
+mbuf_dma_64bit_enable(void)
+{
+ struct ifnet *ifp;
+
+ TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
+ if (!ISSET(ifp->if_xflags, IFXF_MBUF_64BIT)) {
+ printf("%s: restrict all mbufs to low memory\n",
+ ifp->if_xname);
+ return;
+ }
+ }
+
+ printf("enable mbufs in high memory\n");
+ m_pool_constraints(0, ULONG_MAX);
+}
+
/*
* Determine i/o configuration for a machine.
*/
@@ -123,6 +140,8 @@ cpu_configure(void)
panic("configure: mainbus not configured");
intr_printconfig();
+
+ mbuf_dma_64bit_enable();
#if NIOAPIC > 0
lapic_set_lvt();
Index: arch/amd64/amd64/bus_dma.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/bus_dma.c,v
diff -u -p -r1.60 bus_dma.c
--- arch/amd64/amd64/bus_dma.c 13 Mar 2025 13:24:04 -0000 1.60
+++ arch/amd64/amd64/bus_dma.c 11 Feb 2026 21:19:27 -0000
@@ -102,7 +102,8 @@
#endif
int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t,
- struct proc *, int, paddr_t *, int *, int *, int);
+ struct proc *, int, paddr_t *, int *, int *, int,
+ struct uvm_constraint_range *);
/*
* Common function for DMA map creation. May be called by bus-specific
@@ -269,7 +270,7 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dm
seg = 0;
used = 0;
error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
- &lastaddr, &seg, &used, 1);
+ &lastaddr, &seg, &used, 1, &dma_constraint);
if (error == 0) {
map->dm_mapsize = buflen;
map->dm_nsegs = seg + 1;
@@ -311,7 +312,8 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b
if (m->m_len == 0)
continue;
error = _bus_dmamap_load_buffer(t, map, m->m_data, m->m_len,
- NULL, flags, &lastaddr, &seg, &used, first);
+ NULL, flags, &lastaddr, &seg, &used, first,
+ &mbuf_constraint);
first = 0;
}
if (error == 0) {
@@ -366,7 +368,8 @@ _bus_dmamap_load_uio(bus_dma_tag_t t, bu
addr = (caddr_t)iov[i].iov_base;
error = _bus_dmamap_load_buffer(t, map, addr, minlen,
- p, flags, &lastaddr, &seg, &used, first);
+ p, flags, &lastaddr, &seg, &used, first,
+ &dma_constraint);
first = 0;
resid -= minlen;
@@ -721,7 +724,7 @@ _bus_dmamem_mmap(bus_dma_tag_t t, bus_dm
int
_bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp,
- int *segp, int *usedp, int first)
+ int *segp, int *usedp, int first, struct uvm_constraint_range *constraint)
{
bus_size_t sgsize;
bus_addr_t curaddr, lastaddr, baddr, bmask;
@@ -746,7 +749,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t,
*/
pmap_extract(pmap, vaddr, (paddr_t *)&curaddr);
- if (curaddr > dma_constraint.ucr_high &&
+ if (curaddr > constraint->ucr_high &&
(map->_dm_flags & BUS_DMA_64BIT) == 0)
panic("Non dma-reachable buffer at curaddr %#lx(raw)",
curaddr);
Index: arch/amd64/amd64/machdep.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/machdep.c,v
diff -u -p -r1.306 machdep.c
--- arch/amd64/amd64/machdep.c 24 Nov 2025 17:20:40 -0000 1.306
+++ arch/amd64/amd64/machdep.c 11 Feb 2026 21:19:27 -0000
@@ -218,9 +218,11 @@ struct vm_map *phys_map = NULL;
/* UVM constraint ranges. */
struct uvm_constraint_range isa_constraint = { 0x0, 0x00ffffffUL };
struct uvm_constraint_range dma_constraint = { 0x0, 0xffffffffUL };
+struct uvm_constraint_range mbuf_constraint = { 0x0, 0xffffffffUL };
struct uvm_constraint_range *uvm_md_constraints[] = {
&isa_constraint,
&dma_constraint,
+ &mbuf_constraint,
NULL,
};
Index: dev/pci/if_bnxt.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_bnxt.c,v
diff -u -p -r1.64 if_bnxt.c
--- dev/pci/if_bnxt.c 20 Jan 2026 05:08:04 -0000 1.64
+++ dev/pci/if_bnxt.c 11 Feb 2026 21:19:27 -0000
@@ -640,7 +640,7 @@ bnxt_attach(struct device *parent, struc
strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = bnxt_ioctl;
ifp->if_qstart = bnxt_start;
ifp->if_watchdog = bnxt_watchdog;
Index: dev/pci/if_em.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_em.c,v
diff -u -p -r1.379 if_em.c
--- dev/pci/if_em.c 14 Jul 2025 11:52:43 -0000 1.379
+++ dev/pci/if_em.c 11 Feb 2026 21:19:27 -0000
@@ -1990,7 +1990,7 @@ em_setup_interface(struct em_softc *sc)
strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = em_ioctl;
ifp->if_qstart = em_start;
ifp->if_watchdog = em_watchdog;
@@ -2158,7 +2158,8 @@ em_dma_malloc(struct em_softc *sc, bus_s
int r;
r = bus_dmamap_create(sc->sc_dmat, size, 1,
- size, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &dma->dma_map);
+ size, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
+ &dma->dma_map);
if (r != 0)
return (r);
@@ -2250,10 +2251,11 @@ em_setup_transmit_structures(struct em_s
pkt = &que->tx.sc_tx_pkts_ring[i];
error = bus_dmamap_create(sc->sc_dmat, EM_TSO_SIZE,
EM_MAX_SCATTER / (sc->pcix_82544 ? 2 : 1),
- EM_TSO_SEG_SIZE, 0, BUS_DMA_NOWAIT, &pkt->pkt_map);
+ EM_TSO_SEG_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_64BIT,
+ &pkt->pkt_map);
if (error != 0) {
- printf("%s: Unable to create TX DMA map\n",
- DEVNAME(sc));
+ printf("%s: Unable to create TX DMA map, "
+ "error %d\n", DEVNAME(sc), error);
goto fail;
}
}
@@ -2772,11 +2774,11 @@ em_allocate_receive_structures(struct em
pkt = &que->rx.sc_rx_pkts_ring[i];
error = bus_dmamap_create(sc->sc_dmat, EM_MCLBYTES, 1,
- EM_MCLBYTES, 0, BUS_DMA_NOWAIT, &pkt->pkt_map);
+ EM_MCLBYTES, 0, BUS_DMA_NOWAIT | BUS_DMA_64BIT,
+ &pkt->pkt_map);
if (error != 0) {
- printf("%s: em_allocate_receive_structures: "
- "bus_dmamap_create failed; error %u\n",
- DEVNAME(sc), error);
+ printf("%s: Unable to create RX DMA map, "
+ "error %d\n", DEVNAME(sc), error);
goto fail;
}
Index: dev/pci/if_ice.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_ice.c,v
diff -u -p -r1.66 if_ice.c
--- dev/pci/if_ice.c 18 Nov 2025 09:13:55 -0000 1.66
+++ dev/pci/if_ice.c 11 Feb 2026 21:19:27 -0000
@@ -30657,7 +30657,7 @@ ice_attach_hook(struct device *self)
ifp->if_softc = sc;
strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = ice_ioctl;
ifp->if_qstart = ice_start;
ifp->if_watchdog = ice_watchdog;
Index: dev/pci/if_igc.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_igc.c,v
diff -u -p -r1.30 if_igc.c
--- dev/pci/if_igc.c 17 Dec 2025 01:14:42 -0000 1.30
+++ dev/pci/if_igc.c 11 Feb 2026 21:19:27 -0000
@@ -737,8 +737,8 @@ igc_dma_malloc(struct igc_softc *sc, bus
dma->dma_tag = os->os_pa.pa_dmat;
- if (bus_dmamap_create(dma->dma_tag, size, 1, size, 0, BUS_DMA_NOWAIT,
- &dma->dma_map))
+ if (bus_dmamap_create(dma->dma_tag, size, 1, size, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_64BIT, &dma->dma_map))
return 1;
if (bus_dmamem_alloc(dma->dma_tag, size, PAGE_SIZE, 0, &dma->dma_seg,
1, &dma->dma_nseg, BUS_DMA_NOWAIT))
@@ -796,7 +796,7 @@ igc_setup_interface(struct igc_softc *sc
ifp->if_softc = sc;
strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = igc_ioctl;
ifp->if_qstart = igc_start;
ifp->if_watchdog = igc_watchdog;
@@ -1855,10 +1855,11 @@ igc_allocate_transmit_buffers(struct igc
for (i = 0; i < sc->num_tx_desc; i++) {
txbuf = &txr->tx_buffers[i];
error = bus_dmamap_create(txr->txdma.dma_tag, IGC_TSO_SIZE,
- IGC_MAX_SCATTER, PAGE_SIZE, 0, BUS_DMA_NOWAIT, &txbuf->map);
+ IGC_MAX_SCATTER, PAGE_SIZE, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_64BIT, &txbuf->map);
if (error != 0) {
- printf("%s: Unable to create TX DMA map\n",
- DEVNAME(sc));
+ printf("%s: Unable to create TX DMA map, error %d\n",
+ DEVNAME(sc), error);
goto fail;
}
}
@@ -2161,10 +2162,10 @@ igc_allocate_receive_buffers(struct igc_
for (i = 0; i < sc->num_rx_desc; i++, rxbuf++) {
error = bus_dmamap_create(rxr->rxdma.dma_tag,
sc->rx_mbuf_sz, 1, sc->rx_mbuf_sz, 0,
- BUS_DMA_NOWAIT, &rxbuf->map);
+ BUS_DMA_NOWAIT | BUS_DMA_64BIT, &rxbuf->map);
if (error) {
- printf("%s: Unable to create RX DMA map\n",
- DEVNAME(sc));
+ printf("%s: Unable to create RX DMA map, error %d\n",
+ DEVNAME(sc), error);
goto fail;
}
}
Index: dev/pci/if_ix.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_ix.c,v
diff -u -p -r1.222 if_ix.c
--- dev/pci/if_ix.c 11 Nov 2025 17:43:18 -0000 1.222
+++ dev/pci/if_ix.c 11 Feb 2026 21:19:27 -0000
@@ -1929,7 +1929,7 @@ ixgbe_setup_interface(struct ix_softc *s
strlcpy(ifp->if_xname, sc->dev.dv_xname, IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = ixgbe_ioctl;
ifp->if_qstart = ixgbe_start;
ifp->if_timer = 0;
@@ -2087,7 +2087,7 @@ ixgbe_dma_malloc(struct ix_softc *sc, bu
dma->dma_tag = os->os_pa.pa_dmat;
r = bus_dmamap_create(dma->dma_tag, size, 1,
- size, 0, BUS_DMA_NOWAIT, &dma->dma_map);
+ size, 0, BUS_DMA_NOWAIT | BUS_DMA_64BIT, &dma->dma_map);
if (r != 0) {
printf("%s: ixgbe_dma_malloc: bus_dmamap_create failed; "
"error %u\n", ifp->if_xname, r);
@@ -2293,11 +2293,11 @@ ixgbe_allocate_transmit_buffers(struct i
txbuf = &txr->tx_buffers[i];
error = bus_dmamap_create(txr->txdma.dma_tag, MAXMCLBYTES,
sc->num_segs, PAGE_SIZE, 0,
- BUS_DMA_NOWAIT, &txbuf->map);
+ BUS_DMA_NOWAIT | BUS_DMA_64BIT, &txbuf->map);
if (error != 0) {
- printf("%s: Unable to create TX DMA map\n",
- ifp->if_xname);
+ printf("%s: Unable to create TX DMA map, error %d\n",
+ ifp->if_xname, error);
goto fail;
}
}
@@ -2776,10 +2776,10 @@ ixgbe_allocate_receive_buffers(struct ix
rxbuf = rxr->rx_buffers;
for (i = 0; i < sc->num_rx_desc; i++, rxbuf++) {
error = bus_dmamap_create(rxr->rxdma.dma_tag, 16 * 1024, 1,
- 16 * 1024, 0, BUS_DMA_NOWAIT, &rxbuf->map);
+ 16 * 1024, 0, BUS_DMA_NOWAIT | BUS_DMA_64BIT, &rxbuf->map);
if (error) {
- printf("%s: Unable to create Pack DMA map\n",
- ifp->if_xname);
+ printf("%s: Unable to create RX DMA map, error %d\n",
+ ifp->if_xname, error);
goto fail;
}
}
Index: dev/pci/if_ixl.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/if_ixl.c,v
diff -u -p -r1.114 if_ixl.c
--- dev/pci/if_ixl.c 4 Dec 2025 16:51:29 -0000 1.114
+++ dev/pci/if_ixl.c 11 Feb 2026 21:19:27 -0000
@@ -1914,7 +1914,7 @@ ixl_attach(struct device *parent, struct
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
ifp->if_ioctl = ixl_ioctl;
ifp->if_qstart = ixl_start;
ifp->if_watchdog = ixl_watchdog;
Index: dev/pv/if_vio.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pv/if_vio.c,v
diff -u -p -r1.78 if_vio.c
--- dev/pv/if_vio.c 15 Jan 2026 09:06:19 -0000 1.78
+++ dev/pv/if_vio.c 11 Feb 2026 21:19:27 -0000
@@ -750,7 +750,7 @@ negotiate:
ifp->if_capabilities = 0;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_xflags = IFXF_MPSAFE | IFXF_MBUF_64BIT;
#if NVLAN > 0
ifp->if_capabilities |= IFCAP_VLAN_MTU;
ifp->if_capabilities |= IFCAP_VLAN_HWOFFLOAD;
Index: kern/uipc_mbuf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_mbuf.c,v
diff -u -p -r1.304 uipc_mbuf.c
--- kern/uipc_mbuf.c 5 Feb 2026 03:26:00 -0000 1.304
+++ kern/uipc_mbuf.c 11 Feb 2026 21:19:27 -0000
@@ -1477,7 +1477,21 @@ void
m_pool_init(struct pool *pp, u_int size, u_int align, const char *wmesg)
{
pool_init(pp, size, align, IPL_NET, 0, wmesg, &m_pool_allocator);
- pool_set_constraints(pp, &kp_dma_contig);
+ pool_set_constraints(pp, &kp_mbuf_contig);
+}
+
+void
+m_pool_constraints(paddr_t low, paddr_t high)
+{
+ int i;
+
+ mbuf_constraint.ucr_low = low;
+ mbuf_constraint.ucr_high = high;
+
+ pool_set_constraints(&mbpool, &kp_mbuf_contig);
+
+ for (i = 0; i < nitems(mclsizes); i++)
+ pool_set_constraints(&mclpools[i], &kp_mbuf_contig);
}
u_int
Index: net/if.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.h,v
diff -u -p -r1.223 if.h
--- net/if.h 9 Dec 2025 03:33:06 -0000 1.223
+++ net/if.h 11 Feb 2026 21:19:27 -0000
@@ -232,6 +232,7 @@ struct if_status_description {
#define IFXF_AUTOCONF4 0x80 /* [N] v4 autoconf (aka dhcp) enabled */
#define IFXF_MONITOR 0x100 /* [N] only used for bpf */
#define IFXF_LRO 0x200 /* [N] TCP large recv offload */
+#define IFXF_MBUF_64BIT 0x400 /* [I] mbuf with 64 bit DMA supported */
#define IFXF_CANTCHANGE \
(IFXF_MPSAFE|IFXF_CLONED)
Index: sys/mbuf.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/mbuf.h,v
diff -u -p -r1.269 mbuf.h
--- sys/mbuf.h 5 Feb 2026 03:26:00 -0000 1.269
+++ sys/mbuf.h 11 Feb 2026 21:19:27 -0000
@@ -441,6 +441,7 @@ void m_align(struct mbuf *, int);
struct mbuf *m_clget(struct mbuf *, int, u_int);
void m_extref(struct mbuf *, struct mbuf *);
void m_pool_init(struct pool *, u_int, u_int, const char *);
+void m_pool_constraints(paddr_t, paddr_t);
u_int m_pool_used(void);
void m_extfree_pool(caddr_t, u_int, void *);
void m_adj(struct mbuf *, int);
Index: uvm/uvm_extern.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_extern.h,v
diff -u -p -r1.187 uvm_extern.h
--- uvm/uvm_extern.h 13 Nov 2025 10:55:51 -0000 1.187
+++ uvm/uvm_extern.h 11 Feb 2026 21:19:27 -0000
@@ -232,6 +232,7 @@ extern struct uvmexp uvmexp;
/* Constraint ranges, set by MD code. */
extern struct uvm_constraint_range isa_constraint;
extern struct uvm_constraint_range dma_constraint;
+extern struct uvm_constraint_range mbuf_constraint;
extern struct uvm_constraint_range no_constraint;
extern struct uvm_constraint_range *uvm_md_constraints[];
@@ -358,6 +359,7 @@ extern const struct kmem_pa_mode kp_zero
extern const struct kmem_pa_mode kp_dma;
extern const struct kmem_pa_mode kp_dma_contig;
extern const struct kmem_pa_mode kp_dma_zero;
+extern const struct kmem_pa_mode kp_mbuf_contig;
extern const struct kmem_pa_mode kp_pageable;
extern const struct kmem_pa_mode kp_none;
Index: uvm/uvm_km.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/uvm/uvm_km.c,v
diff -u -p -r1.159 uvm_km.c
--- uvm/uvm_km.c 13 Nov 2025 10:55:51 -0000 1.159
+++ uvm/uvm_km.c 11 Feb 2026 21:19:27 -0000
@@ -745,6 +745,11 @@ const struct kmem_pa_mode kp_dma_zero =
.kp_zero = 1
};
+const struct kmem_pa_mode kp_mbuf_contig = {
+ .kp_constraint = &mbuf_constraint,
+ .kp_maxseg = 1
+};
+
const struct kmem_pa_mode kp_zero = {
.kp_constraint = &no_constraint,
.kp_zero = 1
mbuf dma 64 bit