Date: Thu, 13 Mar 2014 09:38:51 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Konstantin Belousov <kib@freebsd.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r263080 - in head/sys: dev/cpuctl dev/hwpmc kern Message-ID: <20140313081336.C5739@besplex.bde.org> In-Reply-To: <201403121025.s2CAPQRl017239@svn.freebsd.org> References: <201403121025.s2CAPQRl017239@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 12 Mar 2014, Konstantin Belousov wrote: > Log: > Use correct types for sizeof() in the calculations for the malloc(9) sizes [1]. > While there, remove unneeded checks for failed allocations with M_WAITOK flag. > > Submitted by: Conrad Meyer <cemeyer@uw.edu> [1] > MFC after: 1 week Nice cleanups. > Modified: head/sys/kern/kern_linker.c > ============================================================================== > --- head/sys/kern/kern_linker.c Wed Mar 12 10:23:51 2014 (r263079) > +++ head/sys/kern/kern_linker.c Wed Mar 12 10:25:26 2014 (r263080) > @@ -725,14 +725,11 @@ linker_file_add_dependency(linker_file_t > linker_file_t *newdeps; > > sx_assert(&kld_sx, SA_XLOCKED); > - newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *), > - M_LINKER, M_WAITOK | M_ZERO); > - if (newdeps == NULL) > - return (ENOMEM); > + newdeps = malloc((file->ndeps + 1) * sizeof(*newdeps), M_LINKER, > + M_WAITOK | M_ZERO); > Still has a style bug: extra blank line. KNF disallows all optional blank lines (indent -sob), even ones to separate unrelated statements, and this one separates related statements. > if (file->deps) { > - bcopy(file->deps, newdeps, > - file->ndeps * sizeof(linker_file_t *)); > + bcopy(file->deps, newdeps, file->ndeps * sizeof(*newdeps)); > free(file->deps, M_LINKER); > } > file->deps = newdeps; I don't agree with having realloc() or reallocf() in the kernel, but since realloc() is there it is a style bug to not use it in the above. The code using realloc() seems to be: file->deps = realloc(file->deps, (file->ndeps + 1) * sizeof(*newdeps), M_LINKER, M_WAITOK | M_ZERO); This is 5 more lines shorter. Perhaps 8 lines shorter after removing the temporary variable. reallocf() is especially not needed in the kernel, since most allocations are M_WAITOK so they can't fail. It is used a whole 5 files in the whole kernel, and most of these uses are wrong. - in drm_realloc() in dev/drm/drmP.h. This function is badly named. It does reallocf(), not realloc(). This function is so bogus that it is never used, at least in dev/drm. The nearby drm_alloc(), which does malloc(), is used a lot. Instead, 4 places use plain realloc(). Plain realloc() suffices for these cases, since all uses are with M_WAITOK. But all these uses are followed by garbage error handling that is even more laborious than in the garbage removed in this commit, despite having the usual bug from not using reallocf() (leak the old allocation on failure). - 3 times in dev/pci/pci.c. All these uses are bogus, since the allocations are M_WAITOK so they can't fail, and if they could fail the error handling given by reallocf() would be wrong. - 2 times in in uhso_alloc_tty(). All these uses are bogus, as in pci.c, except they are followed by bogus checks that the M_WAITOK reallocf() doesn't fail, so perhaps the error handling for the impossible case where it fails is correct. - in drm_realloc() in dev/drm2/drmP.h. drm is cloned for some reason, so its bugs are cloned too. All the other bugs described above are cloned too, starting with not actually using this function. - twice in dev/drm2/drm_edid2.c. All these uses are bogus, as in pci.c, plus they have the internal layering violation of not using drm2's own realloc interface. These bugs are not due to the cloning -- the original never uses reallocf(), and the dead code for the error handling is not present in the new code. - in atm_getvccs(). This use is actually correct. Summary: after removing the garbage, reallocf() is used a whole once in the kernel. Not counting the above, or boot or utilities, realloc() is used in a whole 22 files in the kernel, with an average of not much more than 1 use per file. Many of the uses are in low quality code that does things like casting the result of realloc() or trying to implement the usual bug from not using reallocf() but not managing to do so since by using M_WAITOK (these tend to be followed by verbose dead code for handling allocation failure but not the leak; hopefully callers of malloc() are not so stupid about M_WAITOK). This leaves about 10 correct useful uses of realloc(). It saves a whole statement to use realloc() instead of malloc() + bcopy() for a M_WAITOK malloc(). I prefer the separate statement, and don't really like the M_ZERO flag instead of a separate bzero() either. Kernel realloc() is non-smart and never extends the original allocation, but just does malloc() + bcopy() internally. Since it is so rarely needed in the kernel, it is OK for callers to know this and not use it just to benefit from it ecoming smarter. reallocf() gives much larger simplifications in callers for the single non-M_WAITOK caller. Further cleanups might give as many a 2 correct non-M_WAITOK callers. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140313081336.C5739>