> Date: Thu, 6 Oct 2016 12:56:37 +0200 > From: Stefan Sperling <s...@stsp.name> > > On Thu, Oct 06, 2016 at 10:49:21AM +0200, Imre Vadasz wrote: > > Hi, > > This patch improves the error handling iwm_rx_addbuf(), specifically in > > out-of-memory and mbuf exhaustion cases. > > > > Keep an additional/spare bus_dmamap_t object around to make error handling > > for bus_dmamap_load_mbuf() failures easier in iwm_rx_addbuf(). > > This seems like an easy way to avoid having weird panic() cases in the code > > (like in iwn, which then tries to bus_dmamap_load_mbuf() the old mbuf and > > panics when that fails). > > > > Move mbuf modifications that are needed before calling ieee80211_input() > > in iwm_rx_rx_mpdu() to below the iwm_rx_addbuf call. Otherwise we can end > > up with a broken mbuf in the rx ring when iwm_rx_rx_mpdu() aborts. > > If memory is so tight that this panic triggers is it reasonable to > even try to recover? I honestly don't know. > > This problem exists in many drivers. > Are we going to add a spare map to all of them? > > $ egrep -i 'panic.*rx.*buf' pci/*c ic/*c > pci/if_ipw.c: panic("%s: could not load old rx mbuf", > pci/if_iwi.c: panic("%s: could not load old rx mbuf", > pci/if_iwm.c: panic("iwm: could not load RX mbuf"); > pci/if_iwn.c: panic("%s: could not load old RX mbuf", > pci/if_ix.c: panic("%s: ixgbe_rxeof: NULL mbuf in slot %d " > pci/if_nfe.c: panic("%s: could not load old rx mbuf", > pci/if_pcn.c: panic("pcn_add_rxbuf"); > pci/if_rtwn.c: panic("%s: could not load old RX mbuf", > pci/if_stge.c: panic("stge_add_rxbuf"); /* XXX */ > pci/if_vio.c: panic("enqueue_prep for rx buffers: %d", r); > pci/if_wpi.c: panic("%s: could not load old RX mbuf", > ic/aic6915.c: panic("sf_add_rxbuf"); /* XXX */ > ic/atw.c: panic("atw_add_rxbuf"); /* XXX */ > ic/dwc_gmac.c: panic("%s: could not load old > rx mbuf", > ic/gem.c: panic("gem_add_rxbuf"); /* XXX */ > ic/malo.c: panic("%s: could not load old rx mbuf", > ic/rt2560.c: panic("%s: could not load old rx mbuf", > ic/rt2661.c: panic("%s: could not load old rx mbuf", > ic/rt2860.c: panic("%s: could not load old rx mbuf", > ic/smc83c170.c: panic("epic_add_rxbuf"); /* XXX */
I think we're at the point where bus_dmamap_load() should never fail because of memory shortage. As part of the effort to make interrupt handlers mpsafe, we pre-allocate all the necessary resources. I think the sparc64 iommu code can still return ENOMEM, but only if you screw up and bus_dmam_load() something that doesn't fit into the resources created by bus_dmamap_create(). And that would almost certainly be a driver bug.