On 2021/5/11 下午12:59, [email protected] wrote:
On 2021/5/11 上午11:24, Bruce Ashfield wrote:
[Please note: This e-mail is from an EXTERNAL e-mail address]
In message: Re: [PATCH 0/1] fs: dcache: avoid livelocks on
d_alloc_parallel
on 11/05/2021 Wenlin Kang wrote:
On 2021/5/11 上午11:04, Bruce Ashfield wrote:
[Please note: This e-mail is from an EXTERNAL e-mail address]
The patch looks good, but is it for 5.10/rt ? Or some other version
and
set of branches ?
Hi bruce
v5.2/standard/preempt-rt
The detail info was written in email "[linux-yocto] [PATCH 0/1] fs:
dcache:
avoid livelocks on d_alloc_parallel",
Aha. That also needs to be summarized in the subject in [], since that
is what my scans pick up during merging.
i.e. [linux-yocto 5.2/standard/base]
What about the other versions of RT ? Do they suffer the same issue ?
We have 5.4/5.10 as newer supported rt versions that might also need
the change.
The patch was made on branch v5.2/standard/preempt-rt/base, and it
also is the highest version I found,
for previous versions, I don't check all branches, but I think it
should be applicable to them.
Hi Bruce
I have checked the v5.4 and v5.10 RT, they should have this issue too,
but for v5.10/standard/preempt-rt/base and v5.4/standard/preempt-rt/base,
it has the change on config option, so we should apply the new attached
patch.
Bruce
please check it, thanks.
Bruce
In message: [PATCH 0/1] fs: dcache: avoid livelocks on
d_alloc_parallel
on 08/05/2021 Kang Wenlin wrote:
From: Wenlin Kang <[email protected]>
With RT, if a high priority task that runs d_alloc_parallel()
preempts a
low priority task that runs __d_add(), it can make
d_alloc_parallel() go
into an infinite retry.
low priority task: high priority task:
__lookup_slow()
d_add()
__d_add
start_dir_add(dir) __lookup_slow()
d_alloc_parallel()
When the low priority task finished start_dir_add(), i_dir_seq has
been
incremented to an odd value. Since __d_add() uses spin_lock(),
migration
is disabled, so if the low priority task is preempted during
start_dir_add()
/end_dir_add(), then high priority task can go into an infinite
waiting for
i_dir_seq.
This patch avoid the issue by enable preempt_disable() during
start_dir_add()
/end_dir_add().
Steps to reproduce:
$ taskset -c 1 chrt -f 70 ./test1.sh &
$ taskset -c 1 chrt -f 80 ./test2.sh &
After about 30 minutes, check whether serial console responds.
The problem happens with specific script combinations(test1.sh and
test2.sh)
This problem was reproduced on v4.12 with preempt-rt, but I think
it should be
exist on v5.2/standard/preempt-rt
P.S.
$ cat test1.sh
#!/bin/bash
while true; do
usleep 1
done
$ cat test2.sh
#!/bin/bash
while true; do
cat /proc/stat > /dev/null
usleep 100
done
Wenlin Kang (1):
fs: dcache: avoid livelocks on d_alloc_parallel
fs/dcache.c | 6 ++++++
1 file changed, 6 insertions(+)
--
1.9.1
--
Thanks,
Wenlin Kang
--
Thanks,
Wenlin Kang
>From eb04091a4c6067a3f10b7abe208fb2b7027162b9 Mon Sep 17 00:00:00 2001
From: Wenlin Kang <[email protected]>
Date: Sun, 25 Apr 2021 17:54:02 +0800
Subject: [PATCH] fs: dcache: avoid livelocks on d_alloc_parallel
With RT, if a high priority task that runs d_alloc_parallel() preempts a
low priority task that runs __d_add(), it can make d_alloc_parallel() go
into an infinite retry.
low priority task: high priority task:
__lookup_slow()
d_add()
__d_add
start_dir_add(dir) __lookup_slow()
d_alloc_parallel()
When the low priority task finished start_dir_add(), i_dir_seq has been
incremented to an odd value. Since __d_add() uses spin_lock(), migration
is disabled, so if the low priority task is preempted during start_dir_add()
/end_dir_add(), then high priority task can go into an infinite waiting for
i_dir_seq.
This patch avoid the issue by enable preempt_disable() during start_dir_add()
/end_dir_add().
Signed-off-by: Wenlin Kang <[email protected]>
---
fs/dcache.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/dcache.c b/fs/dcache.c
index ad9bffc..16e204d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2667,6 +2667,9 @@ static inline void __d_add(struct dentry *dentry, struct inode *inode)
{
struct inode *dir = NULL;
unsigned n;
+#ifdef CONFIG_PREEMPT_RT
+ preempt_disable();
+#endif
spin_lock(&dentry->d_lock);
if (unlikely(d_in_lookup(dentry))) {
dir = dentry->d_parent->d_inode;
@@ -2685,6 +2688,9 @@ static inline void __d_add(struct dentry *dentry, struct inode *inode)
if (dir)
end_dir_add(dir, n);
spin_unlock(&dentry->d_lock);
+#ifdef CONFIG_PREEMPT_RT
+ preempt_enable();
+#endif
if (inode)
spin_unlock(&inode->i_lock);
}
--
1.9.1
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#9877):
https://lists.yoctoproject.org/g/linux-yocto/message/9877
Mute This Topic: https://lists.yoctoproject.org/mt/82675356/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-