Re: vnet(4) memory leak

2016-03-20 Thread Mark Kettenis
> Date: Sat, 19 Mar 2016 14:15:47 +0100
> From: Stefan Sperling 
> 
> A sparc64 machine of mine crashes every few weeks because the kernel
> runs out of memory.
> 
> The crash usually happens in a malloc call in the vnet(4) ioctl code path.
> I have a cronjob which downs/up vnet interfaces in case they get stuck in
> OACTIVE (another bug which, AFAIK, is not solved yet). So this machine runs
> vnet's ioctl code path every now and then.
> 
> Yesterday it crashed again. The machine was still running a snap from Feb 2.
> kettenis@ has fixed one memory leak in vnet since. I believe I may have
> found another leak, which is addresssed by the diff below.
> 
> Is this diff correct? My machine is now running with it.

ok kettenis@

> Index: vnet.c
> ===
> RCS file: /cvs/src/sys/arch/sparc64/dev/vnet.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 vnet.c
> --- vnet.c26 Feb 2016 13:41:51 -  1.54
> +++ vnet.c19 Mar 2016 10:42:06 -
> @@ -169,6 +169,7 @@ struct vnet_softc {
>   struct ldc_map  *sc_lm;
>   struct vnet_dring *sc_vd;
>   struct vnet_soft_desc *sc_vsd;
> +#define VNET_NUM_SOFT_DESC   128
>  
>   size_t  sc_peer_desc_size;
>   struct ldc_cookie sc_peer_dring_cookie;
> @@ -1399,10 +1400,10 @@ vnet_init(struct ifnet *ifp)
>   return;
>   }
>  
> - sc->sc_vd = vnet_dring_alloc(sc->sc_dmatag, 128);
> + sc->sc_vd = vnet_dring_alloc(sc->sc_dmatag, VNET_NUM_SOFT_DESC);
>   if (sc->sc_vd == NULL)
>   return;
> - sc->sc_vsd = malloc(128 * sizeof(*sc->sc_vsd), M_DEVBUF,
> + sc->sc_vsd = malloc(VNET_NUM_SOFT_DESC * sizeof(*sc->sc_vsd), M_DEVBUF,
>   M_NOWAIT|M_ZERO);
>   if (sc->sc_vsd == NULL)
>   return;
> @@ -1453,6 +1454,8 @@ vnet_stop(struct ifnet *ifp)
>   lc->lc_state = 0;
>   lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN;
>   vnet_ldc_reset(lc);
> +
> + free(sc->sc_vsd, M_DEVBUF, VNET_NUM_SOFT_DESC * sizeof(*sc->sc_vsd));
>  
>   vnet_dring_free(sc->sc_dmatag, sc->sc_vd);
>  
> 
> 



vnet(4) memory leak

2016-03-19 Thread Stefan Sperling
A sparc64 machine of mine crashes every few weeks because the kernel
runs out of memory.

The crash usually happens in a malloc call in the vnet(4) ioctl code path.
I have a cronjob which downs/up vnet interfaces in case they get stuck in
OACTIVE (another bug which, AFAIK, is not solved yet). So this machine runs
vnet's ioctl code path every now and then.

Yesterday it crashed again. The machine was still running a snap from Feb 2.
kettenis@ has fixed one memory leak in vnet since. I believe I may have
found another leak, which is addresssed by the diff below.

Is this diff correct? My machine is now running with it.

Index: vnet.c
===
RCS file: /cvs/src/sys/arch/sparc64/dev/vnet.c,v
retrieving revision 1.54
diff -u -p -r1.54 vnet.c
--- vnet.c  26 Feb 2016 13:41:51 -  1.54
+++ vnet.c  19 Mar 2016 10:42:06 -
@@ -169,6 +169,7 @@ struct vnet_softc {
struct ldc_map  *sc_lm;
struct vnet_dring *sc_vd;
struct vnet_soft_desc *sc_vsd;
+#define VNET_NUM_SOFT_DESC 128
 
size_t  sc_peer_desc_size;
struct ldc_cookie sc_peer_dring_cookie;
@@ -1399,10 +1400,10 @@ vnet_init(struct ifnet *ifp)
return;
}
 
-   sc->sc_vd = vnet_dring_alloc(sc->sc_dmatag, 128);
+   sc->sc_vd = vnet_dring_alloc(sc->sc_dmatag, VNET_NUM_SOFT_DESC);
if (sc->sc_vd == NULL)
return;
-   sc->sc_vsd = malloc(128 * sizeof(*sc->sc_vsd), M_DEVBUF,
+   sc->sc_vsd = malloc(VNET_NUM_SOFT_DESC * sizeof(*sc->sc_vsd), M_DEVBUF,
M_NOWAIT|M_ZERO);
if (sc->sc_vsd == NULL)
return;
@@ -1453,6 +1454,8 @@ vnet_stop(struct ifnet *ifp)
lc->lc_state = 0;
lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN;
vnet_ldc_reset(lc);
+
+   free(sc->sc_vsd, M_DEVBUF, VNET_NUM_SOFT_DESC * sizeof(*sc->sc_vsd));
 
vnet_dring_free(sc->sc_dmatag, sc->sc_vd);