From nobody Wed Feb 11 10:38:05 2026 Received: from out-183.mta1.migadu.com (out-183.mta1.migadu.com [95.215.58.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E1B3389DF4 for ; Tue, 13 Jan 2026 17:40:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326061; cv=none; b=Mnj4XJlayBpHLJVJ/yUeqeJ1AXY/ssfPQf/8ehJoLZMMfvnlF06aJjy0DhpGXvSsyyMTI2A0763bGjA3PRKxtLV7ucstFjMJBjpcRkFMt2FaszQdvTLCFINkDkROh9YbgEMvHMPQ10NRu21a9/VA/rX6DQHEHnzRWQO6MftGJbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326061; c=relaxed/simple; bh=h+CWyFH79b+ck649UTadWNeq1frfKSYLW3i0Y1ktqcY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FYh/Nf3fgBpC1Bhc6xUFzNt1IIXOKGcsKyAFGX8p/Kj7oE65uEP7z+tnQgruMf4GMkMQWn2l/qG48I8WjdRsJX00tdvWeu+EWHdlRVGqTQuP0rrixIg/RfrLsyH080Dte3NNS7FdACApnPhx1w8THhKpc3LXGGy+WmyuGv6B8VE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=GGXAyyCj; arc=none smtp.client-ip=95.215.58.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="GGXAyyCj" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1768326057; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tGPLKt/qbYWtt+2IkGYIoT8dXR/EXHgixA9v9y5+YHU=; b=GGXAyyCj635jxIejGsiwqr/Iq71TsLfTm4/40TIeDDRHyWBgwWvYb4KJUXmIxNV4EN/jsN /REiTRenvzmP98Ld7p2on4YxXMehIp/Nyrqvl+697R8Gvzn+R55xR4vaEFlrTgOpuVzIBY 9tz5z9dljhuMfc/JS88GZ6AYIbkUFWM= From: wen.yang@linux.dev To: Joel Granados Cc: linux-kernel@vger.kernel.org, Wen Yang Subject: [RFC PATCH 1/4] sysctl: add SYSCTL_ENTRY/SYSCTL_RANGE_ENTRY helpers for ctl_table init Date: Wed, 14 Jan 2026 01:40:30 +0800 Message-Id: <09f6437ba1aeb067be4d295ec79f2d51f5355ce0.1768324215.git.wen.yang@linux.dev> In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Wen Yang Introduce SYSCTL_ENTRY() and SYSCTL_RANGE_ENTRY() (built on __SYSCTL_ENTRY(= )) to consolidate common struct ctl_table initializers in one place. This is a preparatory refactor in support of future tree-wide sysctl cleanups by making the how to build a ctl_table entry logic uniform. Also add SYSCTL_NULL for explicitly passing a NULL .data pointer through the new macros, and convert a few in-tree users (kernel/sysctl.c) to validate the new helpers. No functional change intended. Selftest were also made: [19:31:40] Starting KUnit Kernel (1/1)... [19:31:40] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Running tests with: $ .kunit/linux kunit.filter_glob=3Dsysctl_test kunit.enable=3D1 mem=3D1G co= nsole=3Dtty kunit_shutdown=3Dhalt [19:31:40] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D sysctl_test (10= subtests) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [19:31:40] [PASSED] sysctl_test_api_dointvec_null_tbl_data [19:31:40] [PASSED] sysctl_test_api_dointvec_table_maxlen_unset [19:31:40] [PASSED] sysctl_test_api_dointvec_table_len_is_zero [19:31:40] [PASSED] sysctl_test_api_dointvec_table_read_but_position_set [19:31:40] [PASSED] sysctl_test_dointvec_read_happy_single_positive [19:31:40] [PASSED] sysctl_test_dointvec_read_happy_single_negative [19:31:40] [PASSED] sysctl_test_dointvec_write_happy_single_positive [19:31:40] [PASSED] sysctl_test_dointvec_write_happy_single_negative [19:31:40] [PASSED] sysctl_test_api_dointvec_write_single_less_int_min [19:31:40] [PASSED] sysctl_test_api_dointvec_write_single_greater_int_max [19:31:40] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [PASSE= D] sysctl_test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [19:31:40] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [19:31:40] Testing complete. Ran 10 tests: passed: 10 [19:31:40] Elapsed time: 26.755s total, 0.002s configuring, 26.632s buildin= g, 0.102s running Suggested-by: Joel Granados Link: https://lore.kernel.org/all/7mevcgca7xsd5gckrap22byjinhrgqnelu4y7hzo2= r5t2cq7w4@nyaa42khwqez/#t Signed-off-by: Wen Yang --- include/linux/sysctl.h | 18 ++++++ kernel/sysctl-test.c | 131 ++++++++++------------------------------- kernel/sysctl.c | 43 ++------------ 3 files changed, 56 insertions(+), 136 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 2886fbceb5d6..683422bc3e7f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -53,6 +53,7 @@ struct ctl_dir; #define SYSCTL_MAXOLDUID ((void *)&sysctl_vals[10]) #define SYSCTL_NEG_ONE ((void *)&sysctl_vals[11]) =20 +#define SYSCTL_NULL ((void *)NULL) extern const int sysctl_vals[]; =20 #define SYSCTL_LONG_ZERO ((void *)&sysctl_long_vals[0]) @@ -175,6 +176,23 @@ struct ctl_table { void *extra2; } __randomize_layout; =20 +#define __SYSCTL_ENTRY(NAME, DATA, TYPE, MODE, HANDLER, SMIN, SMAX)\ + { \ + .procname =3D NAME, \ + .data =3D DATA, \ + .maxlen =3D sizeof(TYPE), \ + .mode =3D MODE, \ + .proc_handler =3D HANDLER, \ + .extra1 =3D SMIN, \ + .extra2 =3D SMAX, \ + } + +#define SYSCTL_ENTRY(NAME, DATA, TYPE, MODE) \ + __SYSCTL_ENTRY(NAME, DATA, TYPE, MODE, proc_do##TYPE##vec, NULL, NULL) + +#define SYSCTL_RANGE_ENTRY(NAME, DATA, TYPE, MODE, SMIN, SMAX) \ + __SYSCTL_ENTRY(NAME, DATA, TYPE, MODE, proc_do##TYPE##vec_minmax, SMIN, S= MAX) + struct ctl_node { struct rb_node node; struct ctl_table_header *header; diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c index 92f94ea28957..7fb0e7f1e62f 100644 --- a/kernel/sysctl-test.c +++ b/kernel/sysctl-test.c @@ -15,20 +15,14 @@ */ static void sysctl_test_api_dointvec_null_tbl_data(struct kunit *test) { - struct ctl_table null_data_table =3D { - .procname =3D "foo", - /* - * Here we are testing that proc_dointvec behaves correctly when - * we give it a NULL .data field. Normally this would point to a - * piece of memory where the value would be stored. - */ - .data =3D NULL, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + /* + * Here we are testing that proc_dointvec behaves correctly when + * we give it a NULL .data field. Normally this would point to a + * piece of memory where the value would be stored. + */ + struct ctl_table null_data_table =3D SYSCTL_RANGE_ENTRY("foo", \ + SYSCTL_NULL, int, 0644, SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); + /* * proc_dointvec expects a buffer in user space, so we allocate one. We * also need to cast it to __user so sparse doesn't get mad. @@ -66,19 +60,14 @@ static void sysctl_test_api_dointvec_null_tbl_data(stru= ct kunit *test) static void sysctl_test_api_dointvec_table_maxlen_unset(struct kunit *test) { int data =3D 0; - struct ctl_table data_maxlen_unset_table =3D { - .procname =3D "foo", - .data =3D &data, - /* - * So .data is no longer NULL, but we tell proc_dointvec its - * length is 0, so it still shouldn't try to use it. - */ - .maxlen =3D 0, - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + + /* + * So .data is no longer NULL, but we tell proc_dointvec its + * length is 0, so it still shouldn't try to use it. + */ + struct ctl_table data_maxlen_unset_table =3D SYSCTL_RANGE_ENTRY("foo", \ + &data, int, 0644, SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); + data_maxlen_unset_table.maxlen =3D 0; void __user *buffer =3D (void __user *)kunit_kzalloc(test, sizeof(int), GFP_USER); size_t len; @@ -113,15 +102,8 @@ static void sysctl_test_api_dointvec_table_len_is_zero= (struct kunit *test) { int data =3D 0; /* Good table. */ - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644,\ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); void __user *buffer =3D (void __user *)kunit_kzalloc(test, sizeof(int), GFP_USER); /* @@ -147,15 +129,8 @@ static void sysctl_test_api_dointvec_table_read_but_po= sition_set( { int data =3D 0; /* Good table. */ - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644,\ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); void __user *buffer =3D (void __user *)kunit_kzalloc(test, sizeof(int), GFP_USER); /* @@ -182,15 +157,8 @@ static void sysctl_test_dointvec_read_happy_single_pos= itive(struct kunit *test) { int data =3D 0; /* Good table. */ - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644, \ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); size_t len =3D 4; loff_t pos =3D 0; char *buffer =3D kunit_kzalloc(test, len, GFP_USER); @@ -213,15 +181,8 @@ static void sysctl_test_dointvec_read_happy_single_neg= ative(struct kunit *test) { int data =3D 0; /* Good table. */ - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644, \ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); size_t len =3D 5; loff_t pos =3D 0; char *buffer =3D kunit_kzalloc(test, len, GFP_USER); @@ -242,15 +203,8 @@ static void sysctl_test_dointvec_write_happy_single_po= sitive(struct kunit *test) { int data =3D 0; /* Good table. */ - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644, \ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); char input[] =3D "9"; size_t len =3D sizeof(input) - 1; loff_t pos =3D 0; @@ -272,15 +226,8 @@ static void sysctl_test_dointvec_write_happy_single_po= sitive(struct kunit *test) static void sysctl_test_dointvec_write_happy_single_negative(struct kunit = *test) { int data =3D 0; - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644, \ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); char input[] =3D "-9"; size_t len =3D sizeof(input) - 1; loff_t pos =3D 0; @@ -304,15 +251,8 @@ static void sysctl_test_api_dointvec_write_single_less= _int_min( struct kunit *test) { int data =3D 0; - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644,\ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); size_t max_len =3D 32, len =3D max_len; loff_t pos =3D 0; char *buffer =3D kunit_kzalloc(test, max_len, GFP_USER); @@ -342,15 +282,8 @@ static void sysctl_test_api_dointvec_write_single_grea= ter_int_max( struct kunit *test) { int data =3D 0; - struct ctl_table table =3D { - .procname =3D "foo", - .data =3D &data, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - .extra1 =3D SYSCTL_ZERO, - .extra2 =3D SYSCTL_ONE_HUNDRED, - }; + struct ctl_table table =3D SYSCTL_RANGE_ENTRY("foo", &data, int, 0644,\ + SYSCTL_ZERO, SYSCTL_ONE_HUNDRED); size_t max_len =3D 32, len =3D max_len; loff_t pos =3D 0; char *buffer =3D kunit_kzalloc(test, max_len, GFP_USER); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9d3a666ffde1..2e769550b268 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1373,47 +1373,16 @@ int proc_do_static_key(const struct ctl_table *tabl= e, int dir, =20 static const struct ctl_table sysctl_subsys_table[] =3D { #ifdef CONFIG_PROC_SYSCTL - { - .procname =3D "sysctl_writes_strict", - .data =3D &sysctl_writes_strict, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec_minmax, - .extra1 =3D SYSCTL_NEG_ONE, - .extra2 =3D SYSCTL_ONE, - }, + SYSCTL_RANGE_ENTRY("sysctl_writes_strict", &sysctl_writes_strict, int, \ + 0644, SYSCTL_NEG_ONE, SYSCTL_ONE), #endif - { - .procname =3D "ngroups_max", - .data =3D (void *)&ngroups_max, - .maxlen =3D sizeof (int), - .mode =3D 0444, - .proc_handler =3D proc_dointvec, - }, - { - .procname =3D "cap_last_cap", - .data =3D (void *)&cap_last_cap, - .maxlen =3D sizeof(int), - .mode =3D 0444, - .proc_handler =3D proc_dointvec, - }, + SYSCTL_ENTRY("ngroups_max", (void *)&ngroups_max, int, 0444), + SYSCTL_ENTRY("cap_last_cap", (void *)&cap_last_cap, int, 0444), #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW - { - .procname =3D "unaligned-trap", - .data =3D &unaligned_enabled, - .maxlen =3D sizeof(int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - }, + SYSCTL_ENTRY("unaligned-trap", &unaligned_enabled, int, 0644), #endif #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN - { - .procname =3D "ignore-unaligned-usertrap", - .data =3D &no_unaligned_warning, - .maxlen =3D sizeof (int), - .mode =3D 0644, - .proc_handler =3D proc_dointvec, - }, + SYSCTL_ENTRY("ignore-unaligned-usertrap", &no_unaligned_warning, int, 064= 4), #endif }; =20 --=20 2.25.1 From nobody Wed Feb 11 10:38:05 2026 Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8CD33921C0 for ; Tue, 13 Jan 2026 17:41:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326063; cv=none; b=Dep3mmJJ4dIUeVMlE/ohGugCvDGwUQVbTawqIGyAxcGaXOHnUTuvvAVrAhQs9GyzsDooMBRhP4loTuyUrdntUMwll/x80G5fc8mI2CbW666xHV8739v6cnk9ptrPFj4QDvex/5EuthivigDBjegSiUNA/JcewQMQb0eMHQjcxag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326063; c=relaxed/simple; bh=9r5bUSwFXgwDwXbYoF5UNPZxb7XdgMlrcpWBnWHrgqM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hWI6r+mpqxC/Tj0jcGk9hOgIrmRKj6wto3mhlxJN5T+AVt2czNowlMLq3bmYcx0L2Bpsm49MWyawEc9ljC2lUym6KW61wUNfUMmcDNTbzD1YgB9xoEpCVgDMSKlmoatkXQd4cDra/odOEFwviG9ouCeTyWg+6jcB/67DIm23fE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=c9hU5k9j; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="c9hU5k9j" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1768326060; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oe3qKWHteBxzE4yfo0khrmbu7CoLF1rmgSJExh6X4EU=; b=c9hU5k9jFPimzJuXoygWhHgDcrxYxydjhuCTZRVya7n8D1OXoKoz60yInBBBnynzEz6E3u bErK90lUX7VeMvswqFgmbgE5vOw2vztpvgoH+BfIN4CPjTOAH/FGwR/cVrDa5E01zuvjy2 zmDLUFznEiBeV5wVdSOI4fsAgqGG5F8= From: wen.yang@linux.dev To: Joel Granados Cc: linux-kernel@vger.kernel.org, Wen Yang Subject: [RFC PATCH 2/4] sysctl: add helper functions to extract table->extra1/extra2 Date: Wed, 14 Jan 2026 01:40:31 +0800 Message-Id: <9ebbce66874c884f7112476bfd4132510d06854c.1768324215.git.wen.yang@linux.dev> In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Wen Yang Add some sysctl helper functions to avoid direct access to table->extra1/extra2. No functional change intended. Selftest were also made: [14:52:13] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D sysctl_test (10= subtests) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:52:13] [PASSED] sysctl_test_api_dointvec_null_tbl_data [14:52:13] [PASSED] sysctl_test_api_dointvec_table_maxlen_unset [14:52:13] [PASSED] sysctl_test_api_dointvec_table_len_is_zero [14:52:13] [PASSED] sysctl_test_api_dointvec_table_read_but_position_set [14:52:13] [PASSED] sysctl_test_dointvec_read_happy_single_positive [14:52:13] [PASSED] sysctl_test_dointvec_read_happy_single_negative [14:52:13] [PASSED] sysctl_test_dointvec_write_happy_single_positive [14:52:13] [PASSED] sysctl_test_dointvec_write_happy_single_negative [14:52:13] [PASSED] sysctl_test_api_dointvec_write_single_less_int_min [14:52:13] [PASSED] sysctl_test_api_dointvec_write_single_greater_int_max [14:52:13] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [PASSE= D] sysctl_test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:52:13] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [14:52:13] Testing complete. Ran 10 tests: passed: 10 Suggested-by: Joel Granados Signed-off-by: Wen Yang --- include/linux/sysctl.h | 10 ++++++++++ kernel/sysctl.c | 14 ++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 683422bc3e7f..9690740885ab 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -164,6 +164,16 @@ static inline void *proc_sys_poll_event(struct ctl_tab= le_poll *poll) #define DEFINE_CTL_TABLE_POLL(name) \ struct ctl_table_poll name =3D __CTL_TABLE_POLL_INITIALIZER(name) =20 +#define SYSCTL_IN_RANGE(tbl, val, type) \ + ((tbl) && \ + (!(tbl)->extra1 || (*(type *)(tbl)->extra1 <=3D (type)(val))) && \ + (!(tbl)->extra2 || (*(type *)(tbl)->extra2 >=3D (type)(val)))) + +#define SYSCTL_IN_RANGE_INT(tbl, val) SYSCTL_IN_RANGE(tbl, val, = int) +#define SYSCTL_IN_RANGE_LONG(tbl, val) SYSCTL_IN_RANGE(tbl, val, = long) +#define SYSCTL_IN_RANGE_UINT(tbl, val) SYSCTL_IN_RANGE(tbl, val, = unsigned int) +#define SYSCTL_IN_RANGE_ULONG(tbl, val) SYSCTL_IN_RANGE(tbl, val, = unsigned long) + /* A sysctl table is an array of struct ctl_table: */ struct ctl_table { const char *procname; /* Text ID for /proc/sys */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 2e769550b268..990e692f626b 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -428,10 +428,7 @@ int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, ret =3D user_to_kern(u_ptr, &tmp_k); if (ret) return ret; - if ((tbl->extra1 && - *(uint *)tbl->extra1 > tmp_k) || - (tbl->extra2 && - *(uint *)tbl->extra2 < tmp_k)) + if (!SYSCTL_IN_RANGE_UINT(tbl, tmp_k)) return -ERANGE; WRITE_ONCE(*k_ptr, tmp_k); } else @@ -531,8 +528,7 @@ int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr,= int dir, ret =3D user_to_kern(negp, u_ptr, &tmp_k); if (ret) return ret; - if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || - (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) + if (!SYSCTL_IN_RANGE_INT(tbl, tmp_k)) return -EINVAL; WRITE_ONCE(*k_ptr, tmp_k); } else @@ -969,7 +965,7 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int dir, unsigned long convmul, unsigned long convdiv) { - unsigned long *i, *min, *max; + unsigned long *i ; int vleft, first =3D 1, err =3D 0; size_t left; char *p; @@ -981,8 +977,6 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int dir, } =20 i =3D table->data; - min =3D table->extra1; - max =3D table->extra2; vleft =3D table->maxlen / sizeof(unsigned long); left =3D *lenp; =20 @@ -1014,7 +1008,7 @@ static int do_proc_doulongvec_minmax(const struct ctl= _table *table, int dir, } =20 val =3D convmul * val / convdiv; - if ((min && val < *min) || (max && val > *max)) { + if (!SYSCTL_IN_RANGE_ULONG(table, val)) { err =3D -EINVAL; break; } --=20 2.25.1 From nobody Wed Feb 11 10:38:05 2026 Received: from out-177.mta1.migadu.com (out-177.mta1.migadu.com [95.215.58.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 623C038F92E for ; Tue, 13 Jan 2026 17:41:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326068; cv=none; b=aSiTA7CQX8gfdmrKu5z25vniiXd+SBFsgefDw83f8Bcazgk9zXMuWSPIjwaDLjljwDKzyi5cO0bVllAz82JVK8ysBDigx18wgEdaB2UvJKDHIMNe12cWyfr3AO3JwlnwdwjkWsMW11gvZgPuYPWtuauQbjzTeRTqRubZ7BXjMeU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326068; c=relaxed/simple; bh=JOSu76aRahi8Zi6Mjw5Audnjqe4gRaoSwvfOazMhRP4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nkHOvWlDOa7WvPHj7/u0CwJnI9wR5u2h+GwtOeI7+d7STKkD6i5ZVac39OvqcaO9tsNxmoiNOjFPS6oZIXJdQRdyctVov5BXISudL/4ETWVxnePW0aCN4OilTlEstluluvmfvbdP3zm9mRFlVT+5Ic0cgEOgKNV9eniIPHYEO5Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=d2REPc8S; arc=none smtp.client-ip=95.215.58.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="d2REPc8S" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1768326064; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ifay54OqERVPeY4XKiP7/HvcLuGvqlaESPUepzyC/eo=; b=d2REPc8S7PTw4yPDtAL5EXuIssE3f2zPU4LXh5N0gsnzvq3N/g+0DHkzVFpjFmqGFV8yyB PS0ezv2vbJyYri7zhPC89esY57Lfe6cnBqrVw7QvkjLwXKkH4FhYs4CYOGlcOou383vmUY 2Ii1+kF7ENgTFAXBtkxBZm5whXu7uC4= From: wen.yang@linux.dev To: Joel Granados Cc: linux-kernel@vger.kernel.org, Wen Yang Subject: [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry Date: Wed, 14 Jan 2026 01:40:32 +0800 Message-Id: <907e4f14cedb2bfb2810dec255b930d59b821dc2.1768324215.git.wen.yang@linux.dev> In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Wen Yang Eric points out: "by turning .extra1 and .extra2 into longs instead of keeping them as pointers and needing constants to be pointed at somewhere .. The only people I can see who find a significant benefit by consolidating all of the constants into one place are people who know how to stomp kernel memory." This patch supports encoding values directly in table entries. This patch also adds a kunit test case: [15:09:24] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D sysctl_test (11= subtests) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [15:09:24] [PASSED] sysctl_test_api_dointvec_null_tbl_data [15:09:24] [PASSED] sysctl_test_api_dointvec_table_maxlen_unset [15:09:24] [PASSED] sysctl_test_api_dointvec_table_len_is_zero [15:09:24] [PASSED] sysctl_test_api_dointvec_table_read_but_position_set [15:09:24] [PASSED] sysctl_test_dointvec_read_happy_single_positive [15:09:24] [PASSED] sysctl_test_dointvec_read_happy_single_negative [15:09:24] [PASSED] sysctl_test_dointvec_write_happy_single_positive [15:09:24] [PASSED] sysctl_test_dointvec_write_happy_single_negative [15:09:24] [PASSED] sysctl_test_api_dointvec_write_single_less_int_min [15:09:24] [PASSED] sysctl_test_api_dointvec_write_single_greater_int_max [15:09:24] [PASSED] sysctl_test_api_dointvec_write_range_check [15:09:24] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [PASSE= D] sysctl_test =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [15:09:24] =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [15:09:24] Testing complete. Ran 11 tests: passed: 11 Suggested-by: Joel Granados Signed-off-by: Wen Yang --- include/linux/sysctl.h | 60 +++++++++++++++-- kernel/sysctl-test.c | 142 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 7 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 9690740885ab..19be4f3f700b 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -165,9 +165,14 @@ static inline void *proc_sys_poll_event(struct ctl_tab= le_poll *poll) struct ctl_table_poll name =3D __CTL_TABLE_POLL_INITIALIZER(name) =20 #define SYSCTL_IN_RANGE(tbl, val, type) \ - ((tbl) && \ - (!(tbl)->extra1 || (*(type *)(tbl)->extra1 <=3D (type)(val))) && \ - (!(tbl)->extra2 || (*(type *)(tbl)->extra2 >=3D (type)(val)))) + ((tbl) && ({ \ + type v =3D (type)(val); \ + !((tbl)->min_is_value ? (tbl)->min > (unsigned long)v \ + : (tbl)->extra1 && *(type*)(tbl)->extra1 > v) \ + && !((tbl)->max_is_value ? (tbl)->max < (unsigned long)v \ + : (tbl)->extra2 && *(type*)(tbl)->extra2 < v); \ + }) \ + ) =20 #define SYSCTL_IN_RANGE_INT(tbl, val) SYSCTL_IN_RANGE(tbl, val, = int) #define SYSCTL_IN_RANGE_LONG(tbl, val) SYSCTL_IN_RANGE(tbl, val, = long) @@ -180,12 +185,52 @@ struct ctl_table { void *data; int maxlen; umode_t mode; + + /** + * Range bound type flags + * - min_is_value: 1 =3D min field is direct value, 0 =3D extra1 is point= er + * - max_is_value: 1 =3D max field is direct value, 0 =3D extra2 is point= er + */ + union { + struct { + unsigned char min_is_value : 1; /* bit 0: min type */ + unsigned char max_is_value : 1; /* bit 1: max type */ + unsigned char reserved : 6; /* bits 2-7: reserved */ + }; + unsigned char flags; + }; + proc_handler *proc_handler; /* Callback for text formatting */ struct ctl_table_poll *poll; - void *extra1; - void *extra2; + + /* Range bounds: either pointers or direct values */ + union { + struct { + void *extra1; /* min as pointer */ + void *extra2; /* max as pointer */ + }; + struct { + unsigned long min; /* min as direct value */ + unsigned long max; /* max as direct value */ + }; + }; } __randomize_layout; =20 +/* Pointer detection using _Generic */ +#define IS_PTR(x) _Generic((x), \ + char*:1, short*:1, int*:1, long*:1, \ + unsigned char*:1, unsigned short*:1, unsigned int*:1, unsigned lon= g*:1, \ + const char*:1, const int*:1, const long*:1, \ + void*:1, const void*:1, default:0) + +/* Auto-detect range flags: 0=3Dptr_ptr, 1=3Dval_ptr, 2=3Dptr_val, 3=3Dval= _val */ +#define RANGE_FLAGS(smin, smax) ((!IS_PTR(smin)) | ((!IS_PTR(smax)) << 1)) + +/* Type-specific checks */ +#define CHECK_INT(tbl, val) CHECK(tbl, val, int) +#define CHECK_UINT(tbl, val) CHECK(tbl, val, unsigned int) +#define CHECK_LONG(tbl, val) CHECK(tbl, val, long) + #define __SYSCTL_ENTRY(NAME, DATA, TYPE, MODE, HANDLER, SMIN, SMAX)\ { \ .procname =3D NAME, \ @@ -193,8 +238,9 @@ struct ctl_table { .maxlen =3D sizeof(TYPE), \ .mode =3D MODE, \ .proc_handler =3D HANDLER, \ - .extra1 =3D SMIN, \ - .extra2 =3D SMAX, \ + .flags =3D RANGE_FLAGS(SMIN, SMAX), \ + .min =3D (unsigned long)(SMIN), \ + .max =3D (unsigned long)(SMAX), \ } =20 #define SYSCTL_ENTRY(NAME, DATA, TYPE, MODE) \ diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c index 7fb0e7f1e62f..b55bc84e56c2 100644 --- a/kernel/sysctl-test.c +++ b/kernel/sysctl-test.c @@ -300,6 +300,147 @@ static void sysctl_test_api_dointvec_write_single_gre= ater_int_max( KUNIT_EXPECT_EQ(test, 0, *((int *)table.data)); } =20 +/* + * Test that writing values within the specified range succeeds, + * and ensures out-of-range writes are correctly rejected. + */ +static void sysctl_test_api_dointvec_write_range_check(struct kunit *test) +{ + int data =3D 0; + size_t len; + loff_t pos; + char *buffer; + char __user *user_buffer; + + /* Prepare bound variables for pointer modes */ + int min_bounds[] =3D {10, 0, 15, 0}; + int max_bounds[] =3D {90, 75, 0, 0}; + + /* Initialize test tables using macro */ + struct ctl_table test_cases[] =3D { + /* PTR_PTR: both pointers */ + SYSCTL_RANGE_ENTRY("ptr_ptr", &data, int, 0644, + &min_bounds[0], &max_bounds[0]), + /* VAL_PTR: min is value, max is pointer */ + SYSCTL_RANGE_ENTRY("val_ptr", &data, int, 0644, + 25, &max_bounds[1]), + /* PTR_VAL: min is pointer, max is value */ + SYSCTL_RANGE_ENTRY("ptr_val", &data, int, 0644, + &min_bounds[2], 85), + /* VAL_VAL: both values */ + SYSCTL_RANGE_ENTRY("val_val", &data, int, 0644, + 20, 80), + }; + + /* Test parameters for each mode */ + const struct { + int min, max; + const char *valid; + const char *below_min; + const char *above_max; + } test_params[] =3D { + {10, 90, "50", "5", "95"}, /* PTR_PTR */ + {25, 75, "50", "20", "80"}, /* VAL_PTR */ + {15, 85, "50", "10", "90"}, /* PTR_VAL */ + {20, 80, "50", "15", "85"}, /* VAL_VAL */ + }; + + for (int i =3D 0; i < 4; i++) { + struct ctl_table *table =3D &test_cases[i]; + const typeof(test_params[0]) *param =3D &test_params[i]; + + /* Verify flags auto-detection */ + KUNIT_EXPECT_EQ(test, table->flags, i); + KUNIT_EXPECT_EQ(test, (int)table->min_is_value, (i & 1) !=3D 0); + KUNIT_EXPECT_EQ(test, (int)table->max_is_value, (i & 2) !=3D 0); + + /* Verify union access */ + if (table->min_is_value) { + KUNIT_EXPECT_EQ(test, table->min, (unsigned long)param->min); + } else { + KUNIT_EXPECT_PTR_EQ(test, table->extra1, &min_bounds[i]); + KUNIT_EXPECT_EQ(test, *(int *)table->extra1, param->min); + } + + if (table->max_is_value) { + KUNIT_EXPECT_EQ(test, table->max, (unsigned long)param->max); + } else { + KUNIT_EXPECT_PTR_EQ(test, table->extra2, &max_bounds[i]); + KUNIT_EXPECT_EQ(test, *(int *)table->extra2, param->max); + } + + /* Test valid value in range */ + data =3D 0; + len =3D strlen(param->valid); + pos =3D 0; + buffer =3D kunit_kzalloc(test, len, GFP_USER); + user_buffer =3D (char __user *)buffer; + memcpy(buffer, param->valid, len); + + KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE, + user_buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, strlen(param->valid), len); + KUNIT_EXPECT_EQ(test, strlen(param->valid), pos); + KUNIT_EXPECT_EQ(test, 50, data); + + /* Test min boundary */ + data =3D 0; + char min_str[16]; + snprintf(min_str, sizeof(min_str), "%d", param->min); + len =3D strlen(min_str); + pos =3D 0; + buffer =3D kunit_kzalloc(test, len, GFP_USER); + user_buffer =3D (char __user *)buffer; + memcpy(buffer, min_str, len); + + KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE, + user_buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, strlen(min_str), len); + KUNIT_EXPECT_EQ(test, strlen(min_str), pos); + KUNIT_EXPECT_EQ(test, param->min, data); + + /* Test max boundary */ + data =3D 0; + char max_str[16]; + snprintf(max_str, sizeof(max_str), "%d", param->max); + len =3D strlen(max_str); + pos =3D 0; + buffer =3D kunit_kzalloc(test, len, GFP_USER); + user_buffer =3D (char __user *)buffer; + memcpy(buffer, max_str, len); + + KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE, + user_buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, strlen(max_str), len); + KUNIT_EXPECT_EQ(test, strlen(max_str), pos); + KUNIT_EXPECT_EQ(test, param->max, data); + + /* Test below min - should fail */ + data =3D 0; + len =3D strlen(param->below_min); + pos =3D 0; + buffer =3D kunit_kzalloc(test, len, GFP_USER); + user_buffer =3D (char __user *)buffer; + memcpy(buffer, param->below_min, len); + + KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WR= ITE, + user_buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, 0, data); + + /* Test above max - should fail */ + data =3D 0; + len =3D strlen(param->above_max); + pos =3D 0; + buffer =3D kunit_kzalloc(test, len, GFP_USER); + user_buffer =3D (char __user *)buffer; + memcpy(buffer, param->above_max, len); + + KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WR= ITE, + user_buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, 0, data); + } +} + static struct kunit_case sysctl_test_cases[] =3D { KUNIT_CASE(sysctl_test_api_dointvec_null_tbl_data), KUNIT_CASE(sysctl_test_api_dointvec_table_maxlen_unset), @@ -311,6 +452,7 @@ static struct kunit_case sysctl_test_cases[] =3D { KUNIT_CASE(sysctl_test_dointvec_write_happy_single_negative), KUNIT_CASE(sysctl_test_api_dointvec_write_single_less_int_min), KUNIT_CASE(sysctl_test_api_dointvec_write_single_greater_int_max), + KUNIT_CASE(sysctl_test_api_dointvec_write_range_check), {} }; =20 --=20 2.25.1 From nobody Wed Feb 11 10:38:05 2026 Received: from out-178.mta1.migadu.com (out-178.mta1.migadu.com [95.215.58.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8B7638FF01 for ; Tue, 13 Jan 2026 17:41:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326070; cv=none; b=NWSEsSTNGYo8YnH8sTUzHDdghvOGpc/PlnnnNtFjyyDqmIoDQmb7eL2mV9aMGitsifGZH2d+Oc0yPwdz5YP4Uwj58fo+J3vDozPGw6i/CwTFeHNls4nLQlAwdHRN0Exax4BgKDg/WJnm8o+Nv5zPp0Cm9XnTjnvUVuSeUMm3IkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768326070; c=relaxed/simple; bh=4tF7C0/K5GxRjUtITWKZmJWWPLvfCUsYLLCaRyb7NvQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Rq6+ps2rqTqfOU3BwFLbvKSeaM1qA3R5FEYuRBxdDjmerLBnWsceb3uw4qHAjCglGRFkzcr+fA1ptEyuFvZ6TphkX8i11vKrNH6kQSJkntOXrCsVN6AWCDW5BuekoeFczMfG4Vck5siRHKhAQnuaf5VAk9du9OouVm6y9zsZnv0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=BDTdDvCx; arc=none smtp.client-ip=95.215.58.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="BDTdDvCx" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1768326067; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UpAbv0unuTX33LMuiBZGkHJD131VDi/YMASM/w+rUBE=; b=BDTdDvCxifzsuTK7TT3mndim0/EQ+1qvj8nyVZh8z/Vq5WEw16kp1sBuKTz1f/fSPE8ly0 NYB44u5kaIFKNlFZw3+v+iQbT6uAlsVZ5KXfqRKr4jFmwXA/68GO8tDhBZwRB3BUAQbWsX vx81rvqaqa5e2OTB2QE89A+R572+s8Y= From: wen.yang@linux.dev To: Joel Granados Cc: linux-kernel@vger.kernel.org, Wen Yang Subject: [RFC PATCH 4/4] scripts/coccinelle: add sysctl_table_init.cocci Date: Wed, 14 Jan 2026 01:40:33 +0800 Message-Id: In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Wen Yang This coccinelle script transforms traditional sysctl table initializations into the new macro-based format using SYSCTL_ENTRY and SYSCTL_RANGE_ENTRY. Suggested-by: Joel Granados Signed-off-by: Wen Yang --- .../coccinelle/api/sysctl_table_init.cocci | 519 ++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 scripts/coccinelle/api/sysctl_table_init.cocci diff --git a/scripts/coccinelle/api/sysctl_table_init.cocci b/scripts/cocci= nelle/api/sysctl_table_init.cocci new file mode 100644 index 000000000000..e2a1ce46329d --- /dev/null +++ b/scripts/coccinelle/api/sysctl_table_init.cocci @@ -0,0 +1,519 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// Convert sysctl table initializations to use SYSCTL_ENTRY and SYSCTL_RA= NGE_ENTRY macros +/// +// Confidence: Medium +// Options: --no-includes --include-headers + +// Virtual rules for different modes +virtual patch +virtual context +virtual report +virtual org + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// STRUCT DECLARATIONS with extra1/extra2 - Type-specific rules +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +// int type +@rule_struct_range_int depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(int), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, int, E2, E3, E4); + +// unsigned int -> uint +@rule_struct_range_uint depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned int), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, uint, E2, E3, E4); + +// unsigned -> uint +@rule_struct_range_unsigned depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, uint, E2, E3, E4); + +// long type +@rule_struct_range_long depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(long), +- .mode =3D E2, +- .proc_handler =3D proc_dolongvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, long, E2, E3, E4); + +// unsigned long -> ulong +@rule_struct_range_ulong depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned long), +- .mode =3D E2, +- .proc_handler =3D proc_doulongvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, ulong, E2, E3, E4); + +// unsigned char -> u8 +@rule_struct_range_u8 depends on patch@ +expression E1, E2, E3, E4; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned char), +- .mode =3D E2, +- .proc_handler =3D proc_dou8vec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- }; ++ struct ctl_table I =3D SYSCTL_RANGE_ENTRY(E1, &D, u8, E2, E3, E4); + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// STRUCT DECLARATIONS without extra1/extra2 - Type-specific rules +// Only match standard proc_handler: proc_dointvec, proc_douintvec, etc. +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +// int type +@rule_struct_simple_int depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(int), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, int, E2); + +// unsigned int -> uint +@rule_struct_simple_uint depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned int), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, uint, E2); + +// unsigned -> uint +@rule_struct_simple_unsigned depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, uint, E2); + +// long type +@rule_struct_simple_long depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(long), +- .mode =3D E2, +- .proc_handler =3D proc_dolongvec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, long, E2); + +// unsigned long -> ulong +@rule_struct_simple_ulong depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned long), +- .mode =3D E2, +- .proc_handler =3D proc_doulongvec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, ulong, E2); + +// unsigned char -> u8 +@rule_struct_simple_u8 depends on patch@ +expression E1, E2; +identifier D, I; +@@ +- struct ctl_table I =3D { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned char), +- .mode =3D E2, +- .proc_handler =3D proc_dou8vec +- }; ++ struct ctl_table I =3D SYSCTL_ENTRY(E1, &D, u8, E2); + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// ARRAY ELEMENTS with extra1/extra2 - Type-specific rules +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +// int type +@rule_array_range_int depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(int), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, int, E2, E3, E4) + +// unsigned int -> uint +@rule_array_range_uint depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned int), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, uint, E2, E3, E4) + +// unsigned -> uint +@rule_array_range_unsigned depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, uint, E2, E3, E4) + +// long type +@rule_array_range_long depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(long), +- .mode =3D E2, +- .proc_handler =3D proc_dolongvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, long, E2, E3, E4) + +// unsigned long -> ulong +@rule_array_range_ulong depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned long), +- .mode =3D E2, +- .proc_handler =3D proc_doulongvec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, ulong, E2, E3, E4) + +// unsigned char -> u8 +@rule_array_range_u8 depends on patch@ +expression E1, E2, E3, E4; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned char), +- .mode =3D E2, +- .proc_handler =3D proc_dou8vec_minmax, +- .extra1 =3D E3, +- .extra2 =3D E4 +- } ++ SYSCTL_RANGE_ENTRY(E1, &D, u8, E2, E3, E4) + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// ARRAY ELEMENTS without extra1/extra2 - Type-specific rules +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +// int type +@rule_array_simple_int depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(int), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec +- } ++ SYSCTL_ENTRY(E1, &D, int, E2) + +// unsigned int -> uint +@rule_array_simple_uint depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned int), +- .mode =3D E2, +- .proc_handler =3D proc_douintvec +- } ++ SYSCTL_ENTRY(E1, &D, uint, E2) + +// unsigned -> uint +@rule_array_simple_unsigned depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned), +- .mode =3D E2, +- .proc_handler =3D proc_dointvec +- } ++ SYSCTL_ENTRY(E1, &D, uint, E2) + +// long type +@rule_array_simple_long depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(long), +- .mode =3D E2, +- .proc_handler =3D proc_dolongvec +- } ++ SYSCTL_ENTRY(E1, &D, long, E2) + +// unsigned long -> ulong +@rule_array_simple_ulong depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned long), +- .mode =3D E2, +- .proc_handler =3D proc_doulongvec +- } ++ SYSCTL_ENTRY(E1, &D, ulong, E2) + +// unsigned char -> u8 +@rule_array_simple_u8 depends on patch@ +expression E1, E2; +identifier D; +@@ +- { +- .procname =3D E1, +- .data =3D &D, +- .maxlen =3D sizeof(unsigned char), +- .mode =3D E2, +- .proc_handler =3D proc_dou8vec +- } ++ SYSCTL_ENTRY(E1, &D, u8, E2) + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// CONTEXT MODE - Generic rule to show all matches +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +@rule_context_range depends on context@ +expression E1, E2, E3, E4; +identifier D; +identifier H =3D {proc_dointvec_minmax, proc_douintvec_minmax, proc_dolong= vec_minmax, proc_doulongvec_minmax, proc_dou8vec_minmax}; +type T; +@@ +* { +* .procname =3D E1, +* .data =3D &D, +* .maxlen =3D sizeof(T), +* .mode =3D E2, +* .proc_handler =3D H, +* .extra1 =3D E3, +* .extra2 =3D E4 +* } + +@rule_context_simple depends on context@ +expression E1, E2; +identifier D; +identifier H =3D {proc_dointvec, proc_douintvec, proc_dolongvec, proc_doul= ongvec, proc_dou8vec}; +type T; +@@ +* { +* .procname =3D E1, +* .data =3D &D, +* .maxlen =3D sizeof(T), +* .mode =3D E2, +* .proc_handler =3D H +* } + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// REPORT MODE - Generic rule to report all matches +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +@rule_report_range depends on report@ +expression E1, E2, E3, E4; +identifier D; +identifier H =3D {proc_dointvec_minmax, proc_douintvec_minmax, proc_dolong= vec_minmax, proc_doulongvec_minmax, proc_dou8vec_minmax}; +type T; +position p; +@@ +{ + .procname@p =3D E1, + .data =3D &D, + .maxlen =3D sizeof(T), + .mode =3D E2, + .proc_handler =3D H, + .extra1 =3D E3, + .extra2 =3D E4 +} + +@script:python depends on report@ +p << rule_report_range.p; +@@ +msg =3D "INFO: ctl_table initialization can use SYSCTL_RANGE_ENTRY" +coccilib.report.print_report(p[0], msg) + +@rule_report_simple depends on report@ +expression E1, E2; +identifier D; +identifier H =3D {proc_dointvec, proc_douintvec, proc_dolongvec, proc_doul= ongvec, proc_dou8vec}; +type T; +position p; +@@ +{ + .procname@p =3D E1, + .data =3D &D, + .maxlen =3D sizeof(T), + .mode =3D E2, + .proc_handler =3D H +} + +@script:python depends on report@ +p << rule_report_simple.p; +@@ +msg =3D "INFO: ctl_table initialization can use SYSCTL_ENTRY" +coccilib.report.print_report(p[0], msg) + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +// ORG MODE - Generic rule for org-mode output +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +@rule_org_range depends on org@ +expression E1, E2, E3, E4; +identifier D; +identifier H =3D {proc_dointvec_minmax, proc_douintvec_minmax, proc_dolong= vec_minmax, proc_doulongvec_minmax, proc_dou8vec_minmax}; +type T; +position p; +@@ +{ + .procname@p =3D E1, + .data =3D &D, + .maxlen =3D sizeof(T), + .mode =3D E2, + .proc_handler =3D H, + .extra1 =3D E3, + .extra2 =3D E4 +} + +@script:python depends on org@ +p << rule_org_range.p; +@@ +msg =3D "INFO: ctl_table initialization can use SYSCTL_RANGE_ENTRY" +coccilib.org.print_todo(p[0], msg) + +@rule_org_simple depends on org@ +expression E1, E2; +identifier D; +identifier H =3D {proc_dointvec, proc_douintvec, proc_dolongvec, proc_doul= ongvec, proc_dou8vec}; +type T; +position p; +@@ +{ + .procname@p =3D E1, + .data =3D &D, + .maxlen =3D sizeof(T), + .mode =3D E2, + .proc_handler =3D H +} + +@script:python depends on org@ +p << rule_org_simple.p; +@@ +msg =3D "INFO: ctl_table initialization can use SYSCTL_ENTRY" +coccilib.org.print_todo(p[0], msg) + --=20 2.25.1