Message ID | 20201028061054.1411116-1-yhs@fb.com (mailing list archive) |
---|---|
State | Accepted |
Commit | cf83b2d2e2b64920bd6999b199dfa271d7e94cf8 |
Delegated to: | BPF |
Headers | show |
Series | [bpf-next] bpf: permit cond_resched for some iterators | expand |
Hello: This patch was applied to bpf/bpf-next.git (refs/heads/master): On Tue, 27 Oct 2020 23:10:54 -0700 you wrote: > Commit e679654a704e ("bpf: Fix a rcu_sched stall issue with > bpf task/task_file iterator") tries to fix rcu stalls warning > which is caused by bpf task_file iterator when running > "bpftool prog". > > rcu: INFO: rcu_sched self-detected stall on CPU > rcu: \x097-....: (20999 ticks this GP) idle=302/1/0x4000000000000000 softirq=1508852/1508852 fqs=4913 > \x09(t=21031 jiffies g=2534773 q=179750) > NMI backtrace for cpu 7 > CPU: 7 PID: 184195 Comm: bpftool Kdump: loaded Tainted: G W 5.8.0-00004-g68bfc7f8c1b4 #6 > Hardware name: Quanta Twin Lakes MP/Twin Lakes Passive MP, BIOS F09_3A17 05/03/2019 > Call Trace: > <IRQ> > dump_stack+0x57/0x70 > nmi_cpu_backtrace.cold+0x14/0x53 > ? lapic_can_unplug_cpu.cold+0x39/0x39 > nmi_trigger_cpumask_backtrace+0xb7/0xc7 > rcu_dump_cpu_stacks+0xa2/0xd0 > rcu_sched_clock_irq.cold+0x1ff/0x3d9 > ? tick_nohz_handler+0x100/0x100 > update_process_times+0x5b/0x90 > tick_sched_timer+0x5e/0xf0 > __hrtimer_run_queues+0x12a/0x2a0 > hrtimer_interrupt+0x10e/0x280 > __sysvec_apic_timer_interrupt+0x51/0xe0 > asm_call_on_stack+0xf/0x20 > </IRQ> > sysvec_apic_timer_interrupt+0x6f/0x80 > ... > task_file_seq_next+0x52/0xa0 > bpf_seq_read+0xb9/0x320 > vfs_read+0x9d/0x180 > ksys_read+0x5f/0xe0 > do_syscall_64+0x38/0x60 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > [...] Here is the summary with links: - [bpf-next] bpf: permit cond_resched for some iterators https://git.kernel.org/bpf/bpf-next/c/cf83b2d2e2b6 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 2b16bf48aab6..2fffd30e13ac 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1294,6 +1294,10 @@ typedef void (*bpf_iter_show_fdinfo_t) (const struct bpf_iter_aux_info *aux, typedef int (*bpf_iter_fill_link_info_t)(const struct bpf_iter_aux_info *aux, struct bpf_link_info *info); +enum bpf_iter_feature { + BPF_ITER_RESCHED = BIT(0), +}; + #define BPF_ITER_CTX_ARG_MAX 2 struct bpf_iter_reg { const char *target; @@ -1302,6 +1306,7 @@ struct bpf_iter_reg { bpf_iter_show_fdinfo_t show_fdinfo; bpf_iter_fill_link_info_t fill_link_info; u32 ctx_arg_info_size; + u32 feature; struct bpf_ctx_arg_aux ctx_arg_info[BPF_ITER_CTX_ARG_MAX]; const struct bpf_iter_seq_info *seq_info; }; diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c index 8f10e30ea0b0..5454161407f1 100644 --- a/kernel/bpf/bpf_iter.c +++ b/kernel/bpf/bpf_iter.c @@ -67,6 +67,15 @@ static void bpf_iter_done_stop(struct seq_file *seq) iter_priv->done_stop = true; } +static bool bpf_iter_support_resched(struct seq_file *seq) +{ + struct bpf_iter_priv_data *iter_priv; + + iter_priv = container_of(seq->private, struct bpf_iter_priv_data, + target_private); + return iter_priv->tinfo->reg_info->feature & BPF_ITER_RESCHED; +} + /* maximum visited objects before bailing out */ #define MAX_ITER_OBJECTS 1000000 @@ -83,6 +92,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, struct seq_file *seq = file->private_data; size_t n, offs, copied = 0; int err = 0, num_objs = 0; + bool can_resched; void *p; mutex_lock(&seq->lock); @@ -135,6 +145,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, goto done; } + can_resched = bpf_iter_support_resched(seq); while (1) { loff_t pos = seq->index; @@ -180,6 +191,9 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, } break; } + + if (can_resched) + cond_resched(); } stop: offs = seq->count; diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c index 5b6af30bfbcd..1fdb2fc196cd 100644 --- a/kernel/bpf/task_iter.c +++ b/kernel/bpf/task_iter.c @@ -337,6 +337,7 @@ static const struct bpf_iter_seq_info task_seq_info = { static struct bpf_iter_reg task_reg_info = { .target = "task", + .feature = BPF_ITER_RESCHED, .ctx_arg_info_size = 1, .ctx_arg_info = { { offsetof(struct bpf_iter__task, task), @@ -354,6 +355,7 @@ static const struct bpf_iter_seq_info task_file_seq_info = { static struct bpf_iter_reg task_file_reg_info = { .target = "task_file", + .feature = BPF_ITER_RESCHED, .ctx_arg_info_size = 2, .ctx_arg_info = { { offsetof(struct bpf_iter__task_file, task),