summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2015-01-20 12:56:50 +0000
committerkettenis <kettenis@openbsd.org>2015-01-20 12:56:50 +0000
commitc4698f58e31650b8d3a250d6e20cd8ebc98ac859 (patch)
tree718617df3c2312733a4ba39fa5743f18719ff9cc
parentWe do not support AIO, so comment it out in the kqueue(2) manpage for now. (diff)
downloadwireguard-openbsd-c4698f58e31650b8d3a250d6e20cd8ebc98ac859.tar.xz
wireguard-openbsd-c4698f58e31650b8d3a250d6e20cd8ebc98ac859.zip
Make ix(4) work on strict alignment architectures. The Intel networking
hardware is fairly retarded. While it allows receive buffers with an ETHER_ALIGN offset, it only allows the size of the buffers to be specified in multiples of 1K. This means that if we want to use standard mbuf clusters we will waste 1024 - ETHER_ALIGN bytes per cluster, which is a lot for the 2K clusters we use now. Compromise a bit by using 4K clusters on strict alignment architectures and tell the hardware to use 3K of those, reducing the spillage a bit. While this isn't optimal, at least on sparc64 where we have 8K pages, the pool page allocation overhead should be the same as on amd64/i386 where we have 4K pages and continue to use 2K mbuf clusters. ok mikeb@, dlg@
-rw-r--r--sys/dev/pci/if_ix.c39
1 files changed, 17 insertions, 22 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c
index 8e7a6ebe236..fe6b47f08a6 100644
--- a/sys/dev/pci/if_ix.c
+++ b/sys/dev/pci/if_ix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.c,v 1.115 2015/01/12 10:40:51 mikeb Exp $ */
+/* $OpenBSD: if_ix.c,v 1.116 2015/01/20 12:56:50 kettenis Exp $ */
/******************************************************************************
@@ -496,7 +496,7 @@ ixgbe_rxrinfo(struct ix_softc *sc, struct if_rxrinfo *ifri)
for (i = 0; i < sc->num_queues; i++) {
rxr = &sc->rx_rings[i];
- ifr[n].ifr_size = MCLBYTES;
+ ifr[n].ifr_size = sc->rx_mbuf_sz;
snprintf(ifr[n].ifr_name, sizeof(ifr[n].ifr_name), "/%d", i);
ifr[n].ifr_info = rxr->rx_ring;
n++;
@@ -615,8 +615,13 @@ ixgbe_init(void *arg)
ixgbe_init_hw(&sc->hw);
ixgbe_initialize_transmit_units(sc);
+#ifdef __STRICT_ALIGNMENT
+ /* Use 4k clusters, even for jumbo frames */
+ sc->rx_mbuf_sz = 4096;
+#else
/* Use 2k clusters, even for jumbo frames */
sc->rx_mbuf_sz = MCLBYTES;
+#endif
/* Prepare receive descriptors and buffers */
if (ixgbe_setup_receive_structures(sc)) {
@@ -2044,8 +2049,6 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
#ifdef notyet
struct ip6_hdr *ip6;
#endif
- struct mbuf *m;
- int ipoff;
uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0;
int ehdrlen, ip_hlen = 0;
uint16_t etype;
@@ -2091,13 +2094,9 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
* Jump over vlan headers if already present,
* helpful for QinQ too.
*/
- if (mp->m_len < sizeof(struct ether_header))
- return (1);
#if NVLAN > 0
eh = mtod(mp, struct ether_vlan_header *);
if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
- if (mp->m_len < sizeof(struct ether_vlan_header))
- return (1);
etype = ntohs(eh->evl_proto);
ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
} else {
@@ -2115,23 +2114,15 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
switch (etype) {
case ETHERTYPE_IP:
- if (mp->m_pkthdr.len < ehdrlen + sizeof(*ip))
- return (1);
- m = m_getptr(mp, ehdrlen, &ipoff);
- KASSERT(m != NULL && m->m_len - ipoff >= sizeof(*ip));
- ip = (struct ip *)(m->m_data + ipoff);
+ ip = (struct ip *)(mp->m_data + ehdrlen);
ip_hlen = ip->ip_hl << 2;
ipproto = ip->ip_p;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
break;
#ifdef notyet
case ETHERTYPE_IPV6:
- if (mp->m_pkthdr.len < ehdrlen + sizeof(*ip6))
- return (1);
- m = m_getptr(mp, ehdrlen, &ipoff);
- KASSERT(m != NULL && m->m_len - ipoff >= sizeof(*ip6));
- ip6 = (struct ip6 *)(m->m_data + ipoff);
- ip_hlen = sizeof(*ip6);
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+ ip_hlen = sizeof(struct ip6_hdr);
/* XXX-BZ this will go badly in case of ext hdrs. */
ipproto = ip6->ip6_nxt;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
@@ -2447,8 +2438,9 @@ ixgbe_get_buf(struct rx_ring *rxr, int i)
return (ENOBUFS);
mp->m_len = mp->m_pkthdr.len = sc->rx_mbuf_sz;
- if (sc->max_frame_size <= (sc->rx_mbuf_sz - ETHER_ALIGN))
- m_adj(mp, ETHER_ALIGN);
+#ifdef __STRICT_ALIGNMENT
+ m_adj(mp, ETHER_ALIGN);
+#endif
error = bus_dmamap_load_mbuf(rxr->rxdma.dma_tag, rxbuf->map,
mp, BUS_DMA_NOWAIT);
@@ -2655,7 +2647,11 @@ ixgbe_initialize_receive_units(struct ix_softc *sc)
hlreg |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(&sc->hw, IXGBE_HLREG0, hlreg);
+#ifdef __STRICT_ALIGNMENT
+ bufsz = (sc->rx_mbuf_sz - ETHER_ALIGN) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#else
bufsz = sc->rx_mbuf_sz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#endif
for (i = 0; i < sc->num_queues; i++, rxr++) {
uint64_t rdba = rxr->rxdma.dma_map->dm_segs[0].ds_addr;
@@ -2853,7 +2849,6 @@ ixgbe_rxeof(struct ix_queue *que)
rxr->last_desc_filled);
}
- /* XXX ixgbe_realign() STRICT_ALIGN */
/* Currently no HW RSC support of 82599 */
if (!eop) {
/*