test/review: plug mii leakage

From: Bjoern A. Zeeb (bzeeb-lists_at_lists.zabbadoz.net)
Date: 03/27/05

  • Next message: Bjoern A. Zeeb: "Re: test/review: plug mii leakage"
    Date: Sun, 27 Mar 2005 19:54:25 +0000 (UTC)
    To: FreeBSD current mailing list <current@freebsd.org>
    
    

    Hi,

    could you please test following patch:
     http://sources.zabbadoz.net/freebsd/patchset/mii-20050326-plug-leaks.diff

    Any feedback welcome.

    Thanks in advance.

    -- 
    Greetings
    Bjoern A. Zeeb				bzeeb at Zabbadoz dot NeT
    Index: sys/dev/mii/mii.c
    ===================================================================
    RCS file: /local/mirror/FreeBSD/r/ncvs/src/sys/dev/mii/mii.c,v
    retrieving revision 1.25
    diff -u -p -r1.25 mii.c
    --- sys/dev/mii/mii.c	16 Feb 2005 05:56:39 -0000	1.25
    +++ sys/dev/mii/mii.c	26 Mar 2005 19:02:41 -0000
    @@ -115,7 +115,7 @@ miibus_probe(device_t dev)
     	struct mii_attach_args	ma, *args;
     	struct mii_data		*mii;
     	device_t		child = NULL, parent;
    -	int			bmsr, capmask = 0xFFFFFFFF;
    +	int			bmsr, capmask = 0xFFFFFFFF, count = 0;
     	mii = device_get_softc(dev);
     	parent = device_get_parent(dev);
    @@ -149,12 +149,24 @@ miibus_probe(device_t dev)
     		args = malloc(sizeof(struct mii_attach_args),
     		    M_DEVBUF, M_NOWAIT);
    +		if (args == NULL) {
    +			device_printf(dev, "%s: memory allocation failure, "
    +			    "phyno %d", __func__, ma.mii_phyno);
    +			continue;
    +		}
     		bcopy((char *)&ma, (char *)args, sizeof(ma));
     		child = device_add_child(dev, NULL, -1);
    +		if (child == NULL) {
    +			free(args, M_DEVBUF);
    +			device_printf(dev, "%s: device_add_child failed",
    +			    __func__);
    +			continue;
    +		}
     		device_set_ivars(child, args);
    +		count++;
     	}
    -	if (child == NULL)
    +	if (count == 0)
     		return(ENXIO);
     	device_set_desc(dev, "MII bus");
    @@ -176,20 +188,40 @@ miibus_attach(device_t dev)
     	 */
     	mii->mii_ifp = device_get_softc(device_get_parent(dev));
     	v = device_get_ivars(dev);
    +	if (v == NULL)
    +		return (ENXIO);	/* XXX */
     	ifmedia_upd = v[0];
     	ifmedia_sts = v[1];
     	ifmedia_init(&mii->mii_media, IFM_IMASK, ifmedia_upd, ifmedia_sts);
    -	bus_generic_attach(dev);
    -	return(0);
    +	return(bus_generic_attach(dev));
     }
     int
     miibus_detach(device_t dev)
     {
     	struct mii_data		*mii;
    +	device_t		*children, *childp;
    +	int			error, j, childcount = 0;
    +	void			*v;
    +
    +	if (device_get_state(dev) != DS_ATTACHED)
    +		return (EBUSY);
    -	bus_generic_detach(dev);
    +	device_get_children(dev, &children, &childcount);
    +	for (j = 0, childp = children; j < childcount; j++, childp++) {
    +		/*
    +		 * Free ivars but not before device_detach.
    +		 * miibus_child_* fuinctions still use them unchecked.
    +		 */
    +		v = device_get_ivars(*childp);
    +		if ((error = device_detach(*childp)) != 0)
    +			return (error);
    +		if (v != NULL) {
    +			device_set_ivars(*childp, NULL);
    +			free(v, M_DEVBUF);
    +		}
    +	}
     	mii = device_get_softc(dev);
     	ifmedia_removeall(&mii->mii_media);
     	mii->mii_ifp = NULL;
    @@ -300,12 +332,16 @@ mii_phy_probe(device_t dev, device_t *ch
     	int			bmsr, i;
     	v = malloc(sizeof(vm_offset_t) * 2, M_DEVBUF, M_NOWAIT);
    -	if (v == 0) {
    +	if (v == NULL) {
     		return (ENOMEM);
     	}
     	v[0] = ifmedia_upd;
     	v[1] = ifmedia_sts;
     	*child = device_add_child(dev, "miibus", -1);
    +	if (*child == NULL) {
    +		free(v, M_DEVBUF);
    +		return (ENXIO);
    +	}
     	device_set_ivars(*child, v);
     	for (i = 0; i < MII_NPHY; i++) {
    @@ -319,14 +355,23 @@ mii_phy_probe(device_t dev, device_t *ch
     	}
     	if (i == MII_NPHY) {
    +		device_set_ivars(*child, NULL);
    +		free(v, M_DEVBUF);
     		device_delete_child(dev, *child);
     		*child = NULL;
     		return(ENXIO);
     	}
    -	bus_generic_attach(dev);
    +	i = bus_generic_attach(dev);
    -	return(0);
    +	/* Free ivars as they are no longer needed. */
    +	v = device_get_ivars(*child);
    +	if (v != NULL) {
    +		device_set_ivars(*child, NULL);
    +		free(v, M_DEVBUF);
    +	}
    +
    +	return(i);
     }
     /*
    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
    

  • Next message: Bjoern A. Zeeb: "Re: test/review: plug mii leakage"

    Relevant Pages

    • Re: mem leak in mii ? (fwd)
      ... third and last call for review and comments. ... mii doesn't ssem to be very error corrective and reporting; as others currently also seem to be debugging problems with undetectable PHYs I added some error handling in those places that I touched anyway. ... args = malloc, ... device_delete_child(dev, ...
      (freebsd-current)
    • Re: mem leak in mii ? (fwd)
      ... third and last call for review and comments. ... mii doesn't ssem to be very error corrective and reporting; as others currently also seem to be debugging problems with undetectable PHYs I added some error handling in those places that I touched anyway. ... args = malloc, ... device_delete_child(dev, ...
      (freebsd-net)
    • test/review: plug mii leakage
      ... parent = device_get_parent; ... args = malloc, ... device_set_desc(dev, "MII bus"); ... device_delete_child(dev, *child); ...
      (freebsd-current)
    • Re: Call functions of superclass
      ... def send_super(meth, *args, &blk) ... "Hello from Parent!" ... "Hello from Child!" ...
      (comp.lang.ruby)