proc: calculate end pointer for /proc/*/* lookup at compile time
authorAlexey Dobriyan <adobriyan@gmail.com>
Thu, 7 Feb 2019 00:58:28 +0000 (11:58 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 8 Feb 2019 09:30:53 +0000 (20:30 +1100)
Compilers like to transform loops like

for (i = 0; i < n; i++) {
[use p[i]]
}

into
for (p = p0; p < end; p++) {
...
}

Do it by hand, so that it results in overall simpler loop
and smaller code.

Space savings:

$ ./scripts/bloat-o-meter ../vmlinux-001 ../obj/vmlinux
add/remove: 0/0 grow/shrink: 2/1 up/down: 4/-9 (-5)
Function                                     old     new   delta
proc_tid_base_lookup                          17      19      +2
proc_tgid_base_lookup                         17      19      +2
proc_pident_lookup                           179     170      -9

The same could be done to proc_pident_readdir(), but the code becomes
bigger for some reason.

Link: http://lkml.kernel.org/r/20190114200422.GB9680@avx2
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
fs/proc/base.c

index 1b26b6a..775a873 100644 (file)
@@ -2463,11 +2463,10 @@ static struct dentry *proc_pident_instantiate(struct dentry *dentry,
 
 static struct dentry *proc_pident_lookup(struct inode *dir, 
                                         struct dentry *dentry,
-                                        const struct pid_entry *ents,
-                                        unsigned int nents)
+                                        const struct pid_entry *p,
+                                        const struct pid_entry *end)
 {
        struct task_struct *task = get_proc_task(dir);
-       const struct pid_entry *p, *last;
        struct dentry *res = ERR_PTR(-ENOENT);
 
        if (!task)
@@ -2477,8 +2476,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
         * Yes, it does not scale. And it should not. Don't add
         * new entries into /proc/<tgid>/ without very good reasons.
         */
-       last = &ents[nents];
-       for (p = ents; p < last; p++) {
+       for (; p < end; p++) {
                if (p->len != dentry->d_name.len)
                        continue;
                if (!memcmp(dentry->d_name.name, p->name, p->len)) {
@@ -2659,7 +2657,8 @@ static struct dentry *proc_attr_dir_lookup(struct inode *dir,
                                struct dentry *dentry, unsigned int flags)
 {
        return proc_pident_lookup(dir, dentry,
-                                 attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
+                                 attr_dir_stuff,
+                                 attr_dir_stuff + ARRAY_SIZE(attr_dir_stuff));
 }
 
 static const struct inode_operations proc_attr_dir_inode_operations = {
@@ -3104,7 +3103,8 @@ struct pid *tgid_pidfd_to_pid(const struct file *file)
 static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 {
        return proc_pident_lookup(dir, dentry,
-                                 tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
+                                 tgid_base_stuff,
+                                 tgid_base_stuff + ARRAY_SIZE(tgid_base_stuff));
 }
 
 static const struct inode_operations proc_tgid_base_inode_operations = {
@@ -3476,7 +3476,8 @@ static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
 static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 {
        return proc_pident_lookup(dir, dentry,
-                                 tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
+                                 tid_base_stuff,
+                                 tid_base_stuff + ARRAY_SIZE(tid_base_stuff));
 }
 
 static const struct file_operations proc_tid_base_operations = {