[lustre-devel] [PATCH 01/18] lustre: statahead: update task management code
James Simmons
jsimmons at infradead.org
Mon Jul 19 05:31:56 PDT 2021
From: "Mr. NeilBrown" <neilb at suse.de>
When the rewrite to remove ptlrpc_thread from statahead
was ported to OpenSFS, a number of improvements were made.
This patch back-ports those to Linux
And import bug-fix is in ll_agl_add() where we now call
wake_up_process() inside a spinlock, so we can be sure the task pointer
is not NULL.
A few while-loops waiting for events have been simplified to only check
each 'continue' condition once instead of checking before doing an
action, then checking it before sleeping.
WC-bug-id: https://jira.whamcloud.com/browse/LU-12780
Lustre-commit: 5b630935452d5d8d7 ("LU-12780 llite: don't use ptlrpc_thread for sai_agl_thread")
Lustre-commit: 6bf49037b3a134587 ("LU-12780 llite: avoid ptlrpc_thread for ll_statahead_thread")
Signed-off-by: Mr. NeilBrown <neilb at suse.de>
Reviewed-on: https://review.whamcloud.com/36258
Reviewed-on: https://review.whamcloud.com/36259
Reviewed-by: Lai Siyao <lai.siyao at whamcloud.com>
Reviewed-by: James Simmons <jsimmons at infradead.org>
Reviewed-by: Shaun Tancheff <shaun.tancheff at hpe.com>
Reviewed-by: Oleg Drokin <green at whamcloud.com>
Signed-off-by: James Simmons <jsimmons at infradead.org>
---
fs/lustre/llite/statahead.c | 95 +++++++++++++++++++++++----------------------
1 file changed, 49 insertions(+), 46 deletions(-)
diff --git a/fs/lustre/llite/statahead.c b/fs/lustre/llite/statahead.c
index 282cb5a..40ea206 100644
--- a/fs/lustre/llite/statahead.c
+++ b/fs/lustre/llite/statahead.c
@@ -35,6 +35,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
+#include <linux/delay.h>
#define DEBUG_SUBSYSTEM S_LLITE
@@ -299,7 +300,6 @@ static void sa_put(struct ll_statahead_info *sai, struct sa_entry *entry,
if (sai->sai_task)
wake_up_process(sai->sai_task);
spin_unlock(&lli->lli_sa_lock);
-
}
/*
@@ -898,37 +898,40 @@ static int ll_agl_thread(void *arg)
CDEBUG(D_READA, "agl thread started: sai %p, parent %pd\n",
sai, parent);
- while (!kthread_should_stop()) {
-
+ while (({set_current_state(TASK_IDLE);
+ !kthread_should_stop(); })) {
spin_lock(&plli->lli_agl_lock);
- /* The statahead thread maybe help to process AGL entries,
- * so check whether list empty again.
- */
clli = list_first_entry_or_null(&sai->sai_agls,
struct ll_inode_info,
lli_agl_list);
if (clli) {
+ __set_current_state(TASK_RUNNING);
list_del_init(&clli->lli_agl_list);
spin_unlock(&plli->lli_agl_lock);
ll_agl_trigger(&clli->lli_vfs_inode, sai);
cond_resched();
} else {
spin_unlock(&plli->lli_agl_lock);
- }
-
- set_current_state(TASK_IDLE);
- if (list_empty(&sai->sai_agls) &&
- !kthread_should_stop())
schedule();
- __set_current_state(TASK_RUNNING);
+ }
}
+ __set_current_state(TASK_RUNNING);
return 0;
}
static void ll_stop_agl(struct ll_statahead_info *sai)
{
- struct ll_inode_info *plli = ll_i2info(sai->sai_dentry->d_inode);
+ struct dentry *parent = sai->sai_dentry;
+ struct ll_inode_info *plli = ll_i2info(parent->d_inode);
struct ll_inode_info *clli;
+ struct task_struct *agl_task;
+
+ spin_lock(&plli->lli_agl_lock);
+ agl_task = sai->sai_agl_task;
+ sai->sai_agl_task = NULL;
+ spin_unlock(&plli->lli_agl_lock);
+ if (!agl_task)
+ return;
CDEBUG(D_READA, "stop agl thread: sai %p pid %u\n",
sai, (unsigned int)sai->sai_agl_task->pid);
@@ -1076,14 +1079,19 @@ static int ll_statahead_thread(void *arg)
fid_le_to_cpu(&fid, &ent->lde_fid);
- do {
- sa_handle_callback(sai);
+ while (({set_current_state(TASK_IDLE);
+ sai->sai_task; })) {
+ if (sa_has_callback(sai)) {
+ __set_current_state(TASK_RUNNING);
+ sa_handle_callback(sai);
+ }
spin_lock(&lli->lli_agl_lock);
while (sa_sent_full(sai) &&
!agl_list_empty(sai)) {
struct ll_inode_info *clli;
+ __set_current_state(TASK_RUNNING);
clli = list_first_entry(&sai->sai_agls,
struct ll_inode_info,
lli_agl_list);
@@ -1097,15 +1105,11 @@ static int ll_statahead_thread(void *arg)
}
spin_unlock(&lli->lli_agl_lock);
- set_current_state(TASK_IDLE);
- if (sa_sent_full(sai) &&
- !sa_has_callback(sai) &&
- agl_list_empty(sai) &&
- sai->sai_task)
- /* wait for spare statahead window */
- schedule();
- __set_current_state(TASK_RUNNING);
- } while (sa_sent_full(sai) && sai->sai_task);
+ if (!sa_sent_full(sai))
+ break;
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
sa_statahead(parent, name, namelen, &fid);
}
@@ -1138,21 +1142,18 @@ static int ll_statahead_thread(void *arg)
* statahead is finished, but statahead entries need to be cached, wait
* for file release to stop me.
*/
- while (sai->sai_task) {
- sa_handle_callback(sai);
-
- set_current_state(TASK_IDLE);
- /* ensure we see the NULL stored by
- * ll_deauthorize_statahead()
- */
- if (!sa_has_callback(sai) &&
- smp_load_acquire(&sai->sai_task))
+ while (({set_current_state(TASK_IDLE);
+ sai->sai_task; })) {
+ if (sa_has_callback(sai)) {
+ __set_current_state(TASK_RUNNING);
+ sa_handle_callback(sai);
+ } else {
schedule();
- __set_current_state(TASK_RUNNING);
+ }
}
+ __set_current_state(TASK_RUNNING);
out:
- if (sai->sai_agl_task)
- ll_stop_agl(sai);
+ ll_stop_agl(sai);
/*
* wait for inflight statahead RPCs to finish, and then we can free sai
@@ -1160,7 +1161,7 @@ static int ll_statahead_thread(void *arg)
*/
while (sai->sai_sent != sai->sai_replied) {
/* in case we're not woken up, timeout wait */
- schedule_timeout_idle(HZ>>3);
+ msleep(125);
}
/* release resources held by statahead RPCs */
@@ -1176,7 +1177,7 @@ static int ll_statahead_thread(void *arg)
wake_up(&sai->sai_waitq);
ll_sai_put(sai);
- do_exit(rc);
+ return rc;
}
/* authorize opened dir handle @key to statahead */
@@ -1220,18 +1221,15 @@ void ll_deauthorize_statahead(struct inode *dir, void *key)
sai = lli->lli_sai;
if (sai && sai->sai_task) {
/*
- * statahead thread may not quit yet because it needs to cache
- * entries, now it's time to tell it to quit.
+ * statahead thread may not have quit yet because it needs to
+ * cache entries, now it's time to tell it to quit.
*
- * In case sai is released, wake_up() is called inside spinlock,
- * so we use smp_store_release() to serialize ops.
+ * wake_up_process() provides the necessary barriers
+ * to pair with set_current_state().
*/
struct task_struct *task = sai->sai_task;
- /* ensure ll_statahead_thread sees the NULL before
- * calling schedule() again.
- */
- smp_store_release(&sai->sai_task, NULL);
+ sai->sai_task = NULL;
wake_up_process(task);
}
spin_unlock(&lli->lli_sa_lock);
@@ -1510,6 +1508,11 @@ static int revalidate_statahead_dentry(struct inode *dir,
ldd = ll_d2d(*dentryp);
ldd->lld_sa_generation = lli->lli_sa_generation;
sa_put(sai, entry, lli);
+ spin_lock(&lli->lli_sa_lock);
+ if (sai->sai_task)
+ wake_up_process(sai->sai_task);
+ spin_unlock(&lli->lli_sa_lock);
+
return rc;
}
--
1.8.3.1
More information about the lustre-devel
mailing list