On 09/09/19(Mon) 16:37, Stefan Sperling wrote:
> On Mon, Sep 09, 2019 at 03:10:04PM +0200, Stefan Sperling wrote:
> > The wifi stack currently calls if_input once per packet instead of once
> > per interrupt. To make the wifi layer play nicely with the network stack
> > we can split ieee80211_input() into two parts:
> 
> Updated diff which avoids purging the input queue at every state
> change, e.g. even during SCAN->SCAN. With this we only purge the
> queue if we're leaving RUN state or going back to INIT state.

Thanks a lot!  I must say I looked at this in the past but got lost in
ieee80211_input().

Why not keep ieee80211_input() as a wrapper around your new mechanism?
This way you don't need to touch all drivers at once.

I'd also suggest using a queue on-stack like we do for Ethernet drivers,
this would get rid of the cleanup of `ic_ml' when the state change.  It
would also help developers familiar with Ethernet drivers to understand
what's happening ;o)

What about:

          ieee80211_enqueue(ifp, m, ni, &rxi, &ml);
          ieee80211_inputm(ifp, &ml);

Are you sure if_input() needs to be called at splnet()?  I don't think
so because many pseudo-drivers call it at a different IPL.

> diff refs/heads/master refs/heads/ifqdrop
> blob - a1ca62ea1a4b5af7d1d1765eb1da131e15e21e4e
> blob + bb0660f8da5ea340de57519e471b3a1a88c7da33
> --- sys/dev/ic/acx.c
> +++ sys/dev/ic/acx.c
> @@ -1398,6 +1398,7 @@ acx_rxeof(struct acx_softc *sc)
>                       rxi.rxi_rssi = head->rbh_level;
>                       rxi.rxi_tstamp = letoh32(head->rbh_time);
>                       ieee80211_input(ifp, m, ni, &rxi);
> +                     ieee80211_input_flush(ifp);
>  
>                       ieee80211_release_node(ic, ni);
>               } else {
> blob - d3b9ada242c555f179dad1529c20a1748d4b7917
> blob + d62e42897867623911ae53637503a42178637603
> --- sys/dev/ic/an.c
> +++ sys/dev/ic/an.c
> @@ -477,6 +477,7 @@ an_rxeof(struct an_softc *sc)
>       rxi.rxi_rssi = frmhdr.an_rx_signal_strength;
>       rxi.rxi_tstamp = an_switch32(frmhdr.an_rx_time);
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>       ieee80211_release_node(ic, ni);
>  }
>  
> blob - d72e8edceada8a680744a6b8478bb91ac9e15e6e
> blob + 14dc84e692380a6a59b9fd9e3846f83e9a28e461
> --- sys/dev/ic/ar5008.c
> +++ sys/dev/ic/ar5008.c
> @@ -960,7 +960,12 @@ ar5008_rx_process(struct athn_softc *sc)
>  void
>  ar5008_rx_intr(struct athn_softc *sc)
>  {
> +     struct ieee80211com *ic = &sc->sc_ic;
> +     struct ifnet *ifp = &ic->ic_if;
> +
>       while (ar5008_rx_process(sc) == 0);
> +
> +     ieee80211_input_flush(ifp);
>  }
>  
>  int
> blob - 69ade5ade5a35e632a025db327668d695a0edd2d
> blob + c34c8dae63f268c4baa4b8be396e0a6f6af8d05b
> --- sys/dev/ic/ar9003.c
> +++ sys/dev/ic/ar9003.c
> @@ -1066,7 +1066,12 @@ ar9003_rx_process(struct athn_softc *sc, int qid)
>  void
>  ar9003_rx_intr(struct athn_softc *sc, int qid)
>  {
> +     struct ieee80211com *ic = &sc->sc_ic;
> +     struct ifnet *ifp = &ic->ic_if;
> +
>       while (ar9003_rx_process(sc, qid) == 0);
> +
> +     ieee80211_input_flush(ifp);
>  }
>  
>  int
> blob - c0c5f4241b010c5c38a557d97963fbdbc884336d
> blob + 4d481bf2aada58fd7f9c484e3564db5b3d96d2b0
> --- sys/dev/ic/ath.c
> +++ sys/dev/ic/ath.c
> @@ -2005,6 +2005,8 @@ ath_rx_proc(void *arg, int npending)
>               TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
>       } while (ath_rxbuf_init(sc, bf) == 0);
>  
> +     ieee80211_input_flush(ifp);
> +
>       ath_hal_set_rx_signal(ah);              /* rx signal state monitoring */
>       ath_hal_start_rx(ah);                   /* in case of RXEOL */
>  #undef PA2DESC
> blob - cbf21da74007080c510fa9c56a58aedff62fa586
> blob + 301b784e1b6878e0b024e17f7e515097fa6363d1
> --- sys/dev/ic/atw.c
> +++ sys/dev/ic/atw.c
> @@ -3191,6 +3191,7 @@ atw_rxintr(struct atw_softc *sc)
>                */
>               ieee80211_release_node(ic, ni);
>       }
> +     ieee80211_input_flush(ifp);
>  
>       /* Update the receive pointer. */
>       sc->sc_rxptr = i;
> blob - 7d6f2c5a5693881e2dffdd1814a757c9563196fc
> blob + 9ce7309aeb96e7282fc8ac28e3cfc633e1d9f592
> --- sys/dev/ic/bwfm.c
> +++ sys/dev/ic/bwfm.c
> @@ -2118,6 +2118,7 @@ bwfm_rx_auth_ind(struct bwfm_softc *sc, struct bwfm_ev
>       rxi.rxi_rssi = 0;
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ic->ic_bss, &rxi);
> +     ieee80211_input_flush(ifp);
>  }
>  
>  void
> @@ -2174,6 +2175,7 @@ bwfm_rx_assoc_ind(struct bwfm_softc *sc, struct bwfm_e
>       rxi.rxi_rssi = 0;
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  }
>  
>  void
> @@ -2229,6 +2231,7 @@ bwfm_rx_leave_ind(struct bwfm_softc *sc, struct bwfm_e
>       rxi.rxi_rssi = 0;
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  }
>  #endif
>  
> @@ -2418,6 +2421,7 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_
>       rxi.rxi_rssi = (int16_t)letoh16(bss->rssi);
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>       /* Restore channel */
>       if (bss_chan)
>               ni->ni_chan = bss_chan;
> blob - 58417ce6f7de644fe86347459c04553956b2edc0
> blob + 25a40399a82089a496698f4a1fb8d88cb59375ac
> --- sys/dev/ic/bwi.c
> +++ sys/dev/ic/bwi.c
> @@ -8466,6 +8466,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
>  next:
>               idx = (idx + 1) % BWI_RX_NDESC;
>       }
> +     ieee80211_input_flush(ifp);
>  
>       rbd->rbd_idx = idx;
>       bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
> blob - 6a8c5646f0b6f649a60793e127cbd746d8ee89d7
> blob + bcd515d11a392f49f75914f1af6581b35b8cf054
> --- sys/dev/ic/malo.c
> +++ sys/dev/ic/malo.c
> @@ -1727,6 +1727,7 @@ skip:
>               sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
>                   MALO_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(ifp);
>  
>       malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr);
>  }
> blob - f44264645097e6f991f5642f7973ed5ebe3e5d7e
> blob + 2f316718eb1c5310c46c64394c8b3603b056499e
> --- sys/dev/ic/pgt.c
> +++ sys/dev/ic/pgt.c
> @@ -1036,6 +1036,7 @@ input:
>                       ifp->if_ierrors++;
>               }
>       }
> +     ieee80211_input_flush(ifp);
>  }
>  
>  void
> blob - c8d85564272d263215e829d007c11a47741316e6
> blob + 32b3ddbc260c86e39043baef04ceb64edf4c02b4
> --- sys/dev/ic/rt2560.c
> +++ sys/dev/ic/rt2560.c
> @@ -1220,6 +1220,7 @@ skip:           desc->flags = htole32(RT2560_RX_BUSY);
>               sc->rxq.cur_decrypt =
>                   (sc->rxq.cur_decrypt + 1) % RT2560_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(ifp);
>  }
>  
>  /*
> blob - 591115f692d4f77a522d114e5a91d6026e3452fe
> blob + 8e090624a986aee3b0748884baa8a84332d92ff5
> --- sys/dev/ic/rt2661.c
> +++ sys/dev/ic/rt2661.c
> @@ -1302,6 +1302,7 @@ skip:           desc->flags |= htole32(RT2661_RX_BUSY);
>  
>               sc->rxq.cur = (sc->rxq.cur + 1) % RT2661_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(ifp);
>  }
>  
>  #ifndef IEEE80211_STA_ONLY
> blob - c6c811c835ef4558079c00d50041075b9a8321bb
> blob + 2fc9aedb090a50080c099d5b24ca96535ccf33dc
> --- sys/dev/ic/rt2860.c
> +++ sys/dev/ic/rt2860.c
> @@ -1432,6 +1432,7 @@ skip:           rxd->sdl0 &= ~htole16(RT2860_RX_DDONE);
>  
>               sc->rxq.cur = (sc->rxq.cur + 1) % RT2860_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(ifp);
>  
>       /* tell HW what we have processed */
>       RAL_WRITE(sc, RT2860_RX_CALC_IDX,
> blob - ce7686c40fa4b1166d0af3fe54d8cad60704f556
> blob + 420bcd5f0db656fb85833f6ad290b2432c1fe82f
> --- sys/dev/ic/rtw.c
> +++ sys/dev/ic/rtw.c
> @@ -1294,6 +1294,7 @@ rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
>  next:
>               rtw_rxdesc_init(rdb, rs, next, 0);
>       }
> +     ieee80211_input_flush(&sc->sc_if);
>       rdb->rdb_next = next;
>  
>       KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
> blob - cd0d354d12f45e34327a1d9d2d6ae5b480f9e305
> blob + cf8f4f3f38d70f01c28136f6a2e3f9f8fa9dc7c4
> --- sys/dev/pci/if_ipw.c
> +++ sys/dev/pci/if_ipw.c
> @@ -966,6 +966,7 @@ ipw_rx_intr(struct ipw_softc *sc)
>                   i * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
>                   BUS_DMASYNC_PREWRITE);
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>       /* tell the firmware what we have processed */
>       sc->rxcur = (r == 0) ? IPW_NRBD - 1 : r - 1;
> blob - bdb4827425118b9159ae05ad1263bdf5c084254f
> blob + 77621142318b26269d864de7443d3f6cd27ffe27
> --- sys/dev/pci/if_iwi.c
> +++ sys/dev/pci/if_iwi.c
> @@ -1105,6 +1105,7 @@ iwi_rx_intr(struct iwi_softc *sc)
>  
>               sc->rxq.cur = (sc->rxq.cur + 1) % IWI_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>       /* tell the firmware what we have processed */
>       hw = (hw == 0) ? IWI_RX_RING_COUNT - 1 : hw - 1;
> blob - 0b2116dbc13428f1726773000e8e6a8c251d86b4
> blob + d347c3d8f4853099592dd1617dcfd5946bdd5c6c
> --- sys/dev/pci/if_iwm.c
> +++ sys/dev/pci/if_iwm.c
> @@ -7289,6 +7289,7 @@ iwm_notif_intr(struct iwm_softc *sc)
>  
>               ADVANCE_RXQ(sc);
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>       /*
>        * Tell the firmware what we have processed.
> blob - 6be794c2cd435c74b1b5c3f028b9613dc74ecf20
> blob + 06d0e55d42910fc8c60bd29078829399cf337fe4
> --- sys/dev/pci/if_iwn.c
> +++ sys/dev/pci/if_iwn.c
> @@ -2913,6 +2913,7 @@ iwn_notif_intr(struct iwn_softc *sc)
>  
>               sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>       /* Tell the firmware what we have processed. */
>       hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
> blob - 2c53aa925247b5056360daf479fca12e45624107
> blob + 9dc76928c677c89fc9f7d2aa09082bf73e62190c
> --- sys/dev/pci/if_rtwn.c
> +++ sys/dev/pci/if_rtwn.c
> @@ -1511,6 +1511,8 @@ rtwn_88e_intr(struct rtwn_pci_softc *sc)
>               rtwn_tx_done(sc, RTWN_VO_QUEUE);
>       if ((status & (R88E_HIMR_ROK | R88E_HIMR_RDU)) ||
>           (estatus & R88E_HIMRE_RXFOVW)) {
> +             struct ieee80211com *ic = &sc->sc_sc.sc_ic;
> +
>               bus_dmamap_sync(sc->sc_dmat, sc->rx_ring.map, 0,
>                   sizeof(struct r92c_rx_desc_pci) * RTWN_RX_LIST_COUNT,
>                   BUS_DMASYNC_POSTREAD);
> @@ -1524,6 +1526,7 @@ rtwn_88e_intr(struct rtwn_pci_softc *sc)
>  
>                       rtwn_rx_frame(sc, rx_desc, rx_data, i);
>               }
> +             ieee80211_input_flush(&ic->ic_if);
>       }
>  
>       if (status & R88E_HIMR_HSISR_IND_ON_INT) {
> @@ -1561,6 +1564,8 @@ rtwn_intr(void *xsc)
>  
>       /* Vendor driver treats RX errors like ROK... */
>       if (status & (R92C_IMR_ROK | R92C_IMR_RXFOVW | R92C_IMR_RDU)) {
> +             struct ieee80211com *ic = &sc->sc_sc.sc_ic;
> +
>               bus_dmamap_sync(sc->sc_dmat, sc->rx_ring.map, 0,
>                   sizeof(struct r92c_rx_desc_pci) * RTWN_RX_LIST_COUNT,
>                   BUS_DMASYNC_POSTREAD);
> @@ -1574,6 +1579,7 @@ rtwn_intr(void *xsc)
>  
>                       rtwn_rx_frame(sc, rx_desc, rx_data, i);
>               }
> +             ieee80211_input_flush(&ic->ic_if);
>       }
>  
>       if (status & R92C_IMR_BDOK)
> blob - 2a91ccec016f8047bfe26ede71e8881404fef619
> blob + 02f8191621b3c3967aab4abec9447c7cd4e5ffac
> --- sys/dev/pci/if_wpi.c
> +++ sys/dev/pci/if_wpi.c
> @@ -1527,6 +1527,7 @@ wpi_notif_intr(struct wpi_softc *sc)
>  
>               sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT;
>       }
> +     ieee80211_input_flush(&ic->ic_if);
>  
>       /* Tell the firmware what we have processed. */
>       hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
> blob - 39edb129685cac47d29224f18c6f2e7c92922720
> blob + 2fe4fc1af606a4ab32e6dcce83cc7c710e3c814b
> --- sys/dev/usb/if_athn_usb.c
> +++ sys/dev/usb/if_athn_usb.c
> @@ -2175,6 +2175,7 @@ athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
>               buf += off;
>               len -= off;
>       }
> +     ieee80211_input_flush(ifp);
>  
>   resubmit:
>       /* Setup a new transfer. */
> blob - 7c49042002e73f07bda3c9a5dc7e13e9d7e97503
> blob + 46fa39efc05c66d59e7e73c94dfe2b5ec635d9ad
> --- sys/dev/usb/if_atu.c
> +++ sys/dev/usb/if_atu.c
> @@ -1743,6 +1743,7 @@ atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_sta
>       rxi.rxi_rssi = h->rssi;
>       rxi.rxi_tstamp = UGETDW(h->rx_time);
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       ieee80211_release_node(ic, ni);
>  done1:
> blob - cb7e65865adb17b86e10bf5c2bc59983a5c8c2c9
> blob + 3c8da94867b14ab18d315b7c69c1188cc770569d
> --- sys/dev/usb/if_otus.c
> +++ sys/dev/usb/if_otus.c
> @@ -1241,6 +1241,7 @@ otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>               buf += hlen;
>               len -= hlen;
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>   resubmit:
>       usbd_setup_xfer(xfer, sc->data_rx_pipe, data, data->buf, OTUS_RXBUFSZ,
> blob - 9d81664f824def87770512b3e61a015782c99be0
> blob + 623fd79146a1879baf23aee4380611444c21f440
> --- sys/dev/usb/if_ral.c
> +++ sys/dev/usb/if_ral.c
> @@ -782,6 +782,7 @@ ural_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>       rxi.rxi_rssi = desc->rssi;
>       rxi.rxi_tstamp = 0;     /* unused */
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       /* node is no longer needed */
>       ieee80211_release_node(ic, ni);
> blob - 417666c3503da89fce1d3dc4301b48376dcf7e41
> blob + e8d263d2c4322d44836e0197cdd909adc795648e
> --- sys/dev/usb/if_rsu.c
> +++ sys/dev/usb/if_rsu.c
> @@ -1120,6 +1120,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, i
>       rxi.rxi_rssi = letoh32(bss->rssi);
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>       /* Node is no longer needed. */
>       ieee80211_release_node(ic, ni);
>  }
> @@ -1415,6 +1416,7 @@ rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf,
>               buf += totlen;
>               len -= totlen;
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  }
>  
>  void
> blob - 7126aaa9540a3f838e7bc1d4e80a06e759e98517
> blob + 3fe904607ebf7584cee0348ebb9d4135510d499e
> --- sys/dev/usb/if_rum.c
> +++ sys/dev/usb/if_rum.c
> @@ -851,6 +851,7 @@ rum_rxeof(struct usbd_xfer *xfer, void *priv, usbd_sta
>       rxi.rxi_rssi = desc->rssi;
>       rxi.rxi_tstamp = 0;     /* unused */
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       /* node is no longer needed */
>       ieee80211_release_node(ic, ni);
> blob - fc6ba52f271725fe7afbb4abf1a4a1700920a1b4
> blob + 5342470a39c8094143e9372855c0511c2ed0161e
> --- sys/dev/usb/if_run.c
> +++ sys/dev/usb/if_run.c
> @@ -2352,6 +2352,7 @@ run_rxeof(struct usbd_xfer *xfer, void *priv, usbd_sta
>               buf += dmalen + 8;
>               xferlen -= dmalen + 8;
>       }
> +     ieee80211_input_flush(&sc->sc_ic.ic_if);
>  
>  skip:        /* setup a new transfer */
>       usbd_setup_xfer(xfer, sc->rxq.pipeh, data, data->buf, RUN_MAX_RXSZ,
> blob - 30aa31b56bfd1226a4199c9024907adbbb3e429d
> blob + d657466dccf52fb1271a3650718feecb6e19c297
> --- sys/dev/usb/if_uath.c
> +++ sys/dev/usb/if_uath.c
> @@ -1265,6 +1265,7 @@ uath_data_rxeof(struct usbd_xfer *xfer, void *priv,
>       rxi.rxi_rssi = (int)betoh32(desc->rssi);
>       rxi.rxi_tstamp = 0;     /* unused */
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       /* node is no longer needed */
>       ieee80211_release_node(ic, ni);
> blob - 6c8b66842fb650329fb36d812e76fa41be9ab9c7
> blob + 72928af7c891bcc295dd79d71a2b6155a64eb0a5
> --- sys/dev/usb/if_upgt.c
> +++ sys/dev/usb/if_upgt.c
> @@ -1748,6 +1748,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkgl
>       rxi.rxi_rssi = rxdesc->rssi;
>       rxi.rxi_tstamp = 0;     /* unused */
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       /* node is no longer needed */
>       ieee80211_release_node(ic, ni);
> blob - 17d56c174230515195c13c070aed9065a68bc959
> blob + 87bdc93a6df4786458f6eec62ceb025cc7e75a5a
> --- sys/dev/usb/if_urtw.c
> +++ sys/dev/usb/if_urtw.c
> @@ -3161,6 +3161,7 @@ urtw_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>       rxi.rxi_rssi = rssi;
>       rxi.rxi_tstamp = 0;
>       ieee80211_input(ifp, m, ni, &rxi);
> +     ieee80211_input_flush(ifp);
>  
>       /* node is no longer needed */
>       ieee80211_release_node(ic, ni);
> blob - 96a1ad1a91c3e98ebc6dece98df6ac277046612c
> blob + 3f353ff8296162cde2163af94099b9a666bb106c
> --- sys/dev/usb/if_urtwn.c
> +++ sys/dev/usb/if_urtwn.c
> @@ -1206,6 +1206,7 @@ urtwn_rxeof(struct usbd_xfer *xfer, void *priv,
>  {
>       struct urtwn_rx_data *data = priv;
>       struct urtwn_softc *sc = data->sc;
> +     struct ieee80211com *ic = &sc->sc_sc.sc_ic;
>       struct r92c_rx_desc_usb *rxd;
>       uint32_t rxdw0;
>       uint8_t *buf;
> @@ -1305,6 +1306,7 @@ urtwn_rxeof(struct usbd_xfer *xfer, void *priv,
>               buf += totlen;
>               len -= totlen;
>       }
> +     ieee80211_input_flush(&ic->ic_if);
>  
>   resubmit:
>       /* Setup a new transfer. */
> blob - 689ac7e7178ca36a091d25cc6f2cf8d15cc45b0b
> blob + 498bb68138994cd361f996c866e95c959a5ddf15
> --- sys/dev/usb/if_zyd.c
> +++ sys/dev/usb/if_zyd.c
> @@ -2039,6 +2039,7 @@ zyd_rxeof(struct usbd_xfer *xfer, void *priv, usbd_sta
>  
>               zyd_rx_data(sc, data->buf, len);
>       }
> +     ieee80211_input_flush(ifp);
>  
>  skip:        /* setup a new transfer */
>       usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL,
> blob - ace97a38cc4ff76b454c1f6a12655565ad131275
> blob + c20962c799b141638a2fff11d5ceef6d6db47667
> --- sys/net80211/ieee80211.c
> +++ sys/net80211/ieee80211.c
> @@ -184,6 +184,8 @@ ieee80211_ifattach(struct ifnet *ifp)
>       ic->ic_bmissthres = 7;  /* default 7 beacons */
>       ic->ic_dtim_period = 1; /* all TIMs are DTIMs */
>  
> +     ml_init(&ic->ic_ml);
> +
>       ieee80211_node_attach(ifp);
>       ieee80211_proto_attach(ifp);
>  
> @@ -200,6 +202,7 @@ ieee80211_ifdetach(struct ifnet *ifp)
>  {
>       struct ieee80211com *ic = (void *)ifp;
>  
> +     ml_purge(&ic->ic_ml);
>       timeout_del(&ic->ic_bgscan_timeout);
>       ieee80211_proto_detach(ifp);
>       ieee80211_crypto_detach(ifp);
> blob - 73a9d5229502797c5279734663b1ac1591bec309
> blob + de36481038ec3372d0d5533002cbc62a1ebe2b6a
> --- sys/net80211/ieee80211_input.c
> +++ sys/net80211/ieee80211_input.c
> @@ -71,11 +71,11 @@ void      ieee80211_input_ba_seq(struct ieee80211com *,
>           struct ieee80211_node *, uint8_t, uint16_t);
>  struct       mbuf *ieee80211_align_mbuf(struct mbuf *);
>  void ieee80211_decap(struct ieee80211com *, struct mbuf *,
> -         struct ieee80211_node *, int);
> +         struct ieee80211_node *, int, struct mbuf_list *);
>  void ieee80211_amsdu_decap(struct ieee80211com *, struct mbuf *,
> -         struct ieee80211_node *, int);
> -void ieee80211_deliver_data(struct ieee80211com *, struct mbuf *,
> -         struct ieee80211_node *, int);
> +         struct ieee80211_node *, int, struct mbuf_list *);
> +void ieee80211_enqueue_data(struct ieee80211com *, struct mbuf *,
> +         struct ieee80211_node *, int, struct mbuf_list *);
>  int  ieee80211_parse_edca_params_body(struct ieee80211com *,
>           const u_int8_t *);
>  int  ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
> @@ -155,6 +155,9 @@ ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
>   * any units so long as values have consistent units and higher values
>   * mean ``better signal''.  The receive timestamp is currently not used
>   * by the 802.11 layer.
> + *
> + * This function only queues frames for delivery.
> + * Actual delivery to upper layers is triggered by ieee80211_input_flush().
>   */
>  void
>  ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
> @@ -463,9 +466,9 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, str
>  
>               if ((ni->ni_flags & IEEE80211_NODE_HT) &&
>                   hasqos && (qos & IEEE80211_QOS_AMSDU))
> -                     ieee80211_amsdu_decap(ic, m, ni, hdrlen);
> +                     ieee80211_amsdu_decap(ic, m, ni, hdrlen, &ic->ic_ml);
>               else
> -                     ieee80211_decap(ic, m, ni, hdrlen);
> +                     ieee80211_decap(ic, m, ni, hdrlen, &ic->ic_ml);
>               return;
>  
>       case IEEE80211_FC0_TYPE_MGT:
> @@ -561,6 +564,22 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, str
>  }
>  
>  /*
> + * Deliver frames queued by ieee80211_input() to the network stack.
> + * Drivers should call this function only once per Rx interrupt to avoid
> + * triggering the input ifq pressure drop mechanism unnecessarily.
> + */
> +void
> +ieee80211_input_flush(struct ifnet *ifp)
> +{
> +     struct ieee80211com *ic = (void *)ifp;
> +     int s;
> +
> +     s = splnet();
> +     if_input(ifp, &ic->ic_ml);
> +     splx(s);
> +}
> +
> +/*
>   * Handle defragmentation (see 9.5 and Annex C).  We support the concurrent
>   * reception of fragments of three fragmented MSDUs or MMPDUs.
>   */
> @@ -856,8 +875,8 @@ ieee80211_ba_move_window(struct ieee80211com *ic, stru
>  }
>  
>  void
> -ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
> -    struct ieee80211_node *ni, int mcast)
> +ieee80211_enqueue_data(struct ieee80211com *ic, struct mbuf *m,
> +    struct ieee80211_node *ni, int mcast, struct mbuf_list *ml)
>  {
>       struct ifnet *ifp = &ic->ic_if;
>       struct ether_header *eh;
> @@ -920,16 +939,14 @@ ieee80211_deliver_data(struct ieee80211com *ic, struct
>  #endif
>                       ieee80211_eapol_key_input(ic, m, ni);
>               } else {
> -                     struct mbuf_list ml = MBUF_LIST_INITIALIZER();
> -                     ml_enqueue(&ml, m);
> -                     if_input(ifp, &ml);
> +                     ml_enqueue(ml, m);
>               }
>       }
>  }
>  
>  void
>  ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
> -    struct ieee80211_node *ni, int hdrlen)
> +    struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
>  {
>       struct ether_header eh;
>       struct ieee80211_frame *wh;
> @@ -985,7 +1002,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf *
>                       return;
>               }
>       }
> -     ieee80211_deliver_data(ic, m, ni, mcast);
> +     ieee80211_enqueue_data(ic, m, ni, mcast, ml);
>  }
>  
>  /*
> @@ -993,7 +1010,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf *
>   */
>  void
>  ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
> -    struct ieee80211_node *ni, int hdrlen)
> +    struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
>  {
>       struct mbuf *n;
>       struct ether_header *eh;
> @@ -1059,7 +1076,7 @@ ieee80211_amsdu_decap(struct ieee80211com *ic, struct 
>                       m_freem(m);
>                       break;
>               }
> -             ieee80211_deliver_data(ic, m, ni, mcast);
> +             ieee80211_enqueue_data(ic, m, ni, mcast, ml);
>  
>               if (n->m_pkthdr.len == 0) {
>                       m_freem(n);
> blob - d00d1b631f2966efbd88992c92fea88a99e3ddf8
> blob + 87c41116d48d86cf446cae6486ee1dde42a92701
> --- sys/net80211/ieee80211_proto.c
> +++ sys/net80211/ieee80211_proto.c
> @@ -974,9 +974,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee8
>       struct ieee80211_node *ni;
>       enum ieee80211_state ostate;
>       u_int rate;
> -#ifndef IEEE80211_STA_ONLY
>       int s;
> -#endif
>  
>       ostate = ic->ic_state;
>       if (ifp->if_flags & IFF_DEBUG)
> @@ -1060,6 +1058,9 @@ justcleanup:
>                       ic->ic_mgt_timer = 0;
>                       mq_purge(&ic->ic_mgtq);
>                       mq_purge(&ic->ic_pwrsaveq);
> +                     s = splnet();
> +                     ml_purge(&ic->ic_ml);
> +                     splx(s);
>                       ieee80211_free_allnodes(ic, 1);
>                       break;
>               }
> @@ -1113,6 +1114,9 @@ justcleanup:
>                       ic->ic_bgscan_fail = 0;
>                       ieee80211_stop_ampdu_tx(ic, ni, mgt);
>                       ieee80211_free_allnodes(ic, 1);
> +                     s = splnet();
> +                     ml_purge(&ic->ic_ml);
> +                     splx(s);
>                       /* FALLTHROUGH */
>               case IEEE80211_S_AUTH:
>               case IEEE80211_S_ASSOC:
> @@ -1161,6 +1165,9 @@ justcleanup:
>                       ic->ic_bgscan_fail = 0;
>                       ieee80211_stop_ampdu_tx(ic, ni, mgt);
>                       ieee80211_ba_del(ni);
> +                     s = splnet();
> +                     ml_purge(&ic->ic_ml);
> +                     splx(s);
>                       switch (mgt) {
>                       case IEEE80211_FC0_SUBTYPE_AUTH:
>                               IEEE80211_SEND_MGMT(ic, ni,
> @@ -1193,6 +1200,9 @@ justcleanup:
>               case IEEE80211_S_RUN:
>                       ieee80211_stop_ampdu_tx(ic, ni, mgt);
>                       ieee80211_ba_del(ni);
> +                     s = splnet();
> +                     ml_purge(&ic->ic_ml);
> +                     splx(s);
>                       IEEE80211_SEND_MGMT(ic, ni,
>                           IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
>                       break;
> blob - e622d35f4dcd21ea0bb40c6a5d0b3f758e197b38
> blob + c1d3ad65a46f76266533a4cfd5fffa08b4fa6537
> --- sys/net80211/ieee80211_proto.h
> +++ sys/net80211/ieee80211_proto.h
> @@ -68,6 +68,7 @@ extern      u_int ieee80211_get_hdrlen(const struct ieee802
>  extern       int ieee80211_classify(struct ieee80211com *, struct mbuf *);
>  extern       void ieee80211_input(struct ifnet *, struct mbuf *,
>               struct ieee80211_node *, struct ieee80211_rxinfo *);
> +extern       void ieee80211_input_flush(struct ifnet *);
>  extern       int ieee80211_output(struct ifnet *, struct mbuf *, struct 
> sockaddr *,
>               struct rtentry *);
>  extern       void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *,
> blob - 2a567a01422aaaf6024b05c5589f6f45b3744100
> blob + fcbe48513883c4c81cfb4c4d96e4d5d08a07ab7f
> --- sys/net80211/ieee80211_var.h
> +++ sys/net80211/ieee80211_var.h
> @@ -340,6 +340,8 @@ struct ieee80211com {
>       u_int8_t                ic_dialog_token;
>       int                     ic_fixed_mcs;
>       TAILQ_HEAD(, ieee80211_ess)      ic_ess;
> +
> +     struct mbuf_list ic_ml; /* frames queued for if_input() */
>  };
>  #define      ic_if           ic_ac.ac_if
>  #define      ic_softc        ic_if.if_softc
> 

Reply via email to