From: Zhipeng Shi <zhipeng.shi0@gmail.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: peterz@infradead.org, mingo@redhat.com, will@kernel.org,
longman@redhat.com, boqun.feng@gmail.com, tglx@linutronix.de,
schspa@gmail.com, shengjian.xu@horizon.ai,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] locking/rtmutex: Provide proper spin_is_contended
Date: Wed, 8 Jun 2022 22:24:57 +0800 [thread overview]
Message-ID: <20220608142457.GA2400218@ubuntu20> (raw)
In-Reply-To: <Yp8ZaHHBrHzg+o49@linutronix.de>
On Tue, Jun 07, 2022 at 11:24:56AM +0200, Sebastian Andrzej Siewior wrote:
> On 2022-06-07 17:15:14 [+0800], Zhipeng Shi wrote:
> > Commit d89c70356acf ("locking/core: Remove break_lock field when
> > CONFIG_GENERIC_LOCKBREAK=y") removed GENERIC_LOCKBREAK, which caused
> > spin_is_contended depend on the implementation of arch_spin_is_contended.
> > But now in rt-spinlock, spin_is_contended returns 0 directly.
> >
> > This causes cond_resched_lock to fail to correctly detect lock contention
> > in RT-linux. In some scenarios (such as __purge_vmap_area_lazy in vmalloc),
> > this will cause a large latency.
> >
> > This patch provides the implementation of spin_is_contended for
> > rt-spinlock.
>
> Do you have a test-case or an example?
Sorry for late reply, here is my test-case.
After apply this patch, max-latency of vmalloc reduce from 10+ msec to
200+ usec, this because spin_lock is released halfway through
__purge_vmap_area_lazy.
But today I find if I 'chrt -f 10' to my test script, There will still be
a large latency in the vmalloc process. After trace, it seems update_curr_rt
leads to resched_curr. I haven't figured out the reason behind it, and I'm
still trying to figure out why. I would really appreciate your thoughts
on this issue.
Below is the test module
---------------------------------
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <trace/events/kmem.h>
#define TEST_MALLOC_SIZE 64
#define MAX_OFF 20000
void* buf[MAX_OFF];
void* fub[MAX_OFF];
int off = 0;
int ffo = 0;
u64 total_time1 = 0;
u64 total_time2 = 0;
u64 total_cnt1 = 0;
u64 total_cnt2 = 0;
u64 alloc_time1[16];
u64 alloc_time2[16];
#define DECIMAL_BASE 10
#define MODULE_NAME "vmalloc_test"
unsigned long long duration_max = 0;
ssize_t vmalloc_test_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *pos)
{
char set_str[4] = {0};
uint32_t set_bits = 0;
ssize_t err = 0;
ktime_t time1, time2, delta;
unsigned long long duration;
int i = 0;
err = simple_write_to_buffer((void*)set_str, sizeof(set_str) - 1u,
pos, (const void*)buffer, count);
if (err == 0)
return err;
if (kstrtouint(set_str, DECIMAL_BASE, &set_bits) != 0)
return -EINVAL;
switch (set_bits) {
case 0:
if (off >= MAX_OFF) {
printk("buf number exceed\n");
return -1;
}
time1 = ktime_get();
buf[off] = vmalloc(TEST_MALLOC_SIZE);
if (NULL == buf[off]) {
printk("vmalloc buf failed\n");
return -1;
}
memset(buf[off], 1, TEST_MALLOC_SIZE);
off++;
time2 = ktime_get();
delta = ktime_sub(time2, time1);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
if (duration > 8000) {
printk("%s:%d, elapse %llu usec\n",
__func__, __LINE__, duration);
return -1;
}
total_cnt1++;
total_time1 += duration;
alloc_time1[fls(duration) - 1]++;
if (duration > duration_max)
duration_max = duration;
break;
case 1:
for (i = 0; i < MAX_OFF; i++) {
if (buf[i] == NULL)
break;
vfree(buf[i]);
buf[i] = NULL;
}
off = 0;
break;
case 2:
if (ffo >= MAX_OFF) {
printk("buf number exceed\n");
return -1;
}
time1 = ktime_get();
fub[ffo] = vmalloc(TEST_MALLOC_SIZE);
if (NULL == fub[ffo]) {
printk("vmalloc buf failed\n");
return -1;
}
memset(fub[ffo], 1, TEST_MALLOC_SIZE);
ffo++;
time2 = ktime_get();
delta = ktime_sub(time2, time1);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
if (duration > 8000) {
printk("%s:%d, elapse %llu usec\n",
__func__, __LINE__, duration);
//return -1;
}
total_cnt2++;
total_time2 += duration;
alloc_time1[fls(duration)- 1]++;
if (duration > duration_max)
duration_max = duration;
break;
case 3:
for (i = 0; i < MAX_OFF; i++) {
if (fub[i] == NULL)
break;
vfree(fub[i]);
fub[i] = NULL;
}
ffo = 0;
break;
default:
printk("input error\n");
return -EINVAL;
}
return (ssize_t)count;
}
static int32_t vmalloc_test_proc_show(struct seq_file *m, void *v)
{
int i = 0;
seq_printf(m, "max: %llu us\n", duration_max);
seq_printf(m, "avg1: %llu us\n", total_time1/total_cnt1);
seq_printf(m, "avg2: %llu us\n", total_time2/total_cnt2);
for (i = 0; i < 16; i++) {
seq_printf(m, "[%u ~ %u): %llu\n",
1 << i, 1 << (i + 1), alloc_time1[i]);
}
return 0;
}
static int32_t vmalloc_test_fault_injection_proc_open(struct inode *inode,
struct file *file)
{
return single_open(file, vmalloc_test_proc_show, PDE_DATA(inode));
}
static const struct proc_ops vmalloc_test_fault_inject_proc_fops = {
.proc_open = vmalloc_test_fault_injection_proc_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = single_release,
.proc_write = vmalloc_test_proc_write,
};
static struct proc_dir_entry *root_irq_dir = NULL;
static struct proc_dir_entry *entry;
#define vmalloc_test_FAULT_INJECTION_MODE 444
static int32_t vmalloc_test_register_procfs(void)
{
if (NULL == root_irq_dir) {
root_irq_dir = proc_mkdir("driver/vmalloc_test", NULL);
if (NULL == root_irq_dir) {
return -EINVAL;
}
}
entry = proc_create_data("test",
vmalloc_test_FAULT_INJECTION_MODE,
root_irq_dir,
&vmalloc_test_fault_inject_proc_fops, NULL);
if (entry == NULL) {
return -ENOMEM;
}
return 0;
}
static int32_t vmalloc_test_unregister_procfs(void)
{
proc_remove(root_irq_dir);
return 0;
}
static s32 __init vmalloc_test_init(void)
{
int ret;
ret = vmalloc_test_register_procfs();
if (ret) {
printk("register proc failed\n");
return -1;
}
return 0;
}
module_init(vmalloc_test_init);/*PRQA S 0605*/
static void __exit vmalloc_test_exit(void)
{
vmalloc_test_unregister_procfs();
return;
}
module_exit(vmalloc_test_exit);/*PRQA S 0605*/
MODULE_AUTHOR("Sun Kaikai<kaikai.sun@horizon.com>");
MODULE_DESCRIPTION("Hobot GDC driver");
MODULE_LICENSE("GPL v2");
-------------------------------
Below is the test script no.1
-------------------------------------
#!/bin/bash
x=0
while true
do
for i in {1..10000}
do
echo 0 > /proc/driver/vmalloc_test/test
if [ $? != 0 ];then
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo 1 > /proc/driver/vmalloc_test/test
exit
fi
done
echo 1 > /proc/driver/vmalloc_test/test
echo "loop $x done"
x=$((x+1))
done
---------------------------------
Below is the test script no.2
------------------------------
#!/bin/bash
x=0
while true
do
for i in {1..10000}
do
echo 2 > /proc/driver/vmalloc_test/test
if [ $? != 0 ];then
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo 3 > /proc/driver/vmalloc_test/test
exit
fi
done
echo 3 > /proc/driver/vmalloc_test/test
echo "loop1 $x done"
x=$((x+1))
done
------------------------------
>
> The thing if _this_ task has higher priority than other tasks waiting on
> this lock then a simple unlock+lock won't do a thing. That is why I
> ripped it all out while it was half way done.
>
> > Signed-off-by: Zhipeng Shi <zhipeng.shi0@gmail.com>
>
> Sebastian
Zhipeng
next prev parent reply other threads:[~2022-06-08 14:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-07 9:15 [PATCH] locking/rtmutex: Provide proper spin_is_contended Zhipeng Shi
2022-06-07 9:24 ` Sebastian Andrzej Siewior
2022-06-08 14:24 ` Zhipeng Shi [this message]
-- strict thread matches above, loose matches on Subject: below --
2022-06-07 9:24 Zhipeng Shi
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=20220608142457.GA2400218@ubuntu20 \
--to=zhipeng.shi0@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=boqun.feng@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=schspa@gmail.com \
--cc=shengjian.xu@horizon.ai \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
/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.