From patchwork Wed Sep 11 21:04:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 1161283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-105153-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="Herpf3Yn"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gkyiQTGc"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46TDwD2mWwz9s7T for ; Thu, 12 Sep 2019 07:06:20 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; q=dns; s=default; b=N1sXCTOo /isaCC3wsQb3g2h8Q5v1gIOuUVRNIEermmXFTTdgjCpNVaNwVL+O4v3rVI+onoo4 zBaFsgIvPNIBd7AXi59OkDeKrKrn6FOc+vhOMEfY6r43btvTpRm6LmN8GFOTbEPN bGXD7HCSYbQ4mTN9YyzEEnWgzKt2zlbZrTA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; s=default; bh=J3mQsq0rd2R+1F uWrFlBxs8SwmI=; b=Herpf3YnkONurIbJaqXZXn65k0JsiP3dbqpBTiUsPYUyS7 kcSkgX9m+QyWx9zzAIdscNmqZ0EOAl/fEVMSTjWDfZdjYgw9bF+ZIK0G4FrzpEcb +4U+e6cN0NMjWmSVxleETryv+AQwvLs6f1HuWIOrnkOTx/d1E4wM/UEwnhVzg= Received: (qmail 95423 invoked by alias); 11 Sep 2019 21:05:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 95334 invoked by uid 89); 11 Sep 2019 21:05:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-pl1-f195.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=blijySI/PV9XEpImKFu0VgH348Ri4IIx0xG+3wTR9pw=; b=gkyiQTGcKeQvGPq30plpbuf4Uiotyz2qfexkxBf4Y60pxGS5GT53jOv1+oyodiHQkG bK//Qwb4FINFtZNz/moCf77XBNicvl0el2BZqWqv/RUEiWopf5hOg7xJdzT2cjHH3wIV K8oIRBtA/OLdiKFey3NQgHM4k4iI8fv9aw3mZNZzlGQKAA4ii+W1xPhc9Du/Bqvjq2JQ r1cl2/MRbQuxnb1n+1hCP9yMCdX7dpBFerjXxVlY3FPZQ9X7lGnV91hzL9oN4E3Iw1Ge iYAuoSaVhaZ20CTZunWfAVFhTOO8eAIRCpUbxOxpbS/nGxcRlEVeY/Gr9lhhzkvLJCtl HD0g== From: Isaku Yamahata To: libc-alpha@sourceware.org Cc: isaku.yamahata@intel.com, Isaku Yamahata Subject: [RFC PATCH 07/11] malloc: make arena size configurable on startup Date: Wed, 11 Sep 2019 14:04:05 -0700 Message-Id: <0438c6b3f81ee46abef884de161dbb4b624655db.1568219400.git.isaku.yamahata@gmail.com> In-Reply-To: References: In-Reply-To: References: This patch is mainly to show the idea and to get feedback. Probably there might be a better implementation. This patch introduce tunable to makes heap allocator friendly to LibOS. It allows a way for the LibOS to adjust allocation size. LibOS may have its own virtual address space layout (duto software or hardware e.g. SGX) and as a result, it may have the limited heap. If heap allocator tries to allocate too large memory, ENOMEM on startup. Signed-off-by: Isaku Yamahata --- elf/dl-tunables.list | 5 +++++ malloc/arena.c | 17 +++++++---------- malloc/malloc.c | 25 +++++++++++++++++++++++++ malloc/malloc.h | 1 + 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 525c3767b5..31aaecd8bd 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -64,6 +64,11 @@ glibc { env_alias: MALLOC_MMAP_MAX_ security_level: SXID_IGNORE } + heap_max { + type: INT_32 + env_alias: MALLOC_HEAP_MAX_ + security_level: SXID_IGNORE + } arena_max { type: SIZE_T env_alias: MALLOC_ARENA_MAX diff --git a/malloc/arena.c b/malloc/arena.c index a32eb403ec..acd03c53eb 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -26,14 +26,7 @@ /* Compile-time constants. */ -#define HEAP_MIN_SIZE (32 * 1024) -#ifndef HEAP_MAX_SIZE -# ifdef DEFAULT_MMAP_THRESHOLD_MAX -# define HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX) -# else -# define HEAP_MAX_SIZE (1024 * 1024) /* must be a power of two */ -# endif -#endif +#define HEAP_MAX_SIZE (mp_.heap_max) /* HEAP_MIN_SIZE and HEAP_MAX_SIZE limit the size of mmap()ed heaps that are dynamically created for multi-threaded programs. The @@ -226,6 +219,7 @@ TUNABLE_CALLBACK (__name) (tunable_val_t *valp) \ TUNABLE_CALLBACK_FNDECL (set_mmap_threshold, size_t) TUNABLE_CALLBACK_FNDECL (set_mmaps_max, int32_t) +TUNABLE_CALLBACK_FNDECL (set_heap_max, int32_t) TUNABLE_CALLBACK_FNDECL (set_top_pad, size_t) TUNABLE_CALLBACK_FNDECL (set_perturb_byte, int32_t) TUNABLE_CALLBACK_FNDECL (set_trim_threshold, size_t) @@ -316,6 +310,7 @@ ptmalloc_init (void) TUNABLE_GET (mmap_threshold, size_t, TUNABLE_CALLBACK (set_mmap_threshold)); TUNABLE_GET (trim_threshold, size_t, TUNABLE_CALLBACK (set_trim_threshold)); TUNABLE_GET (mmap_max, int32_t, TUNABLE_CALLBACK (set_mmaps_max)); + TUNABLE_GET (heap_max, int32_t, TUNABLE_CALLBACK (set_heap_max)); TUNABLE_GET (arena_max, size_t, TUNABLE_CALLBACK (set_arena_max)); TUNABLE_GET (arena_test, size_t, TUNABLE_CALLBACK (set_arena_test)); # if USE_TCACHE @@ -365,6 +360,8 @@ ptmalloc_init (void) __libc_mallopt (M_MMAP_MAX, atoi (&envline[10])); else if (memcmp (envline, "ARENA_MAX", 9) == 0) __libc_mallopt (M_ARENA_MAX, atoi (&envline[10])); + else if (memcmp (envline, "HEAP_MAX_", 9) == 0) + __libc_mallopt (M_HEAP_MAX, atoi (&envline[10])); } break; case 10: @@ -472,7 +469,7 @@ new_heap (size_t size, size_t top_pad) mapping (on Linux, this is the case for all non-writable mappings anyway). */ p2 = MAP_FAILED; - if (aligned_heap_area) + if (aligned_heap_area && !mp_.heap_max_specified) { p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE); @@ -493,7 +490,7 @@ new_heap (size_t size, size_t top_pad) ul = p2 - p1; if (ul) __munmap (p1, ul); - else + else if (!mp_.heap_max_specified) aligned_heap_area = p2 + HEAP_MAX_SIZE; __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); } diff --git a/malloc/malloc.c b/malloc/malloc.c index fe973770a6..f776bb2452 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -981,6 +981,13 @@ int __posix_memalign(void **, size_t, size_t); #define DEFAULT_MMAP_MAX (65536) #endif +#ifdef HEAP_MAX_SIZE +# define DEFAULT_HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THREASHOLD_MAX) +#else +# define DEFAULT_HEAP_MAX_SIZE (1024 * 1024) /* must be power of two */ +#endif +#define HEAP_MIN_SIZE (32 * 1024) + #include #ifndef RETURN_ADDRESS @@ -1713,6 +1720,8 @@ struct malloc_par it manually, at which point we need to disable any dynamic behavior. */ int no_dyn_threshold; + int heap_max; + int heap_max_specified; /* Statistics */ INTERNAL_SIZE_T mmapped_mem; @@ -1766,6 +1775,8 @@ static struct malloc_par mp_ = .top_pad = DEFAULT_TOP_PAD, .n_mmaps_max = DEFAULT_MMAP_MAX, .mmap_threshold = DEFAULT_MMAP_THRESHOLD, + .heap_max = DEFAULT_HEAP_MAX_SIZE, + .heap_max_specified = 0, .trim_threshold = DEFAULT_TRIM_THRESHOLD, #define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8)) .arena_test = NARENAS_FROM_NCORES (1) @@ -5052,6 +5063,16 @@ do_set_mmaps_max (int32_t value) return 1; } +static __always_inline int +do_set_heap_max (int32_t value) +{ + LIBC_PROBE (memory_mallopt_heap_max, 3, value, mp_.heap_max, + mp_.no_dyn_threshold); + mp_.heap_max = value; + mp_.heap_max_specified = 1; + return 1; +} + static __always_inline int do_set_mallopt_check (int32_t value) { @@ -5166,6 +5187,10 @@ __libc_mallopt (int param_number, int value) do_set_mmaps_max (value); break; + case M_HEAP_MAX: + do_set_heap_max (value); + break; + case M_CHECK_ACTION: do_set_mallopt_check (value); break; diff --git a/malloc/malloc.h b/malloc/malloc.h index 70d8282bdc..30b93281aa 100644 --- a/malloc/malloc.h +++ b/malloc/malloc.h @@ -124,6 +124,7 @@ extern struct mallinfo mallinfo (void) __THROW; #define M_PERTURB -6 #define M_ARENA_TEST -7 #define M_ARENA_MAX -8 +#define M_HEAP_MAX -9 /* General SVID/XPG interface to tunable parameters. */ extern int mallopt (int __param, int __val) __THROW;