Skip to content

Commit 2f1f310

Browse files
jankaraamschuma-ntap
authored andcommitted
nfs: Block on write congestion
Commit 6df25e5 ("nfs: remove reliance on bdi congestion") introduced NFS-private solution for limiting number of writes outstanding against a particular server. Unlike previous bdi congestion this algorithm actually works and limits number of outstanding writeback pages to nfs_congestion_kb which scales with amount of client's memory and is capped at 256 MB. As a result some workloads such as random buffered writes over NFS got slower (from ~170 MB/s to ~126 MB/s). The fio command to reproduce is: fio --direct=0 --ioengine=sync --thread --invalidate=1 --group_reporting=1 --runtime=300 --fallocate=posix --ramp_time=10 --new_group --rw=randwrite --size=64256m --numjobs=4 --bs=4k --fsync_on_close=1 --end_fsync=1 This happens because the client sends ~256 MB worth of dirty pages to the server and any further background writeback request is ignored until the number of writeback pages gets below the threshold of 192 MB. By the time this happens and clients decides to trigger another round of writeback, the server often has no pages to write and the disk is idle. To fix this problem and make the client react faster to eased congestion of the server by blocking waiting for congestion to resolve instead of aborting writeback. This improves the random 4k buffered write throughput to 184 MB/s. Reviewed-by: Sagi Grimberg <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent f8a3955 commit 2f1f310

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

fs/nfs/client.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,7 @@ struct nfs_server *nfs_alloc_server(void)
994994

995995
server->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
996996

997+
init_waitqueue_head(&server->write_congestion_wait);
997998
atomic_long_set(&server->writeback, 0);
998999

9991000
ida_init(&server->openowner_id);

fs/nfs/write.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,10 @@ static void nfs_folio_end_writeback(struct folio *folio)
425425

426426
folio_end_writeback(folio);
427427
if (atomic_long_dec_return(&nfss->writeback) <
428-
NFS_CONGESTION_OFF_THRESH)
428+
NFS_CONGESTION_OFF_THRESH) {
429429
nfss->write_congested = 0;
430+
wake_up_all(&nfss->write_congestion_wait);
431+
}
430432
}
431433

432434
static void nfs_page_end_writeback(struct nfs_page *req)
@@ -700,12 +702,17 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
700702
struct nfs_pageio_descriptor pgio;
701703
struct nfs_io_completion *ioc = NULL;
702704
unsigned int mntflags = NFS_SERVER(inode)->flags;
705+
struct nfs_server *nfss = NFS_SERVER(inode);
703706
int priority = 0;
704707
int err;
705708

706-
if (wbc->sync_mode == WB_SYNC_NONE &&
707-
NFS_SERVER(inode)->write_congested)
708-
return 0;
709+
/* Wait with writeback until write congestion eases */
710+
if (wbc->sync_mode == WB_SYNC_NONE && nfss->write_congested) {
711+
err = wait_event_killable(nfss->write_congestion_wait,
712+
nfss->write_congested == 0);
713+
if (err)
714+
return err;
715+
}
709716

710717
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
711718

include/linux/nfs_fs_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ struct nfs_server {
140140
struct rpc_clnt * client_acl; /* ACL RPC client handle */
141141
struct nlm_host *nlm_host; /* NLM client handle */
142142
struct nfs_iostats __percpu *io_stats; /* I/O statistics */
143+
wait_queue_head_t write_congestion_wait; /* wait until write congestion eases */
143144
atomic_long_t writeback; /* number of writeback pages */
144145
unsigned int write_congested;/* flag set when writeback gets too high */
145146
unsigned int flags; /* various flags */

0 commit comments

Comments
 (0)