From 63ad7bd43cbe77c9af63049a7bf93b51742e890f Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 26 Jul 2015 21:45:51 -0700 Subject: [PATCH] boot - Fix minor memory leak, statistics * open() calls devopen() which installs a generic malloc'd device wrapper in f->f_devdata. However, some devices will replace this with their own descriptor. Add F_DEVDESC to indicate when f->f_devdata contains this generic object, free and clear the generic object when replacing f_devdata in particular devices. This fixes a minor memory leak of 192 bytes on open()s made by the boot code when booting from e.g. PXE. * Fix incorrect MallocCount statistics. calloc() and realloc() were improperly incrementing the global, even though the malloc() call they both make also increments it. * Remove the unused F_NODEV flag. This flag is never set, collapse the related code. --- lib/libstand/close.c | 2 +- lib/libstand/open.c | 5 ++--- lib/libstand/stand.h | 3 ++- lib/libstand/zalloc_malloc.c | 6 ------ sys/boot/common/dev_net.c | 2 +- sys/boot/common/devopen.c | 26 ++++++++++++++++++++++---- sys/boot/pc32/libi386/pxe.c | 3 ++- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/libstand/close.c b/lib/libstand/close.c index 67b1535114..31eb104c62 100644 --- a/lib/libstand/close.c +++ b/lib/libstand/close.c @@ -80,7 +80,7 @@ close(int fd) } if (!(f->f_flags & F_RAW) && f->f_ops) err1 = (f->f_ops->fo_close)(f); - if (!(f->f_flags & F_NODEV) && f->f_dev) + if (f->f_dev) err2 = (f->f_dev->dv_close)(f); if (f->f_devdata != NULL) devclose(f); diff --git a/lib/libstand/open.c b/lib/libstand/open.c index 516078eeff..0b0d92f4cb 100644 --- a/lib/libstand/open.c +++ b/lib/libstand/open.c @@ -105,8 +105,7 @@ open(const char *fname, int mode) f->f_fsdata = NULL; file = NULL; error = devopen(f, fname, &file); - if (error || - (((f->f_flags & F_NODEV) == 0) && f->f_dev == NULL)) + if (error || f->f_dev == NULL) goto err; /* see if we opened a raw device; otherwise, 'file' is the file name. */ @@ -129,7 +128,7 @@ open(const char *fname, int mode) } error = besterror; - if ((f->f_flags & F_NODEV) == 0) + if (f->f_dev) f->f_dev->dv_close(f); if (error) devclose(f); diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h index 183da8a4e6..a08d92d3d3 100644 --- a/lib/libstand/stand.h +++ b/lib/libstand/stand.h @@ -174,7 +174,7 @@ extern struct open_file files[]; #define F_READ 0x0001 /* file opened for reading */ #define F_WRITE 0x0002 /* file opened for writing */ #define F_RAW 0x0004 /* raw device open - no file system */ -#define F_NODEV 0x0008 /* network open - no device */ +#define F_DEVDESC 0x0008 /* generic devdesc, else specific */ #define isascii(c) (((c) & ~0x7F) == 0) @@ -379,6 +379,7 @@ extern int ischar(void); extern void putchar(int); extern int devopen(struct open_file *, const char *, const char **); extern int devclose(struct open_file *); +extern void devreplace(struct open_file *, void *devdata); extern void panic(const char *, ...) __dead2 __printflike(1, 2); extern struct fs_ops *file_system[]; extern struct devsw *devsw[]; diff --git a/lib/libstand/zalloc_malloc.c b/lib/libstand/zalloc_malloc.c index b3f1ac9ec6..7b01e20585 100644 --- a/lib/libstand/zalloc_malloc.c +++ b/lib/libstand/zalloc_malloc.c @@ -124,10 +124,6 @@ calloc(size_t n1, size_t n2) if ((res = malloc(bytes)) != NULL) { bzero(res, bytes); -#ifdef DMALLOCDEBUG - if (++MallocCount > MallocMax) - MallocMax = MallocCount; -#endif } return(res); } @@ -157,8 +153,6 @@ realloc(void *ptr, size_t size) free(ptr); } else { #ifdef DMALLOCDEBUG - if (++MallocCount > MallocMax) - MallocMax = MallocCount; #ifdef EXITSTATS if (DidAtExit == 0) { DidAtExit = 1; diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c index 3fbef501e9..1b30a9a44c 100644 --- a/sys/boot/common/dev_net.c +++ b/sys/boot/common/dev_net.c @@ -146,7 +146,7 @@ net_open(struct open_file *f, ...) netdev_opens++; } netdev_opens++; - f->f_devdata = &netdev_sock; + devreplace(f, &netdev_sock); return (error); } diff --git a/sys/boot/common/devopen.c b/sys/boot/common/devopen.c index 8b26fbfef2..dd6b3229a1 100644 --- a/sys/boot/common/devopen.c +++ b/sys/boot/common/devopen.c @@ -32,6 +32,10 @@ #include "bootstrap.h" +/* + * Install f_dev and f_devinfo. Some devices uses the generic + * devdesc, others will replace it with their own and clear F_DEVDESC. + */ int devopen(struct open_file *f, const char *fname, const char **file) { @@ -40,12 +44,13 @@ devopen(struct open_file *f, const char *fname, const char **file) if ((result = archsw.arch_getdev((void *)&dev, fname, file)) == 0) { /* get the device */ /* point to device-specific data so that device open can use it */ + f->f_flags |= F_DEVDESC; f->f_devdata = dev; if ((result = dev->d_dev->dv_open(f, dev)) == 0) { /* try to open it */ /* reference the devsw entry from the open_file structure */ f->f_dev = dev->d_dev; } else { - free(dev); /* release the device descriptor */ + devclose(f); } } return(result); @@ -54,9 +59,22 @@ devopen(struct open_file *f, const char *fname, const char **file) int devclose(struct open_file *f) { - if (f->f_devdata != NULL) { - free(f->f_devdata); - f->f_devdata = NULL; + if (f->f_flags & F_DEVDESC) { + if (f->f_devdata != NULL) { + free(f->f_devdata); + f->f_devdata = NULL; + } + f->f_flags &= ~F_DEVDESC; } return(0); } + +void +devreplace(struct open_file *f, void *devdata) +{ + if (f->f_flags & F_DEVDESC) { + free(f->f_devdata); + f->f_flags &= ~F_DEVDESC; + } + f->f_devdata = devdata; +} diff --git a/sys/boot/pc32/libi386/pxe.c b/sys/boot/pc32/libi386/pxe.c index d75d68beb3..eacf688b74 100644 --- a/sys/boot/pc32/libi386/pxe.c +++ b/sys/boot/pc32/libi386/pxe.c @@ -321,7 +321,8 @@ pxe_open(struct open_file *f, ...) } } pxe_opens++; - f->f_devdata = &pxe_sock; + devreplace(f, &pxe_sock); + return (error); } -- 2.41.0