I have seen a kernel panic with iwn(4) due to a divide by zero on
this line in ieee80211_mira.c's ieee80211_mira_update_stats():

        sfer /= (mn->txfail + 1) * mn->frames;

We ended up in mira_choose() via iwn_rx_compressed_ba().

The following patch prevents the problem.

ok?

diff 618f51c546b1ced449867c384af3a2f0afbf155d /usr/src
blob - 73157095886b0073524e13ea29b695e7809aa870
file + sys/dev/pci/if_iwn.c
--- sys/dev/pci/if_iwn.c
+++ sys/dev/pci/if_iwn.c
@@ -2372,6 +2372,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_
                         */
                        if (txdata->m != NULL && txdata->ampdu_id == id &&
                            txdata->ampdu_txmcs == ni->ni_txmcs &&
+                           txdata->ampdu_nframes > 0 &&
                            (SEQ_LT(ba->ba_winend, s) ||
                            (ba->ba_bitmap & (1 << bit)) == 0)) {
                                have_ack++;
blob - 23bfcf0a331ed839037f8c2a4ef58ed640923233
file + sys/net80211/ieee80211_mira.c
--- sys/net80211/ieee80211_mira.c
+++ sys/net80211/ieee80211_mira.c
@@ -400,6 +400,9 @@ ieee80211_mira_update_stats(struct ieee80211_mira_node
        uint64_t rate = ieee80211_mira_get_txrate(ni->ni_txmcs, sgi);
        struct ieee80211_mira_goodput_stats *g = &mn->g[ni->ni_txmcs];
 
+       if (mn->frames == 0)
+               return; /* avoid divide-by-zero in sfer calculation below */
+
        g->nprobes += mn->agglen;
        g->nprobe_bytes += mn->ampdu_size;
 

Reply via email to