> 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.

Reply via email to