From patchwork Thu Jul 2 15:19:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 138340 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0028C4BA7994 for ; Thu, 2 Jul 2026 15:19:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0028C4BA7994 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dPjz6H3o X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id A194F4BA2E14 for ; Thu, 2 Jul 2026 15:19:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A194F4BA2E14 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A194F4BA2E14 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783005553; cv=none; b=IAnP2BjB8iVrMG9ri3BwgS1Qg+6CGkFtICo+7kDZSUOs5cX7HAd9FmMhT8x3GcSpkv672s2D2J2RORi3/USBeX5rKUG6lugnjyST5fqY1ssRCiWC4GheFC4T79WFKsFk5PhgLHtYUNdG6FeVI1SogyYnbyS1ID3KwxIA4zgDFR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1783005553; c=relaxed/simple; bh=1xlIWmAfnu9TLXJD8NtHW4z0Z9yZ8kfyn18vzaaOVnI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=snyDrUXMcDoh21TADL5CmzOchri+p8YRL7cmmpS28G5p8bUj5iDfIez6qPdgmzW2rNb30W5OkKh7vsz0K6zNDJdfiVvU1TQMWfW2NUhFLy4U1s/4qrGkJuxcUOnJuQF+bbMGXKiZeJ90B2zTPsSwJhnrBz46UTMQPKwiDlRgPH4= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dPjz6H3o DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A194F4BA2E14 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1783005553; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=V+TSgonMs+I7kZ4yj3qvdG8tQ/MgMh32+f1JU/F9RFg=; b=dPjz6H3oFTQIG6R5I3DavAxi4txFDhPoflHPjY/XFC/c/xcbBi2Q22V4pD/16FfFuDujZ1 T7y+Msakp+8a15OzoTnuiGeuqESY8SDeNCJD85HlhxeklZXEEHsOzFmY/l2ZKs5/SX8eAC jBtN2Fre9oWtivhOcGgqNd4dQQjuxgM= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-631-XOaYFmr1MjiPQRbb9lWEOw-1; Thu, 02 Jul 2026 11:19:12 -0400 X-MC-Unique: XOaYFmr1MjiPQRbb9lWEOw-1 X-Mimecast-MFC-AGG-ID: XOaYFmr1MjiPQRbb9lWEOw_1783005551 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0B0B518C1079; Thu, 2 Jul 2026 15:19:11 +0000 (UTC) Received: from greed.delorie.com (unknown [10.22.89.250]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BF9DF1800605; Thu, 2 Jul 2026 15:19:10 +0000 (UTC) Received: from greed.delorie.com.redhat.com (localhost [127.0.0.1]) by greed.delorie.com (8.16.1/8.16.1) with ESMTP id 662FJ9pP043933; Thu, 2 Jul 2026 11:19:09 -0400 From: DJ Delorie To: Andreas Schwab Cc: libc-alpha@sourceware.org Subject: [PATCH v2 1/1] Add system-wide tunables: implement overridability Date: Thu, 02 Jul 2026 11:19:09 -0400 Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 1KcqwZZe1LGp9GdwCXhElyoLd4UnUAU-UPOed054nTM_1783005551 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Andreas Schwab writes: > That proves to be pretty fragile. How about this? Add system-wide tunables: implement overridability Implement the overridability/nonoverridability flags for tunables. Reviewed-by: Adhemerval Zanella diff --git a/elf/Makefile b/elf/Makefile index 789c504da9..7b00a0b931 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -347,7 +347,11 @@ tests-static += \ tst-tls9-static \ # tests-static -tst-tunconf1-TUNABLES-only = glibc.malloc.tcache_count=5 +tst-tunconf1-TUNABLES-only = \ + glibc.malloc.tcache_count=5 \ + :glibc.malloc.perturb=41 \ + :glibc.malloc.mmap_threshold=10002 \ + :glibc.malloc.trim_threshold=10002 static-dlopen-environment = \ LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h index f421c01c26..3506eee512 100644 --- a/elf/dl-tunable-types.h +++ b/elf/dl-tunable-types.h @@ -65,6 +65,8 @@ struct _tunable tunable_val_t val; /* The value. */ bool initialized; /* Flag to indicate that the tunable is initialized. */ + bool locked; /* If set, modifications are not + allowed. */ /* Compatibility elements. */ const char env_alias[TUNABLE_ALIAS_MAX]; /* The compatibility environment variable name. */ diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c index 197d940d38..d19c2358c1 100644 --- a/elf/dl-tunables.c +++ b/elf/dl-tunables.c @@ -72,6 +72,9 @@ do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp, { tunable_num_t val, min, max; + if (cur->locked) + return; + switch (cur->type.type_code) { case TUNABLE_TYPE_STRING: @@ -409,6 +412,12 @@ __tunables_init (char **envp, char **argv) goto skip_due_to_filter; } + /* If the tunable is set here, any previously set + overridability flag is discarded. We need to reset the + overridability flag here so we can change the tunable, + and may set it later if this tunable also locks it. */ + tunable_list[tid].locked = false; + /* See if the parsed type matches the desired type. */ if (tunable_list[tid].type.type_code == TUNABLE_TYPE_STRING) { @@ -435,6 +444,12 @@ __tunables_init (char **envp, char **argv) } } + /* The overriability flag only applies to tunables + which aren't filtered out. */ + if ((tec->flags & TUNCONF_FLAG_OVERRIDABLE) + == TUNCONF_OVERRIDE_DENY) + tunable_list[tid].locked = true; + skip_due_to_filter:; } } diff --git a/elf/tst-tunconf1.c b/elf/tst-tunconf1.c index c95a7cb8ba..74f596d913 100644 --- a/elf/tst-tunconf1.c +++ b/elf/tst-tunconf1.c @@ -26,10 +26,30 @@ do_test (void) { size_t tcache_count = TUNABLE_GET_FULL (glibc, malloc, tcache_count, size_t, NULL); size_t tcache_max = TUNABLE_GET_FULL (glibc, malloc, tcache_max, size_t, NULL); + size_t perturb = TUNABLE_GET_FULL (glibc, malloc, perturb, size_t, NULL); + size_t mmap_threshold = TUNABLE_GET_FULL (glibc, malloc, mmap_threshold, size_t, NULL); + size_t trim_threshold = TUNABLE_GET_FULL (glibc, malloc, trim_threshold, size_t, NULL); + printf("tcache count is %ld (should be 5, from env)\n", (long)tcache_count); TEST_COMPARE ((long)tcache_count, 5); printf("tcache max is %ld (should be 4, from /etc)\n", (long)tcache_max); TEST_COMPARE ((long)tcache_max, 4); + + /* This is set by the environment but blocked by the config. */ + printf("perturb is %ld (should be 42, from /etc)\n", + (long)perturb); + TEST_COMPARE ((long)perturb, 42); + + /* This is blocked by the general config, enabled by filter, set in env. */ + printf("mmap_threshold is %ld (should be 10002, from env)\n", + (long)mmap_threshold); + TEST_COMPARE ((long)mmap_threshold, 10002); + + /* This is allowed by the general config, blocked by filter, set in env. */ + printf("trim_threshold is %ld (should be 10001, from filter)\n", + (long)trim_threshold); + TEST_COMPARE ((long)trim_threshold, 10001); + return 0; } diff --git a/elf/tst-tunconf1.root/etc/tunables.conf b/elf/tst-tunconf1.root/etc/tunables.conf index f373a67902..f708a8fce4 100644 --- a/elf/tst-tunconf1.root/etc/tunables.conf +++ b/elf/tst-tunconf1.root/etc/tunables.conf @@ -8,7 +8,15 @@ $glibc.test_unsecure=1 # These are checked inside the test case glibc.malloc.tcache_max=6 $glibc.malloc.tcache_count=3 + +-glibc.malloc.perturb=42 +-glibc.malloc.mmap_threshold=10000 +overridable glibc.malloc.trim_threshold=10000 + [proc:/bin/ls] glibc.malloc.tcache_max=7 + [proc:tst-tunconf1] glibc.malloc.tcache_max=4 ++glibc.malloc.mmap_threshold=10001 +nonoverridable glibc.malloc.trim_threshold=10001 diff --git a/elf/tunconf.c b/elf/tunconf.c index a5ca755abd..c27b50b1de 100644 --- a/elf/tunconf.c +++ b/elf/tunconf.c @@ -194,34 +194,40 @@ add_tunable (char *line, const char *filename, int lineno) /* Parse modifiers. */ while (*line) { - if (strncmp (line, "overridable ", 13) == 0) + int prefix_len; + +#define TUN_PREFIX(s) \ + prefix_len = sizeof(s) - 1, \ + strncmp (line, s " ", prefix_len + 1) == 0 + + if (TUN_PREFIX("overridable")) { top = TOP_ALLOW; /* The line++ below skips the space. */ - line += 12; + line += prefix_len; } - else if (strncmp (line, "nonoverridable ", 16) == 0) + else if (TUN_PREFIX ("nonoverridable")) { top = TOP_DENY; - line += 15; + line += prefix_len; } - else if (strncmp (line, "onlysecure ", 11) == 0) + else if (TUN_PREFIX ("onlysecure")) { exclude_nonsecure = 1; exclude_secure = 0; - line += 10; + line += prefix_len; } - else if (strncmp (line, "nonsecure ", 10) == 0) + else if (TUN_PREFIX ("nonsecure")) { exclude_secure = 1; exclude_nonsecure = 0; - line += 9; + line += prefix_len; } - else if (strncmp (line, "anysecure ", 10) == 0) + else if (TUN_PREFIX ("anysecure")) { exclude_secure = 0; exclude_nonsecure = 0; - line += 9; + line += prefix_len; } else switch (*line) { diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk index 5d34075c16..7c832303db 100644 --- a/scripts/gen-tunables.awk +++ b/scripts/gen-tunables.awk @@ -169,7 +169,7 @@ END { n = indices[2]; m = indices[3]; printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m) - printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, %s},\n", + printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, false, %s},\n", types[t,n,m], minvals[t,n,m], maxvals[t,n,m], default_val[t,n,m], default_val[t,n,m], env_alias[t,n,m]); }