Date: Sun, 27 Mar 2005 19:54:25 +0000 (UTC) From: "Bjoern A. Zeeb" <bzeeb-lists@lists.zabbadoz.net> To: FreeBSD current mailing list <current@freebsd.org> Cc: FreeBSD net mailing list <net@freebsd.org> Subject: test/review: plug mii leakage Message-ID: <Pine.BSF.4.53.0503271949030.562@e0-0.zab2.int.zabbadoz.net>
next in thread | raw e-mail | index | archive | help
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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.53.0503271949030.562>