]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
NFS: Fix direct WRITE throughput regression
authorChuck Lever <chuck.lever@oracle.com>
Fri, 29 May 2020 18:14:40 +0000 (14:14 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Jun 2020 15:49:11 +0000 (17:49 +0200)
[ Upstream commit ba838a75e73f55a780f1ee896b8e3ecb032dba0f ]

I measured a 50% throughput regression for large direct writes.

The observed on-the-wire behavior is that the client sends every
NFS WRITE twice: once as an UNSTABLE WRITE plus a COMMIT, and once
as a FILE_SYNC WRITE.

This is because the nfs_write_match_verf() check in
nfs_direct_commit_complete() fails for every WRITE.

Buffered writes use nfs_write_completion(), which sets req->wb_verf
correctly. Direct writes use nfs_direct_write_completion(), which
does not set req->wb_verf at all. This leaves req->wb_verf set to
all zeroes for every direct WRITE, and thus
nfs_direct_commit_completion() always sets NFS_ODIRECT_RESCHED_WRITES.

This fix appears to restore nearly all of the lost performance.

Fixes: 1f28476dcb98 ("NFS: Fix O_DIRECT commit verifier handling")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/direct.c

index a57e7c72c7f475dbc5861dc8161a3cb00b3526d8..d49b1d197908439f791a71496f50513890e387b5 100644 (file)
@@ -731,6 +731,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
                nfs_list_remove_request(req);
                if (request_commit) {
                        kref_get(&req->wb_kref);
+                       memcpy(&req->wb_verf, &hdr->verf.verifier,
+                              sizeof(req->wb_verf));
                        nfs_mark_request_commit(req, hdr->lseg, &cinfo,
                                hdr->ds_commit_idx);
                }