From nobody Wed Jun 24 01:04:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B0FAC433F5 for ; Thu, 24 Feb 2022 09:32:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232764AbiBXJdS (ORCPT ); Thu, 24 Feb 2022 04:33:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232750AbiBXJdN (ORCPT ); Thu, 24 Feb 2022 04:33:13 -0500 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F01B020A952 for ; Thu, 24 Feb 2022 01:32:41 -0800 (PST) X-QQ-mid: bizesmtp88t1645695147tgwdwkrk Received: from localhost.localdomain (unknown [58.240.82.166]) by bizesmtp.qq.com (ESMTP) with id ; Thu, 24 Feb 2022 17:32:03 +0800 (CST) X-QQ-SSF: 01400000000000B0F000B00A0000000 X-QQ-FEAT: ZHWZeLXy+8esjqh9jW/ic4y9x7g7V3PVFwHyCbsFjWvtnbyYVlEAO51fszt3T bHxSjNJkqhDKUPW3TEdys3rX/ZjRS2WriSEw7szpdmFr/wjNCZ3jy56t5N8eNio1rzwavz9 g+NrNE0rkbkIglNhcKQPmsFNTM+I/Moj/xIV9pAImVgNztfggHlOmlPsCsIIOZSZVhkpkNL izzDMA51RSzItJVneHxc9/MQE6Z+LIbwQD3tSUqbIjj2t/VxU3jZiT3G/JepSwPApydef8p cl4EL/QX0ywPwrDkNQ+JHzuetTFGg1Qvi/emVHK++mxW5+pUkJqzmjBufyCtfjCv6vAJLzb KDYE1h3DWLL2Qa5JaX4/pPWb0yLeg== X-QQ-GoodBg: 2 From: Meng Tang To: mcgrof@kernel.org, keescook@chromium.org, yzaikin@google.com Cc: nixiaoming@huawei.com, nizhen@uniontech.com, zhanglianjie@uniontech.com, sujiaxun@uniontech.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Meng Tang Subject: [PATCH] fs/proc: optimize exactly register one ctl_table Date: Thu, 24 Feb 2022 17:32:01 +0800 Message-Id: <20220224093201.12440-1-tangmeng@uniontech.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:uniontech.com:qybgforeign:qybgforeign6 X-QQ-Bgrelay: 1 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently, sysctl is being moved to its own file. But ctl_table is quite large(64 bytes per entry) and every array is terminated with an empty one. This leads to thar when register exactly one ctl_table, we've gone from 64 bytes to 128 bytes. So, it is obviously the right thing that we need to fix. In order to avoid compatibility problems, and to be compatible with array terminated with an empty one and register exactly one ctl_table, add the register_one variable in the ctl_table structure to fix it. When we register exactly one table, we only need to add "table->register =3D true" to avoid gone from 64 bytes to 128 bytes. Signed-off-by: Meng Tang --- fs/proc/proc_sysctl.c | 58 +++++++++++++++++++++++++++++++++++++++--- include/linux/sysctl.h | 1 + 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 7d9cfc730bd4..9ecd5c87e8dd 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -215,16 +215,24 @@ static void init_header(struct ctl_table_header *head, INIT_HLIST_HEAD(&head->inodes); if (node) { struct ctl_table *entry; - for (entry =3D table; entry->procname; entry++, node++) + for (entry =3D table; entry->procname; entry++, node++) { node->header =3D head; + + if (entry->register_one) + break; + } } } =20 static void erase_header(struct ctl_table_header *head) { struct ctl_table *entry; - for (entry =3D head->ctl_table; entry->procname; entry++) + for (entry =3D head->ctl_table; entry->procname; entry++) { erase_entry(head, entry); + + if (entry->register_one) + break; + } } =20 static int insert_header(struct ctl_dir *dir, struct ctl_table_header *hea= der) @@ -252,6 +260,9 @@ static int insert_header(struct ctl_dir *dir, struct ct= l_table_header *header) err =3D insert_entry(header, entry); if (err) goto fail; + + if (entry->register_one) + break; } return 0; fail: @@ -1159,6 +1170,9 @@ static int sysctl_check_table(const char *path, struc= t ctl_table *table) if ((table->mode & (S_IRUGO|S_IWUGO)) !=3D table->mode) err |=3D sysctl_err(path, table, "bogus .mode 0%o", table->mode); + + if (table->register_one) + break; } return err; } @@ -1177,6 +1191,9 @@ static struct ctl_table_header *new_links(struct ctl_= dir *dir, struct ctl_table for (entry =3D table; entry->procname; entry++) { nr_entries++; name_bytes +=3D strlen(entry->procname) + 1; + + if (entry->register_one) + break; } =20 links =3D kzalloc(sizeof(struct ctl_table_header) + @@ -1199,6 +1216,9 @@ static struct ctl_table_header *new_links(struct ctl_= dir *dir, struct ctl_table link->mode =3D S_IFLNK|S_IRWXUGO; link->data =3D link_root; link_name +=3D len; + + if (entry->register_one) + break; } init_header(links, dir->header.root, dir->header.set, node, link_table); links->nreg =3D nr_entries; @@ -1218,6 +1238,15 @@ static bool get_links(struct ctl_dir *dir, link =3D find_entry(&head, dir, procname, strlen(procname)); if (!link) return false; + + if (entry->register_one) { + if (S_ISDIR(link->mode) && S_ISDIR(entry->mode)) + break; + if (S_ISLNK(link->mode) && (link->data =3D=3D link_root)) + break; + return false; + } + if (S_ISDIR(link->mode) && S_ISDIR(entry->mode)) continue; if (S_ISLNK(link->mode) && (link->data =3D=3D link_root)) @@ -1230,6 +1259,8 @@ static bool get_links(struct ctl_dir *dir, const char *procname =3D entry->procname; link =3D find_entry(&head, dir, procname, strlen(procname)); head->nreg++; + if (entry->register_one) + break; } return true; } @@ -1295,6 +1326,8 @@ static int insert_links(struct ctl_table_header *head) * * mode - the file permissions for the /proc/sys file * + * register_one - set to true when exactly register one ctl_table + * * child - must be %NULL. * * proc_handler - the text handler routine (described below) @@ -1329,9 +1362,13 @@ struct ctl_table_header *__register_sysctl_table( struct ctl_node *node; int nr_entries =3D 0; =20 - for (entry =3D table; entry->procname; entry++) + for (entry =3D table; entry->procname; entry++) { nr_entries++; =20 + if (entry->register_one) + break; + } + header =3D kzalloc(sizeof(struct ctl_table_header) + sizeof(struct ctl_node)*nr_entries, GFP_KERNEL); if (!header) @@ -1461,6 +1498,9 @@ static int count_subheaders(struct ctl_table *table) nr_subheaders +=3D count_subheaders(entry->child); else has_files =3D 1; + + if (entry->register_one) + break; } return nr_subheaders + has_files; } @@ -1480,6 +1520,9 @@ static int register_leaf_sysctl_tables(const char *pa= th, char *pos, nr_dirs++; else nr_files++; + + if (entry->register_one) + break; } =20 files =3D table; @@ -1497,6 +1540,9 @@ static int register_leaf_sysctl_tables(const char *pa= th, char *pos, continue; *new =3D *entry; new++; + + if (entry->register_one) + break; } } =20 @@ -1532,6 +1578,9 @@ static int register_leaf_sysctl_tables(const char *pa= th, char *pos, pos[0] =3D '\0'; if (err) goto out; + + if (entry->register_one) + break; } err =3D 0; out: @@ -1686,6 +1735,9 @@ static void put_links(struct ctl_table_header *header) sysctl_print_dir(parent); pr_cont("%s\n", name); } + + if (entry->register_one) + break; } } =20 diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 6353d6db69b2..889c995d8a08 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -134,6 +134,7 @@ struct ctl_table { void *data; int maxlen; umode_t mode; + bool register_one; /* Exactly register one ctl_table*/ struct ctl_table *child; /* Deprecated */ proc_handler *proc_handler; /* Callback for text formatting */ struct ctl_table_poll *poll; --=20 2.20.1