Patch "fput: turn "list_head delayed_fput_list" into llist_head" has been added to the 3.10-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
fput: turn "list_head delayed_fput_list" into llist_head
to the 3.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
fput-turn-list_head-delayed_fput_list-into-llist_head.patch
and it can be found in the queue-3.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
4f5e65a1cc90bbb15b9f6cdc362922af1bcc155aMon Sep 17 00:00:00 2001
From: Oleg Nesterov <[email protected]>
Date: Mon, 8 Jul 2013 14:24:16 -0700
Subject: fput: turn "list_head delayed_fput_list" into llist_head
From: Oleg Nesterov <[email protected]>
commit 4f5e65a1cc90bbb15b9f6cdc362922af1bcc155a upstream.
fput() and delayed_fput() can use llist and avoid the locking.
This is unlikely path, it is not that this change can improve the performance, but this way the code looks simpler.
--- fs/file_table.c | 25 ++++++++++--------------- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 15 deletions(-)
fs/file_table.c +10 -15
@@ -265,18 +265,15 @@ static void __fput(struct file *file)mntput (mnt); } -static DEFINE_SPINLOCK (delayed_fput_lock); -static LIST_HEAD (delayed_fput_list); +static LLIST_HEAD (delayed_fput_list);static void delayed_fput (struct work_struct *unused) { -LIST_HEAD (head); -spin_lock_irq (&delayed_fput_lock); -list_splice_init (&delayed_fput_list, &head); -spin_unlock_irq (&delayed_fput_lock); -while (!list_empty (&head)) { - struct file *f = list_first_entry(&head, struct file, f_u.fu_list); -list_del_init (&f->f_u.fu_list); -__fput (f); +struct llist_node *node =llist_del_all (&delayed_fput_list); +struct llist_node *next; + +for (; node; node = next) { + next =llist_next (node); + __fput(llist_entry(node, struct file, f_u.fu_llist)); } }
@@ -306,7 +303,6 @@ void fput(struct file *file) {if (atomic_long_dec_and_test (&file->f_count)) {struct task_struct *task = current; -unsigned long flags;file_sb_list_del (file);if (likely (!in_interrupt () && !(task->flags &PF_KTHREAD ))) {
@@ -314,10 +310,9 @@ void fput(struct file *file)if (!task_work_add (task, &file->f_u.fu_rcuhead, true))return ; } -spin_lock_irqsave (&delayed_fput_lock, flags); -list_add (&file->f_u.fu_list, &delayed_fput_list); -schedule_work (&delayed_fput_work); -spin_unlock_irqrestore (&delayed_fput_lock, flags); + +if (llist_add (&file->f_u.fu_llist, &delayed_fput_list)) +schedule_work (&delayed_fput_work); } }
include/linux/fs.h +2 -0
@@ -10,6 +10,7 @@#include <linux/stat.h> #include <linux/cache.h> #include <linux/list.h> +#include <linux/llist.h> #include <linux/radix-tree.h> #include <linux/rbtree.h> #include <linux/init.h>
@@ -767,6 +768,7 @@ struct file {*/ union {struct list_head fu_list; +struct llist_node fu_llist;struct rcu_head fu_rcuhead; } f_u;struct path f_path;
Patches currently in stable-queue which might be from [email protected] are
queue-3.10/fput-turn-list_head-delayed_fput_list-into-llist_head.patch