From: NeilBrown <neilb@suse.de>
To: NFS list <linux-nfs@vger.kernel.org>,
"Myklebust, Trond" <Trond.Myklebust@netapp.com>
Subject: Is nfs_flush_incompatible to heavy-handed.
Date: Tue, 28 May 2013 11:58:54 +1000 [thread overview]
Message-ID: <20130528115854.3bbb5175@notabene.brown> (raw)
[-- Attachment #1: Type: text/plain, Size: 2474 bytes --]
The nfs client code has a function "nfs_flush_incompatible" which is called
when a process writes to a page to see if the page is already dirty in a way
that means it should be flushed before the write is permitted.
As I understand it, this is needed so that if two different credentials are
used to write to a file, it is important that the server see the different
writes each with their own credentials. Similarly if two different processes
have different locks, then the writes they send should be kept separate.
However if two processes both have the same credentials and neither are
holding any locks on the file, then there can be no need to flush writes from
one before writes from the other are allowed.
I have a customer who has hit exactly this problem. It particularly involves
mmapped files.
Two different processes both mmap a file which happens to be stored on NFS.
They both update the same pages (with some independent synchronisation) and
when this happens each update requires that the change made by the other
process be flushed first.
This was did not happen before 2.6.24, but since the addition of
nfs_vm_page_mkwrite, it has a serious impact on performance.
So my question is: is it safe to make nfs_flush_incompatible" a bit less
heavy handed, and in particular allow different processes with the same
credentials to update the same page without flushing.
The patch I have been experimenting with is below. It probably don't help on
NFSv4 because there probably needs to be some care taken with different
'state' values. But my customer uses NFSv3 so that is what I focussed on.
Any ideas?
Thanks,
NeilBrown
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index c483cc5..df40c57 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -860,11 +860,16 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
if (req == NULL)
return 0;
l_ctx = req->wb_lock_context;
- do_flush = req->wb_page != page || req->wb_context != ctx;
- if (l_ctx) {
+
+ do_flush = req->wb_page != page;
+ if (req->wb_context != ctx)
+ do_flush |=
+ (req->wb_context->dentry != ctx->dentry ||
+ req->wb_context->cred != ctx->cred );
+ if (l_ctx && (req->wb_context->state || ctx->state))
do_flush |= l_ctx->lockowner.l_owner != current->files
|| l_ctx->lockowner.l_pid != current->tgid;
- }
+
nfs_release_request(req);
if (!do_flush)
return 0;
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
reply other threads:[~2013-05-28 1:59 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20130528115854.3bbb5175@notabene.brown \
--to=neilb@suse.de \
--cc=Trond.Myklebust@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).