diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-07-05 12:35:17 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-07-05 12:35:17 +0000 |
commit | 9cbc54e735d6ae43aa0a659fea1ac4384236407a (patch) | |
tree | 43ceedb92bc2dd4ece644137b4603a8fdd05ac5d | |
parent | 78cb2532be3115ceffb7b842509a0eb79206ec82 (diff) |
Since on a SCAN each node is provided in its own event,
the limited ring for asynchronous can easily overflow.
Work around this by chaining the mbufs into a list.
Fixes a panic for jcs@
ok stsp@
-rw-r--r-- | sys/dev/ic/bwfm.c | 27 | ||||
-rw-r--r-- | sys/dev/ic/bwfmvar.h | 7 |
2 files changed, 21 insertions, 13 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 622a4ffb751..461f33f2561 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.62 2019/05/22 15:25:25 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.63 2019/07/05 12:35:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -131,7 +131,7 @@ int bwfm_newstate(struct ieee80211com *, enum ieee80211_state, int); void bwfm_set_key_cb(struct bwfm_softc *, void *); void bwfm_delete_key_cb(struct bwfm_softc *, void *); -void bwfm_rx_event_cb(struct bwfm_softc *, void *); +void bwfm_rx_event_cb(struct bwfm_softc *, struct mbuf *); struct mbuf *bwfm_newbuf(void); void bwfm_rx(struct bwfm_softc *, struct mbuf *); @@ -181,6 +181,7 @@ bwfm_attach(struct bwfm_softc *sc) sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0; sc->sc_taskq = taskq_create(DEVNAME(sc), 1, IPL_SOFTNET, 0); task_set(&sc->sc_task, bwfm_task, sc); + ml_init(&sc->sc_evml); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ @@ -2234,19 +2235,20 @@ bwfm_rx_leave_ind(struct bwfm_softc *sc, struct bwfm_event *e, size_t len, void bwfm_rx_event(struct bwfm_softc *sc, struct mbuf *m) { - struct bwfm_cmd_mbuf cmd; + int s; + + s = splsoftnet(); + ml_enqueue(&sc->sc_evml, m); + splx(s); - cmd.m = m; - bwfm_do_async(sc, bwfm_rx_event_cb, &cmd, sizeof(cmd)); + task_add(sc->sc_taskq, &sc->sc_task); } void -bwfm_rx_event_cb(struct bwfm_softc *sc, void *arg) +bwfm_rx_event_cb(struct bwfm_softc *sc, struct mbuf *m) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct bwfm_cmd_mbuf *cmd = arg; - struct mbuf *m = cmd->m; struct bwfm_event *e = mtod(m, void *); size_t len = m->m_len; @@ -2429,6 +2431,7 @@ bwfm_task(void *arg) struct bwfm_softc *sc = arg; struct bwfm_host_cmd_ring *ring = &sc->sc_cmdq; struct bwfm_host_cmd *cmd; + struct mbuf *m; int s; s = splsoftnet(); @@ -2441,6 +2444,14 @@ bwfm_task(void *arg) ring->next = (ring->next + 1) % BWFM_HOST_CMD_RING_COUNT; } splx(s); + + s = splsoftnet(); + while ((m = ml_dequeue(&sc->sc_evml)) != NULL) { + splx(s); + bwfm_rx_event_cb(sc, m); + s = splsoftnet(); + } + splx(s); } void diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 7ea91a21a28..c09bc87704c 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.15 2018/07/17 19:44:38 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.16 2019/07/05 12:35:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -121,10 +121,6 @@ struct bwfm_cmd_key { struct ieee80211_key *k; }; -struct bwfm_cmd_mbuf { - struct mbuf *m; -}; - struct bwfm_cmd_flowring_create { struct mbuf *m; int flowid; @@ -167,6 +163,7 @@ struct bwfm_softc { struct bwfm_host_cmd_ring sc_cmdq; struct taskq *sc_taskq; struct task sc_task; + struct mbuf_list sc_evml; int sc_bcdc_reqid; TAILQ_HEAD(, bwfm_proto_bcdc_ctl) sc_bcdc_rxctlq; |