proc: spread likely/unlikely a bit
authorAlexey Dobriyan <adobriyan@gmail.com>
Tue, 6 Feb 2018 23:37:28 +0000 (15:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 7 Feb 2018 02:32:43 +0000 (18:32 -0800)
use_pde() is used at every open/read/write/...  of every random /proc
file.  Negative refcount happens only if PDE is being deleted by module
(read: never).  So it gets "likely".

unuse_pde() gets "unlikely" for the same reason.

close_pdeo() gets unlikely as the completion is filled only if there is a
race between PDE removal and close() (read: never ever).

It even saves code on x86_64 defconfig:

add/remove: 0/0 grow/shrink: 1/2 up/down: 2/-20 (-18)
Function                                     old     new   delta
close_pdeo                                   183     185      +2
proc_reg_get_unmapped_area                   119     111      -8
proc_reg_poll                                 85      73     -12

Link: http://lkml.kernel.org/r/20180104175657.GA5204@avx2
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/proc/inode.c

index c5c8e7af5520f351868f3039a69ecb5731a271d5..6e8724958116c56dc97dd05414269622b330e58d 100644 (file)
@@ -129,12 +129,12 @@ enum {BIAS = -1U<<31};
 
 static inline int use_pde(struct proc_dir_entry *pde)
 {
-       return atomic_inc_unless_negative(&pde->in_use);
+       return likely(atomic_inc_unless_negative(&pde->in_use));
 }
 
 static void unuse_pde(struct proc_dir_entry *pde)
 {
-       if (atomic_dec_return(&pde->in_use) == BIAS)
+       if (unlikely(atomic_dec_return(&pde->in_use) == BIAS))
                complete(pde->pde_unload_completion);
 }
 
@@ -167,7 +167,7 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
                spin_lock(&pde->pde_unload_lock);
                /* After ->release. */
                list_del(&pdeo->lh);
-               if (pdeo->c)
+               if (unlikely(pdeo->c))
                        complete(pdeo->c);
                kfree(pdeo);
        }
@@ -421,7 +421,7 @@ static const char *proc_get_link(struct dentry *dentry,
                                 struct delayed_call *done)
 {
        struct proc_dir_entry *pde = PDE(inode);
-       if (unlikely(!use_pde(pde)))
+       if (!use_pde(pde))
                return ERR_PTR(-EINVAL);
        set_delayed_call(done, proc_put_link, pde);
        return pde->data;