The whole point of code in fs/proc/inode.c is to make sure ->release
hook is called either at close() or at rmmod time.

All if it is unnecessary if there is no ->release hook.

Save allocation+list manipulations under spinlock in that case.

Signed-off-by: Alexey Dobriyan <adobri...@gmail.com>
---

 fs/proc/inode.c |   41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -342,31 +342,36 @@ static int proc_reg_open(struct inode *inode, struct file 
*file)
         *
         * Save every "struct file" with custom ->release hook.
         */
-       pdeo = kmalloc(sizeof(struct pde_opener), GFP_KERNEL);
-       if (!pdeo)
-               return -ENOMEM;
-
-       if (!use_pde(pde)) {
-               kfree(pdeo);
+       if (!use_pde(pde))
                return -ENOENT;
-       }
-       open = pde->proc_fops->open;
+
        release = pde->proc_fops->release;
+       if (release) {
+               pdeo = kmalloc(sizeof(struct pde_opener), GFP_KERNEL);
+               if (!pdeo) {
+                       rv = -ENOMEM;
+                       goto out_unuse;
+               }
+       }
 
+       open = pde->proc_fops->open;
        if (open)
                rv = open(inode, file);
 
-       if (rv == 0 && release) {
-               /* To know what to release. */
-               pdeo->file = file;
-               pdeo->closing = false;
-               pdeo->c = NULL;
-               spin_lock(&pde->pde_unload_lock);
-               list_add(&pdeo->lh, &pde->pde_openers);
-               spin_unlock(&pde->pde_unload_lock);
-       } else
-               kfree(pdeo);
+       if (release) {
+               if (rv == 0) {
+                       /* To know what to release. */
+                       pdeo->file = file;
+                       pdeo->closing = false;
+                       pdeo->c = NULL;
+                       spin_lock(&pde->pde_unload_lock);
+                       list_add(&pdeo->lh, &pde->pde_openers);
+                       spin_unlock(&pde->pde_unload_lock);
+               } else
+                       kfree(pdeo);
+       }
 
+out_unuse:
        unuse_pde(pde);
        return rv;
 }

Reply via email to