Date: Fri, 16 Feb 2007 18:43:17 +0100 From: Jeremie Le Hen <jeremie@le-hen.org> To: "V.Chukharev" <chukharev@mail.ru> Cc: freebsd-net@freebsd.org, cognet@FreeBSD.org Subject: Re: iwi leaks memory? Message-ID: <20070216174317.GZ64768@obiwan.tataz.chchile.org> In-Reply-To: <op.tns7i21z0g54sc@localhost> References: <op.tns7i21z0g54sc@localhost>
next in thread | previous in thread | raw e-mail | index | archive | help
--vni90+aGYgRvsTuO Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, On Thu, Feb 15, 2007 at 11:34:48PM +0200, V.Chukharev wrote: > Hi, > > It seems that iwi driver cannot survive more than just a few cycles > of switching down/up. > In a place with a bad wireless connection I needed to do that quite > a number of times > (that was the simplest way to restore connectivity I knew), and after > 5-10 cycles I needed > to reboot my notebook totally. > > Can anybody with iwi (<Intel(R) PRO/Wireless 2200BG>) confirm (or > better unconfirm) > that doing > > for ii in `jot 100`; do sudo ifconfig iwi0 down; sleep 2; sudo ifconfig iwi0 up; done > > always results in the following messages (and lost connectivity): > > Feb 15 09:43:59 chu kernel: iwi0: link state changed to DOWN > Feb 15 09:44:13 chu kernel: iwi0: link state changed to UP > Feb 15 09:44:13 chu kernel: iwi0: link state changed to DOWN > Feb 15 09:44:18 chu kernel: iwi0: device timeout > Feb 15 09:44:20 chu kernel: iwi0: could not allocate firmware DMA memory > > A fix for this would be even better ;)) cognet@ has once provided me a tiny hack to the iwi(4) driver and I never get such errors. Maybe I'm not suffering enough UP/DOWN cycles to trigger it, but it might be worth trying it. Note that he has insisted that this is a *hack*. The patch is attached. Please let us know if it makes things better. Regards, -- Jeremie Le Hen < jeremie at le-hen dot org >< ttz at chchile dot org > --vni90+aGYgRvsTuO Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="if_iwi.c.patch" Index: if_iwi.c =================================================================== RCS file: /home/ncvs/src/sys/dev/iwi/if_iwi.c,v retrieving revision 1.45 diff -u -p -r1.45 if_iwi.c --- if_iwi.c 2 Feb 2007 05:17:18 -0000 1.45 +++ if_iwi.c 16 Feb 2007 17:40:33 -0000 @@ -512,6 +512,12 @@ iwi_detach(device_t dev) if (sc->mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); + if (sc->fw_map) + bus_dmamap_unload(sc->fw_dmat, sc->fw_map); + if (sc->fw_virtaddr != 0) + bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); + if (sc->fw_dmat) + bus_dma_tag_destroy(sc->fw_dmat); if (ifp != NULL) if_free(ifp); @@ -3085,6 +3091,7 @@ iwi_init_locked(void *priv, int force) struct ifnet *ifp = ic->ic_ifp; struct iwi_rx_data *data; int i; + int must_realloc = 0; IWI_LOCK_DECL; if (sc->flags & IWI_FLAG_FW_LOADING) @@ -3106,14 +3113,27 @@ iwi_init_locked(void *priv, int force) } /* allocate DMA memory for mapping firmware image */ - if (sc->fw_boot.size > sc->fw_dma_size) + if (sc->fw_boot.size > sc->fw_dma_size) { + must_realloc = 1; sc->fw_dma_size = sc->fw_boot.size; - if (sc->fw_fw.size > sc->fw_dma_size) + } + if (sc->fw_fw.size > sc->fw_dma_size) { + must_realloc = 1; sc->fw_dma_size = sc->fw_fw.size; - if (sc->fw_uc.size > sc->fw_dma_size) + } + if (sc->fw_uc.size > sc->fw_dma_size) { sc->fw_dma_size = sc->fw_uc.size; + must_realloc = 1; + } + if (must_realloc && sc->fw_virtaddr != 0) { + bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->fw_dmat, sc->fw_map); + bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); + bus_dma_tag_destroy(sc->fw_dmat); + } - if (bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + if (must_realloc && + bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, sc->fw_dma_size, 1, sc->fw_dma_size, 0, NULL, NULL, &sc->fw_dmat) != 0) { @@ -3122,14 +3142,16 @@ iwi_init_locked(void *priv, int force) IWI_LOCK(sc); goto fail; } - if (bus_dmamem_alloc(sc->fw_dmat, &sc->fw_virtaddr, 0, + if (must_realloc && + bus_dmamem_alloc(sc->fw_dmat, &sc->fw_virtaddr, 0, &sc->fw_map) != 0) { device_printf(sc->sc_dev, "could not allocate firmware DMA memory\n"); IWI_LOCK(sc); goto fail2; } - if (bus_dmamap_load(sc->fw_dmat, sc->fw_map, sc->fw_virtaddr, + if (must_realloc && + bus_dmamap_load(sc->fw_dmat, sc->fw_map, sc->fw_virtaddr, sc->fw_dma_size, iwi_dma_map_addr, &sc->fw_physaddr, 0) != 0) { device_printf(sc->sc_dev, "could not load firmware DMA map\n"); IWI_LOCK(sc); @@ -3185,11 +3207,6 @@ iwi_init_locked(void *priv, int force) } sc->flags |= IWI_FLAG_FW_INITED; - bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fw_dmat, sc->fw_map); - bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); - bus_dma_tag_destroy(sc->fw_dmat); - if (iwi_config(sc) != 0) { device_printf(sc->sc_dev, "device configuration failed\n"); goto fail; @@ -3218,6 +3235,7 @@ fail4: bus_dmamap_sync(sc->fw_dmat, sc-> fail3: bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); fail2: bus_dma_tag_destroy(sc->fw_dmat); fail: ifp->if_flags &= ~IFF_UP; + sc->fw_virtaddr = 0; sc->flags &= ~IWI_FLAG_FW_LOADING; iwi_stop(sc); iwi_put_firmware(sc); --vni90+aGYgRvsTuO--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070216174317.GZ64768>