It was discovered that named could crash due to a segmentation fault when jemalloc was in use and memory allocation failed. This was not intended to happen as jemalloc's "xmalloc" option was set to "true" in the "malloc_conf" configuration variable. However, that variable was only set after jemalloc was already done with parsing it, which effectively caused setting that variable to have no effect. While investigating this issue, it was also discovered that enabling the "xmalloc" option makes jemalloc use a slow processing path, decreasing its performance by about 25%. [1] Additionally, further testing (carried out after fixing the way "malloc_conf" was set) revealed that the non-default configuration options do not have any measurable effect on either authoritative or recursive DNS server performance. Replace code setting various jemalloc options to non-default values with assertion checks of mallocx()/rallocx() return values. [1] https://github.com/jemalloc/jemalloc/pull/523
134 lines
2.3 KiB
C
134 lines
2.3 KiB
C
/*
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
* information regarding copyright ownership.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#if !defined(HAVE_JEMALLOC)
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <isc/util.h>
|
|
|
|
const char *malloc_conf = NULL;
|
|
|
|
#if defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE)
|
|
|
|
#include <stdlib.h>
|
|
|
|
static inline void *
|
|
mallocx(size_t size, int flags) {
|
|
UNUSED(flags);
|
|
|
|
return (malloc(size));
|
|
}
|
|
|
|
static inline void
|
|
sdallocx(void *ptr, size_t size, int flags) {
|
|
UNUSED(size);
|
|
UNUSED(flags);
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
static inline void *
|
|
rallocx(void *ptr, size_t size, int flags) {
|
|
UNUSED(flags);
|
|
REQUIRE(size != 0);
|
|
|
|
return (realloc(ptr, size));
|
|
}
|
|
|
|
#ifdef HAVE_MALLOC_SIZE
|
|
|
|
#include <malloc/malloc.h>
|
|
|
|
static inline size_t
|
|
sallocx(void *ptr, int flags) {
|
|
UNUSED(flags);
|
|
|
|
return (malloc_size(ptr));
|
|
}
|
|
|
|
#elif HAVE_MALLOC_USABLE_SIZE
|
|
|
|
#include <malloc.h>
|
|
|
|
static inline size_t
|
|
sallocx(void *ptr, int flags) {
|
|
UNUSED(flags);
|
|
|
|
return (malloc_usable_size(ptr));
|
|
}
|
|
|
|
#endif /* HAVE_MALLOC_SIZE */
|
|
|
|
#else /* defined(HAVE_MALLOC_SIZE) || defined (HAVE_MALLOC_USABLE_SIZE) */
|
|
|
|
#include <stdlib.h>
|
|
|
|
typedef union {
|
|
size_t size;
|
|
max_align_t __alignment;
|
|
} size_info;
|
|
|
|
static inline void *
|
|
mallocx(size_t size, int flags) {
|
|
void *ptr = NULL;
|
|
|
|
UNUSED(flags);
|
|
|
|
size_info *si = malloc(size + sizeof(*si));
|
|
INSIST(si != NULL);
|
|
|
|
si->size = size;
|
|
ptr = &si[1];
|
|
|
|
return (ptr);
|
|
}
|
|
|
|
static inline void
|
|
sdallocx(void *ptr, size_t size, int flags) {
|
|
size_info *si = &(((size_info *)ptr)[-1]);
|
|
|
|
UNUSED(size);
|
|
UNUSED(flags);
|
|
|
|
free(si);
|
|
}
|
|
|
|
static inline size_t
|
|
sallocx(void *ptr, int flags) {
|
|
size_info *si = &(((size_info *)ptr)[-1]);
|
|
|
|
UNUSED(flags);
|
|
|
|
return (si[0].size);
|
|
}
|
|
|
|
static inline void *
|
|
rallocx(void *ptr, size_t size, int flags) {
|
|
size_info *si = &(((size_info *)ptr)[-1]);
|
|
|
|
UNUSED(flags);
|
|
|
|
si = realloc(si, size + sizeof(*si));
|
|
INSIST(si != NULL);
|
|
|
|
si->size = size;
|
|
ptr = &si[1];
|
|
|
|
return (ptr);
|
|
}
|
|
|
|
#endif /* defined(HAVE_MALLOC_SIZE) || defined (HAVE_MALLOC_USABLE_SIZE) */
|
|
|
|
#endif /* !defined(HAVE_JEMALLOC) */
|