public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Al Viro <viro@ZenIV.linux.org.uk>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Eric Dumazet" <eric.dumazet@gmail.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@kernel.org>,
	"Maciej Żenczykowski" <maze@google.com>
Subject: [PATCH? v2] fput: don't abuse task_work_add() too much
Date: Mon, 7 Sep 2015 15:49:24 +0200	[thread overview]
Message-ID: <20150907134924.GA24254@redhat.com> (raw)
In-Reply-To: <20150907122709.GA31811@redhat.com>

On 09/07, Oleg Nesterov wrote:
>
> Oh, I disagree. But I guess I can't convince you/Eric/Linus, so I have
> to shut up.
>
>
> Damn. But I can't relax ;) Al, Linus, could you comment the patch below?
>
> Not for inclusion, lacks the changelog/testing, fput() can be simplified.
> But as you can see it is simple. With this patch task_work_add(____fput)
> will be called only once by (say) do_exit() path. ->fput_list does not
> need any serialization / atomic ops / etc. Probably we also need to move
> cond_resched() from task_work_run() to ____fput() after this patch.
>
> Again, it is not that I think this actually makes sense, but since you
> dislike these 275ms...
>
> What do you think?

Yes, task_struct->fput_list is ugly. We can avoid it, but then we need
another ->next pointer in struct file. Perhaps we can reuse ->f_version?

This way the change looks really simple and not too bad to me. Although
I am not sure you will agree.

Oleg.
---

diff --git a/fs/file_table.c b/fs/file_table.c
index 294174d..c34b666 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -241,7 +241,15 @@ static void delayed_fput(struct work_struct *unused)
 
 static void ____fput(struct callback_head *work)
 {
-	__fput(container_of(work, struct file, f_u.fu_rcuhead));
+	struct file *file = container_of(work, struct file, f_u.fu_rcuhead);
+	struct file *next;
+
+	do {
+		next = file->f_next_put;
+		__fput(file);
+		file = next;
+
+	} while (file);
 }
 
 /*
@@ -267,9 +275,21 @@ void fput(struct file *file)
 		struct task_struct *task = current;
 
 		if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
+			struct callback_head *work = READ_ONCE(task->task_works);
+			struct file *prev;
+
+			if (work && work->func == ____fput) {
+				prev = container_of(work, struct file, f_u.fu_rcuhead);
+				file->f_next_put = prev->f_next_put;
+				prev->f_next_put = file;
+				return;
+			}
+
 			init_task_work(&file->f_u.fu_rcuhead, ____fput);
-			if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
+			if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) {
+				file->f_next_put = NULL;
 				return;
+			}
 			/*
 			 * After this task has run exit_task_work(),
 			 * task_work_add() will fail.  Fall through to delayed
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0774487..9381527 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -849,7 +849,10 @@ struct file {
 	const struct cred	*f_cred;
 	struct file_ra_state	f_ra;
 
-	u64			f_version;
+	union {
+		u64		f_version;
+		struct file	*f_next_put;
+	};
 #ifdef CONFIG_SECURITY
 	void			*f_security;
 #endif


      reply	other threads:[~2015-09-07 13:52 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-29  2:42 [PATCH] task_work: remove fifo ordering guarantee Eric Dumazet
2015-08-29  3:19 ` Linus Torvalds
2015-08-29  9:22   ` Ingo Molnar
2015-08-29 12:54     ` Oleg Nesterov
2015-08-31  6:02       ` Ingo Molnar
2015-08-31 12:51         ` Oleg Nesterov
2015-08-29 12:49 ` Oleg Nesterov
2015-08-29 13:57   ` Eric Dumazet
2015-08-29 14:11     ` Eric Dumazet
2015-08-29 17:08       ` Linus Torvalds
2015-08-31  5:22         ` yalin wang
2015-09-05  5:19           ` Al Viro
2015-08-31 12:44         ` Oleg Nesterov
2015-09-05  5:12         ` Al Viro
2015-09-05  5:42           ` Al Viro
2015-09-05 20:46             ` Linus Torvalds
2015-08-31 12:05     ` change filp_close() to use __fput_sync() ? (Was: [PATCH] task_work: remove fifo ordering guarantee) Oleg Nesterov
2015-09-05  5:35   ` [PATCH] task_work: remove fifo ordering guarantee Al Viro
2015-09-07 12:27     ` [PATCH?] fput: don't abuse task_work_add() too much Oleg Nesterov
2015-09-07 13:49       ` Oleg Nesterov [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150907134924.GA24254@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=eric.dumazet@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maze@google.com \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox