All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olga Kornievskaia <olga.kornievskaia@gmail.com>
To: trond.myklebust@hammerspace.com, anna.schumaker@netapp.com
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH] pNFS: fix IO thread starvation problem during LAYOUTUNAVAILABLE error
Date: Tue, 31 May 2022 09:48:54 -0400	[thread overview]
Message-ID: <20220531134854.63115-1-olga.kornievskaia@gmail.com> (raw)

From: Olga Kornievskaia <kolga@netapp.com>

In recent pnfs testing we've incountered IO thread starvation problem
during the time when the server returns LAYOUTUNAVAILABLE error to the
client. When that happens each IO request tries to get a new layout
and the pnfs_update_layout() code ensures that only 1 LAYOUTGET
RPC is outstanding, the rest would be waiting. As the thread that gets
the layout wakes up the waiters only one gets to run and it tends to be
the latest added to the waiting queue. After receiving LAYOUTUNAVAILABLE
error the client would fall back to the MDS writes and as those writes
complete and the new write is issued, those requests are added as
waiters and they get to run before the earliest of the waiters that
was put on the queue originally never gets to run until the
LAYOUTUNAVAILABLE condition resolves itself on the server.

With the current code, if N IOs arrive asking for a layout, then
there will be N serial LAYOUTGETs that will follow, each would be
getting its own LAYOUTUNAVAILABLE error. Instead, the patch proposes
to apply the error condition to ALL the waiters for the outstanding
LAYOUTGET. Once the error is received, the code would allow all
exiting N IOs fall back to the MDS, but any new arriving IOs would be
then queued up and one them the new IO would trigger a new LAYOUTGET.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
---
 fs/nfs/pnfs.c | 14 +++++++++++++-
 fs/nfs/pnfs.h |  2 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 68a87be3e6f9..5b7a679e32c8 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -2028,10 +2028,20 @@ pnfs_update_layout(struct inode *ino,
 	if ((list_empty(&lo->plh_segs) || !pnfs_layout_is_valid(lo)) &&
 	    atomic_read(&lo->plh_outstanding) != 0) {
 		spin_unlock(&ino->i_lock);
+		atomic_inc(&lo->plh_waiting);
 		lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
 					!atomic_read(&lo->plh_outstanding)));
-		if (IS_ERR(lseg))
+		if (IS_ERR(lseg)) {
+			atomic_dec(&lo->plh_waiting);
 			goto out_put_layout_hdr;
+		}
+		if (test_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags)) {
+			pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
+			lseg = NULL;
+			if (atomic_dec_and_test(&lo->plh_waiting))
+				clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags);
+			goto out_put_layout_hdr;
+		}
 		pnfs_put_layout_hdr(lo);
 		goto lookup_again;
 	}
@@ -2152,6 +2162,8 @@ pnfs_update_layout(struct inode *ino,
 		case -ERECALLCONFLICT:
 		case -EAGAIN:
 			break;
+		case -ENODATA:
+			set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags);
 		default:
 			if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
 				pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 07f11489e4e9..5c07da32320b 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -105,6 +105,7 @@ enum {
 	NFS_LAYOUT_FIRST_LAYOUTGET,	/* Serialize first layoutget */
 	NFS_LAYOUT_INODE_FREEING,	/* The inode is being freed */
 	NFS_LAYOUT_HASHED,		/* The layout visible */
+	NFS_LAYOUT_DRAIN,
 };
 
 enum layoutdriver_policy_flags {
@@ -196,6 +197,7 @@ struct pnfs_commit_ops {
 struct pnfs_layout_hdr {
 	refcount_t		plh_refcount;
 	atomic_t		plh_outstanding; /* number of RPCs out */
+	atomic_t		plh_waiting;
 	struct list_head	plh_layouts;   /* other client layouts */
 	struct list_head	plh_bulk_destroy;
 	struct list_head	plh_segs;      /* layout segments list */
-- 
2.27.0


             reply	other threads:[~2022-05-31 13:49 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-31 13:48 Olga Kornievskaia [this message]
2022-05-31 15:00 ` [PATCH] pNFS: fix IO thread starvation problem during LAYOUTUNAVAILABLE error Trond Myklebust
2022-05-31 16:03   ` Olga Kornievskaia
2022-05-31 16:14     ` Trond Myklebust
2022-06-01  7:27     ` Mkrtchyan, Tigran
2022-06-01 15:50       ` Trond Myklebust
2022-06-02 10:09         ` Mkrtchyan, Tigran
2022-05-31 17:17 ` kernel test robot
2022-05-31 18:19 ` kernel test robot
2022-05-31 18:19 ` kernel test robot

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=20220531134854.63115-1-olga.kornievskaia@gmail.com \
    --to=olga.kornievskaia@gmail.com \
    --cc=anna.schumaker@netapp.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trond.myklebust@hammerspace.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.