Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Feb 2007 00:23:55 +0100
From:      Olivier Houchard <cognet@ci0.org>
To:        "V.Chukharev" <chukharev@mail.ru>
Cc:        freebsd-net@freebsd.org, Jeremie Le Hen <jeremie@le-hen.org>
Subject:   Re: iwi leaks memory?
Message-ID:  <20070216232355.GA83548@ci0.org>
In-Reply-To: <op.tnu03mar0g54sc@localhost>
References:  <op.tns7i21z0g54sc@localhost> <20070216174317.GZ64768@obiwan.tataz.chchile.org> <op.tnu03mar0g54sc@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help

--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Feb 16, 2007 at 11:10:24PM +0200, V.Chukharev wrote:
> On Fri, 16 Feb 2007 19:43:17 +0200, Jeremie Le Hen <jeremie@le-hen.org> wrote:
> 
> > Hi,
> >
> > 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.
> 
> I cannot apply the patch ;-(
> It seems it's for CURRENT, and I run STABLE.
> 

Hi,

I regenerated the patch against STABLE.
Beware however, I didn't test it, only compile-test it, as I have no such
hardware.

Cheers,

Olivier

--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="if_iwi.stable.diff"

Index: dev/iwi/if_iwi.c
===================================================================
RCS file: /cognet/ncvs/src/sys/dev/iwi/if_iwi.c,v
retrieving revision 1.8.2.12
diff -u -p -r1.8.2.12 if_iwi.c
--- dev/iwi/if_iwi.c	23 Jan 2007 22:17:48 -0000	1.8.2.12
+++ dev/iwi/if_iwi.c	16 Feb 2007 22:53:39 -0000
@@ -511,6 +511,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);
 
@@ -3079,6 +3085,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)
@@ -3100,14 +3107,26 @@ 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) {
+		must_realloc = 1;
 		sc->fw_dma_size = sc->fw_uc.size;
-
-	if (bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT,
+	}
+	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 (must_realloc &&
+	    bus_dma_tag_create(NULL, 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) {
 		device_printf(sc->sc_dev,
@@ -3115,14 +3134,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);
@@ -3178,11 +3199,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;
@@ -3211,6 +3227,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);

--r5Pyd7+fXNt84Ff3--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070216232355.GA83548>