Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev bwfm has only one tx descriptor; limit mbuf chains t...
details: https://anonhg.NetBSD.org/src/rev/3edad1fc5f4e
branches: trunk
changeset: 366543:3edad1fc5f4e
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Sep 01 22:01:03 2018 +0000
description:
bwfm has only one tx descriptor; limit mbuf chains to one segment.
PR kern/53287
Can't use m_defrag because it always yields two segments.
Discussion on tech-net:
https://mail-index.netbsd.org/tech-net/2018/09/01/msg007031.html
Diagnosed and tested by maya.
diffstat:
sys/dev/ic/bwfm.c | 4 +-
sys/dev/ic/bwfmvar.h | 4 +-
sys/dev/pci/if_bwfm_pci.c | 57 ++++++++++++++++++++++++++++++----------------
sys/dev/usb/if_bwfm_usb.c | 9 ++++---
4 files changed, 46 insertions(+), 28 deletions(-)
diffs (236 lines):
diff -r aaaa00964f0d -r 3edad1fc5f4e sys/dev/ic/bwfm.c
--- a/sys/dev/ic/bwfm.c Sat Sep 01 20:54:32 2018 +0000
+++ b/sys/dev/ic/bwfm.c Sat Sep 01 22:01:03 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfm.c,v 1.12 2018/06/26 06:48:00 msaitoh Exp $ */
+/* $NetBSD: bwfm.c,v 1.13 2018/09/01 22:01:03 riastradh Exp $ */
/* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
@@ -337,7 +337,7 @@
continue;
}
- error = sc->sc_bus_ops->bs_txdata(sc, m);
+ error = sc->sc_bus_ops->bs_txdata(sc, &m);
if (error == ENOBUFS) {
IF_PREPEND(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
diff -r aaaa00964f0d -r 3edad1fc5f4e sys/dev/ic/bwfmvar.h
--- a/sys/dev/ic/bwfmvar.h Sat Sep 01 20:54:32 2018 +0000
+++ b/sys/dev/ic/bwfmvar.h Sat Sep 01 22:01:03 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bwfmvar.h,v 1.2 2018/05/11 07:41:11 maya Exp $ */
+/* $NetBSD: bwfmvar.h,v 1.3 2018/09/01 22:01:03 riastradh Exp $ */
/* $OpenBSD: bwfmvar.h,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
@@ -93,7 +93,7 @@
void (*bs_init)(struct bwfm_softc *);
void (*bs_stop)(struct bwfm_softc *);
int (*bs_txcheck)(struct bwfm_softc *);
- int (*bs_txdata)(struct bwfm_softc *, struct mbuf *);
+ int (*bs_txdata)(struct bwfm_softc *, struct mbuf **);
int (*bs_txctl)(struct bwfm_softc *, char *, size_t);
int (*bs_rxctl)(struct bwfm_softc *, char *, size_t *);
};
diff -r aaaa00964f0d -r 3edad1fc5f4e sys/dev/pci/if_bwfm_pci.c
--- a/sys/dev/pci/if_bwfm_pci.c Sat Sep 01 20:54:32 2018 +0000
+++ b/sys/dev/pci/if_bwfm_pci.c Sat Sep 01 22:01:03 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bwfm_pci.c,v 1.1 2018/05/11 07:42:22 maya Exp $ */
+/* $NetBSD: if_bwfm_pci.c,v 1.2 2018/09/01 22:01:03 riastradh Exp $ */
/* $OpenBSD: if_bwfm_pci.c,v 1.18 2018/02/08 05:00:38 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
@@ -225,7 +225,7 @@
int bwfm_pci_pktid_avail(struct bwfm_pci_softc *,
struct bwfm_pci_pkts *);
int bwfm_pci_pktid_new(struct bwfm_pci_softc *,
- struct bwfm_pci_pkts *, struct mbuf *,
+ struct bwfm_pci_pkts *, struct mbuf **,
uint32_t *, paddr_t *);
struct mbuf * bwfm_pci_pktid_free(struct bwfm_pci_softc *,
struct bwfm_pci_pkts *, uint32_t);
@@ -281,7 +281,7 @@
void bwfm_pci_stop(struct bwfm_softc *);
int bwfm_pci_txcheck(struct bwfm_softc *);
-int bwfm_pci_txdata(struct bwfm_softc *, struct mbuf *);
+int bwfm_pci_txdata(struct bwfm_softc *, struct mbuf **);
#ifdef BWFM_DEBUG
void bwfm_pci_debug_console(struct bwfm_pci_softc *);
@@ -922,7 +922,7 @@
int
bwfm_pci_pktid_new(struct bwfm_pci_softc *sc, struct bwfm_pci_pkts *pkts,
- struct mbuf *m, uint32_t *pktid, paddr_t *paddr)
+ struct mbuf **mp, uint32_t *pktid, paddr_t *paddr)
{
int i, idx;
@@ -932,15 +932,32 @@
idx = 0;
if (pkts->pkts[idx].bb_m == NULL) {
if (bus_dmamap_load_mbuf(sc->sc_dmat,
- pkts->pkts[idx].bb_map, m, BUS_DMA_NOWAIT) != 0) {
- if (m_defrag(m, M_DONTWAIT))
- return EFBIG;
+ pkts->pkts[idx].bb_map, *mp, BUS_DMA_NOWAIT) != 0) {
+ /*
+ * Didn't fit. Maybe it has too many
+ * segments. If it has only one
+ * segment, fail; otherwise try to
+ * compact it into a single mbuf
+ * segment.
+ */
+ if ((*mp)->m_next == NULL)
+ return ENOBUFS;
+ struct mbuf *m0 = MCLGETI(NULL, M_DONTWAIT,
+ NULL, MSGBUF_MAX_PKT_SIZE);
+ if (m0 == NULL)
+ return ENOBUFS;
+ m_copydata(*mp, 0, (*mp)->m_pkthdr.len,
+ mtod(m0, void *));
+ m0->m_pkthdr.len = m0->m_len =
+ (*mp)->m_pkthdr.len;
+ m_freem(*mp);
+ *mp = m0;
if (bus_dmamap_load_mbuf(sc->sc_dmat,
- pkts->pkts[idx].bb_map, m, BUS_DMA_NOWAIT) != 0)
+ pkts->pkts[idx].bb_map, *mp, BUS_DMA_NOWAIT) != 0)
return EFBIG;
}
pkts->last = idx;
- pkts->pkts[idx].bb_m = m;
+ pkts->pkts[idx].bb_m = *mp;
*pktid = idx;
*paddr = pkts->pkts[idx].bb_map->dm_segs[0].ds_addr;
return 0;
@@ -997,7 +1014,7 @@
break;
}
m->m_len = m->m_pkthdr.len = MSGBUF_MAX_PKT_SIZE;
- if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, m, &pktid, &paddr)) {
+ if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, &m, &pktid, &paddr)) {
bwfm_pci_ring_write_cancel(sc, &sc->sc_ctrl_submit, 1);
m_freem(m);
break;
@@ -1037,7 +1054,7 @@
break;
}
m->m_len = m->m_pkthdr.len = MSGBUF_MAX_PKT_SIZE;
- if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, m, &pktid, &paddr)) {
+ if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, &m, &pktid, &paddr)) {
bwfm_pci_ring_write_cancel(sc, &sc->sc_rxpost_submit, 1);
m_freem(m);
break;
@@ -1388,7 +1405,7 @@
if (ring->m != NULL) {
m = ring->m;
ring->m = NULL;
- if (bwfm_pci_txdata(&sc->sc_sc, m))
+ if (bwfm_pci_txdata(&sc->sc_sc, &m))
m_freem(ring->m);
}
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1851,7 +1868,7 @@
}
int
-bwfm_pci_txdata(struct bwfm_softc *bwfm, struct mbuf *m)
+bwfm_pci_txdata(struct bwfm_softc *bwfm, struct mbuf **mp)
{
struct bwfm_pci_softc *sc = (void *)bwfm;
struct bwfm_pci_msgring *ring;
@@ -1861,7 +1878,7 @@
struct ether_header *eh;
int flowid, ret, ac;
- flowid = bwfm_pci_flowring_lookup(sc, m);
+ flowid = bwfm_pci_flowring_lookup(sc, *mp);
if (flowid < 0) {
/*
* We cannot send the packet right now as there is
@@ -1872,7 +1889,7 @@
* is created the queue will be restarted and this
* mbuf will be transmitted.
*/
- bwfm_pci_flowring_create(sc, m);
+ bwfm_pci_flowring_create(sc, *mp);
return 0;
}
@@ -1890,9 +1907,9 @@
return ENOBUFS;
/* No QoS for EAPOL frames. */
- eh = mtod(m, struct ether_header *);
+ eh = mtod(*mp, struct ether_header *);
ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
- M_WME_GETAC(m) : WME_AC_BE;
+ M_WME_GETAC(*mp) : WME_AC_BE;
memset(tx, 0, sizeof(*tx));
tx->msg.msgtype = MSGBUF_TYPE_TX_POST;
@@ -1900,9 +1917,9 @@
tx->flags = BWFM_MSGBUF_PKT_FLAGS_FRAME_802_3;
tx->flags |= ac << BWFM_MSGBUF_PKT_FLAGS_PRIO_SHIFT;
tx->seg_cnt = 1;
- memcpy(tx->txhdr, mtod(m, char *), ETHER_HDR_LEN);
+ memcpy(tx->txhdr, mtod(*mp, char *), ETHER_HDR_LEN);
- ret = bwfm_pci_pktid_new(sc, &sc->sc_tx_pkts, m, &pktid, &paddr);
+ ret = bwfm_pci_pktid_new(sc, &sc->sc_tx_pkts, mp, &pktid, &paddr);
if (ret) {
if (ret == ENOBUFS) {
printf("%s: no pktid available for TX\n",
@@ -1915,7 +1932,7 @@
paddr += ETHER_HDR_LEN;
tx->msg.request_id = htole32(pktid);
- tx->data_len = htole16(m->m_len - ETHER_HDR_LEN);
+ tx->data_len = htole16((*mp)->m_len - ETHER_HDR_LEN);
tx->data_buf_addr.high_addr = htole32(paddr >> 32);
tx->data_buf_addr.low_addr = htole32(paddr & 0xffffffff);
diff -r aaaa00964f0d -r 3edad1fc5f4e sys/dev/usb/if_bwfm_usb.c
--- a/sys/dev/usb/if_bwfm_usb.c Sat Sep 01 20:54:32 2018 +0000
+++ b/sys/dev/usb/if_bwfm_usb.c Sat Sep 01 22:01:03 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bwfm_usb.c,v 1.7 2018/08/12 06:02:38 rin Exp $ */
+/* $NetBSD: if_bwfm_usb.c,v 1.8 2018/09/01 22:01:03 riastradh Exp $ */
/* $OpenBSD: if_bwfm_usb.c,v 1.2 2017/10/15 14:55:13 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bwfm_usb.c,v 1.7 2018/08/12 06:02:38 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bwfm_usb.c,v 1.8 2018/09/01 22:01:03 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -203,7 +203,7 @@
void bwfm_usb_free_tx_list(struct bwfm_usb_softc *);
int bwfm_usb_txcheck(struct bwfm_softc *);
-int bwfm_usb_txdata(struct bwfm_softc *, struct mbuf *);
+int bwfm_usb_txdata(struct bwfm_softc *, struct mbuf **);
int bwfm_usb_txctl(struct bwfm_softc *, char *, size_t);
int bwfm_usb_rxctl(struct bwfm_softc *, char *, size_t *);
@@ -785,9 +785,10 @@
int
-bwfm_usb_txdata(struct bwfm_softc *bwfm, struct mbuf *m)
+bwfm_usb_txdata(struct bwfm_softc *bwfm, struct mbuf **mp)
{
struct bwfm_usb_softc *sc = (void *)bwfm;
+ struct mbuf *m = *mp;
struct bwfm_proto_bcdc_hdr *hdr;
struct bwfm_usb_tx_data *data;
struct ether_header *eh;
Home |
Main Index |
Thread Index |
Old Index