2022-03-17 12:58:29

by Hyeonggon Yoo

[permalink] [raw]
Subject: RCU: undefined reference to irq_work_queue

Hello RCU folks,

I like to use minimal configuration for kernel development.
when building with tinyconfig + CONFIG_PREEMPT=y on arm64:

ld: kernel/rcu/update.o: in function `call_rcu_tasks':
update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
make: *** [Makefile:1155: vmlinux] Error 1

It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.

--
Thank you, You are awesome!
Hyeonggon :-)


2022-03-17 18:12:17

by Hyeonggon Yoo

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > Hello RCU folks,
> >
> > I like to use minimal configuration for kernel development.
> > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> >
> > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > make: *** [Makefile:1155: vmlinux] Error 1
> >
> > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
>
> Indeed it does!
>
> And kernel/rcu/Kconfig shows why:
>
> config TASKS_TRACE_RCU
> def_bool 0
> select IRQ_WORK
> help
> This option enables a task-based RCU implementation that uses
> explicit rcu_read_lock_trace() read-side markers, and allows
> these readers to appear in the idle loop as well as on the CPU
> hotplug code paths. It can force IPIs on online CPUs, including
> idle ones, so use with caution.
>
> So the solution is to further minimize your configuration so as to
> deselect TASKS_TRACE_RCU.

They are already not selected.

> This means making sure that both BPF and
> the various RCU torture tests are all deselected.

I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
selected, making it fail to build.

> > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > make: *** [Makefile:1155: vmlinux] Error 1

Isn't it better to fix this build failure?

It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
and PREEMPT is selected.

│ Symbol: TASKS_TRACE_RCU [=n] │
│ Type : bool │
│ Defined at kernel/rcu/Kconfig:96 │
│ Selects: IRQ_WORK [=n] │
│ Selected by [n]: │
│ - BPF_SYSCALL [=n] │
│ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
│ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
│ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]

Thanks!

>
> Or turn on IRQ_WORK, for example, if you need to use BPF.
>
> Thanx, Paul

--
Thank you, You are awesome!
Hyeonggon :-)

2022-03-17 19:46:03

by Paul E. McKenney

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > Hello RCU folks,
> > >
> > > I like to use minimal configuration for kernel development.
> > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > >
> > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > make: *** [Makefile:1155: vmlinux] Error 1
> > >
> > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> >
> > Indeed it does!
> >
> > And kernel/rcu/Kconfig shows why:
> >
> > config TASKS_TRACE_RCU
> > def_bool 0
> > select IRQ_WORK
> > help
> > This option enables a task-based RCU implementation that uses
> > explicit rcu_read_lock_trace() read-side markers, and allows
> > these readers to appear in the idle loop as well as on the CPU
> > hotplug code paths. It can force IPIs on online CPUs, including
> > idle ones, so use with caution.
> >
> > So the solution is to further minimize your configuration so as to
> > deselect TASKS_TRACE_RCU.
>
> They are already not selected.

Good, thank you.

How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?

> > This means making sure that both BPF and
> > the various RCU torture tests are all deselected.
>
> I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> selected, making it fail to build.

I am guessing because TASKS_RCU_GENERIC is selected?

If so, does the patch at the end of this email help?

> > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > make: *** [Makefile:1155: vmlinux] Error 1
>
> Isn't it better to fix this build failure?

But of course! However, first I need to know exactly what is causing your
build failure. I cannot see your .config file, so I am having to guess.

Don't get me wrong, I do have a lot of practice guessing, but it is still
just guessing. ;-)

> It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> and PREEMPT is selected.
>
> │ Symbol: TASKS_TRACE_RCU [=n] │
> │ Type : bool │
> │ Defined at kernel/rcu/Kconfig:96 │
> │ Selects: IRQ_WORK [=n] │
> │ Selected by [n]: │
> │ - BPF_SYSCALL [=n] │
> │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
>
> Thanks!
>
> >
> > Or turn on IRQ_WORK, for example, if you need to use BPF.

Or do you already have TASKS_RCU_GENERIC deselected?

Thanx, Paul

------------------------------------------------------------------------

diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
index bf8e341e75b4..f559870fbf8b 100644
--- a/kernel/rcu/Kconfig
+++ b/kernel/rcu/Kconfig
@@ -86,6 +86,7 @@ config TASKS_RCU

config TASKS_RUDE_RCU
def_bool 0
+ select IRQ_WORK
help
This option enables a task-based RCU implementation that uses
only context switch (including preemption) and user-mode

2022-03-17 19:46:15

by Zhouyi Zhou

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

Hi,

On Thu, Mar 17, 2022 at 8:48 PM Hyeonggon Yoo <[email protected]> wrote:
>
> Hello RCU folks,
>
> I like to use minimal configuration for kernel development.
> when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
I invoke cross compiler to reproduce the bug on my X86 machine
$make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
CC=aarch64-linux-gnu-gcc-10 tinyconfig
let CONFIG_PREEMPT=y in .config
$make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
CC=aarch64-linux-gnu-gcc-10 -j 16
LD vmlinux
aarch64-linux-gnu-ld: kernel/rcu/update.o: in function `call_rcu_tasks':
update.c:(.text+0xb30): undefined reference to `irq_work_queue'
update.c:(.text+0xb30): relocation truncated to fit: R_AARCH64_CALL26
against undefined symbol `irq_work_queue'
>
> ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> make: *** [Makefile:1155: vmlinux] Error 1
>
> It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
>
> --
> Thank you, You are awesome!
> Hyeonggon :-)
Meanwhile, there is no error for doing the same to build X86 kernel.
I think the reason is:
arch/x86/Kconfig select PERF_EVENT
and PERF_EVENT select IRQ_WORK

Hope my little research could provide some clues to solve the problem ;-)

You are welcome
Cheers
Zhouyi

2022-03-17 19:46:40

by Hyeonggon Yoo

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> > On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > > Hello RCU folks,
> > > >
> > > > I like to use minimal configuration for kernel development.
> > > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > > >
> > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > >
> > > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> > >
> > > Indeed it does!
> > >
> > > And kernel/rcu/Kconfig shows why:
> > >
> > > config TASKS_TRACE_RCU
> > > def_bool 0
> > > select IRQ_WORK
> > > help
> > > This option enables a task-based RCU implementation that uses
> > > explicit rcu_read_lock_trace() read-side markers, and allows
> > > these readers to appear in the idle loop as well as on the CPU
> > > hotplug code paths. It can force IPIs on online CPUs, including
> > > idle ones, so use with caution.
> > >
> > > So the solution is to further minimize your configuration so as to
> > > deselect TASKS_TRACE_RCU.
> >
> > They are already not selected.
>
> Good, thank you.
>
> How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?
>

TASKS_RUDE_RCU=n
TASKS_TRACE_RCU=n
TASKS_RCU_GENERIC=y
TASKS_RCU=y

> > > This means making sure that both BPF and
> > > the various RCU torture tests are all deselected.
> >
> > I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> > selected, making it fail to build.
>
> I am guessing because TASKS_RCU_GENERIC is selected?
>

Right.

> If so, does the patch at the end of this email help?
>

No. did not help.

I think I found reason...
with PREEMPTION=y,

in kernel/rcu/Kconfig:
config TASKS_RCU
def_bool PREEMPTION
help
This option enables a task-based RCU implementation that uses
only voluntary context switch (not preemption!), idle, and
user-mode execution as quiescent states. Not for manual selection.

in kernel/rcu/Kconfig:
config TASKS_RCU_GENERIC
def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
select SRCU
help
This option enables generic infrastructure code supporting
task-based RCU implementations. Not for manual selection.


> > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > make: *** [Makefile:1155: vmlinux] Error 1
> >
> > Isn't it better to fix this build failure?
>
> But of course! However, first I need to know exactly what is causing your
> build failure. I cannot see your .config file, so I am having to guess.
>
> Don't get me wrong, I do have a lot of practice guessing, but it is still
> just guessing. ;-)

Sorry to make you guess. Maybe too late, but added config as attachment ;)

>
> > It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> > and PREEMPT is selected.
> >
> > │ Symbol: TASKS_TRACE_RCU [=n] │
> > │ Type : bool │
> > │ Defined at kernel/rcu/Kconfig:96 │
> > │ Selects: IRQ_WORK [=n] │
> > │ Selected by [n]: │
> > │ - BPF_SYSCALL [=n] │
> > │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> > │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> > │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
> >
> > Thanks!
> >
> > >
> > > Or turn on IRQ_WORK, for example, if you need to use BPF.
>
> Or do you already have TASKS_RCU_GENERIC deselected?
>

No, this is selected. TASKS_RCU_GENERIC=y. because of PREEMPTION=y.

Thanks!

> Thanx, Paul
>
> ------------------------------------------------------------------------
>
> diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> index bf8e341e75b4..f559870fbf8b 100644
> --- a/kernel/rcu/Kconfig
> +++ b/kernel/rcu/Kconfig
> @@ -86,6 +86,7 @@ config TASKS_RCU
>
> config TASKS_RUDE_RCU
> def_bool 0
> + select IRQ_WORK
> help
> This option enables a task-based RCU implementation that uses
> only context switch (including preemption) and user-mode

--
Thank you, You are awesome!
Hyeonggon :-)


Attachments:
(No filename) (5.02 kB)
.config (32.73 kB)
Download all attachments

2022-03-17 20:17:50

by Paul E. McKenney

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> Hello RCU folks,
>
> I like to use minimal configuration for kernel development.
> when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
>
> ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> make: *** [Makefile:1155: vmlinux] Error 1
>
> It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.

Indeed it does!

And kernel/rcu/Kconfig shows why:

config TASKS_TRACE_RCU
def_bool 0
select IRQ_WORK
help
This option enables a task-based RCU implementation that uses
explicit rcu_read_lock_trace() read-side markers, and allows
these readers to appear in the idle loop as well as on the CPU
hotplug code paths. It can force IPIs on online CPUs, including
idle ones, so use with caution.

So the solution is to further minimize your configuration so as to
deselect TASKS_TRACE_RCU. This means making sure that both BPF and
the various RCU torture tests are all deselected.

Or turn on IRQ_WORK, for example, if you need to use BPF.

Thanx, Paul

2022-03-17 20:18:10

by Paul E. McKenney

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
> On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> > On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> > > On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > > > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > > > Hello RCU folks,
> > > > >
> > > > > I like to use minimal configuration for kernel development.
> > > > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > > > >
> > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > >
> > > > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> > > >
> > > > Indeed it does!
> > > >
> > > > And kernel/rcu/Kconfig shows why:
> > > >
> > > > config TASKS_TRACE_RCU
> > > > def_bool 0
> > > > select IRQ_WORK
> > > > help
> > > > This option enables a task-based RCU implementation that uses
> > > > explicit rcu_read_lock_trace() read-side markers, and allows
> > > > these readers to appear in the idle loop as well as on the CPU
> > > > hotplug code paths. It can force IPIs on online CPUs, including
> > > > idle ones, so use with caution.
> > > >
> > > > So the solution is to further minimize your configuration so as to
> > > > deselect TASKS_TRACE_RCU.
> > >
> > > They are already not selected.
> >
> > Good, thank you.
> >
> > How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?
>
> TASKS_RUDE_RCU=n
> TASKS_TRACE_RCU=n
> TASKS_RCU_GENERIC=y
> TASKS_RCU=y
>
> > > > This means making sure that both BPF and
> > > > the various RCU torture tests are all deselected.
> > >
> > > I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> > > selected, making it fail to build.
> >
> > I am guessing because TASKS_RCU_GENERIC is selected?
> >
>
> Right.
>
> > If so, does the patch at the end of this email help?
> >
>
> No. did not help.
>
> I think I found reason...
> with PREEMPTION=y,
>
> in kernel/rcu/Kconfig:
> config TASKS_RCU
> def_bool PREEMPTION
> help
> This option enables a task-based RCU implementation that uses
> only voluntary context switch (not preemption!), idle, and
> user-mode execution as quiescent states. Not for manual selection.
>
> in kernel/rcu/Kconfig:
> config TASKS_RCU_GENERIC
> def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
> select SRCU
> help
> This option enables generic infrastructure code supporting
> task-based RCU implementations. Not for manual selection.

Ah, this is because some of the tracing code uses TASKS_RCU only
when PREEMPTION=y. That would be KPROBES and TRACING. Maybe also
TRACE_CLOCK and TRACEPOINTS, but I would hope that TRACING would
cover those. Adding the tracing guys for their thoughts.

> > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > >
> > > Isn't it better to fix this build failure?
> >
> > But of course! However, first I need to know exactly what is causing your
> > build failure. I cannot see your .config file, so I am having to guess.
> >
> > Don't get me wrong, I do have a lot of practice guessing, but it is still
> > just guessing. ;-)
>
> Sorry to make you guess. Maybe too late, but added config as attachment ;)

Perhaps I needed the practice. ;-)

> > > It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> > > and PREEMPT is selected.
> > >
> > > │ Symbol: TASKS_TRACE_RCU [=n] │
> > > │ Type : bool │
> > > │ Defined at kernel/rcu/Kconfig:96 │
> > > │ Selects: IRQ_WORK [=n] │
> > > │ Selected by [n]: │
> > > │ - BPF_SYSCALL [=n] │
> > > │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
> > >
> > > Thanks!
> > >
> > > >
> > > > Or turn on IRQ_WORK, for example, if you need to use BPF.
> >
> > Or do you already have TASKS_RCU_GENERIC deselected?
> >
>
> No, this is selected. TASKS_RCU_GENERIC=y. because of PREEMPTION=y.

OK, the patch shown below allows me to get TASKS_RCU_GENERIC=n even
with PREEMPTION=y. This might somehow subtly break tracing, but in
that case further adjustments can be made. Untested other than
generating a few .config combinations.

Thoughts?

Thanx, Paul

------------------------------------------------------------------------

diff --git a/arch/Kconfig b/arch/Kconfig
index 678a80713b21..66c5b5543511 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -38,6 +38,7 @@ config KPROBES
depends on MODULES
depends on HAVE_KPROBES
select KALLSYMS
+ select TASKS_RCU if PREEMPTION
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
index f559870fbf8b..4f665ae0cf55 100644
--- a/kernel/rcu/Kconfig
+++ b/kernel/rcu/Kconfig
@@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
task-based RCU implementations. Not for manual selection.

config TASKS_RCU
- def_bool PREEMPTION
+ def_bool 0
+ select IRQ_WORK
help
This option enables a task-based RCU implementation that uses
only voluntary context switch (not preemption!), idle, and
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 752ed89a293b..a7aaf150b704 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -127,6 +127,7 @@ config TRACING
select BINARY_PRINTF
select EVENT_TRACING
select TRACE_CLOCK
+ select TASKS_RCU if PREEMPTION

config GENERIC_TRACER
bool

2022-03-17 20:31:33

by Hyeonggon Yoo

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 11:22:28PM +0800, Zhouyi Zhou wrote:
> Hi,
>
> On Thu, Mar 17, 2022 at 8:48 PM Hyeonggon Yoo <[email protected]> wrote:
> >
> > Hello RCU folks,
> >
> > I like to use minimal configuration for kernel development.
> > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> I invoke cross compiler to reproduce the bug on my X86 machine
> $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> CC=aarch64-linux-gnu-gcc-10 tinyconfig
> let CONFIG_PREEMPT=y in .config
> $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> CC=aarch64-linux-gnu-gcc-10 -j 16
> LD vmlinux
> aarch64-linux-gnu-ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> update.c:(.text+0xb30): undefined reference to `irq_work_queue'
> update.c:(.text+0xb30): relocation truncated to fit: R_AARCH64_CALL26
> against undefined symbol `irq_work_queue'

Right. that was exactly what I faced :)

> >
> > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > make: *** [Makefile:1155: vmlinux] Error 1
> >
> > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> >
> > --
> > Thank you, You are awesome!
> > Hyeonggon :-)

> Meanwhile, there is no error for doing the same to build X86 kernel.
> I think the reason is:
> arch/x86/Kconfig select PERF_EVENT
> and PERF_EVENT select IRQ_WORK

Right. selecting anything that selects IRQ_WORK solves the problem.
Simply enabling printk also solves this.

> Hope my little research could provide some clues to solve the problem ;-)

Thank you for kind reply!

BTW, can we just fix this? (e.g. by conditionally compiling the problematic
code or always selecting IRQ_WORK)

> You are welcome
> Cheers
> Zhouyi

--
Thank you, You are awesome!
Hyeonggon :-)

2022-03-17 21:00:29

by Randy Dunlap

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue



On 3/17/22 10:36, Paul E. McKenney wrote:
> On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
>> On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
>>> On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
>>>> On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
>>>>> On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
>>>>>> Hello RCU folks,
>>>>>>

> ------------------------------------------------------------------------
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 678a80713b21..66c5b5543511 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -38,6 +38,7 @@ config KPROBES
> depends on MODULES
> depends on HAVE_KPROBES
> select KALLSYMS
> + select TASKS_RCU if PREEMPTION
> help
> Kprobes allows you to trap at almost any kernel address and
> execute a callback function. register_kprobe() establishes
> diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> index f559870fbf8b..4f665ae0cf55 100644
> --- a/kernel/rcu/Kconfig
> +++ b/kernel/rcu/Kconfig
> @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
> task-based RCU implementations. Not for manual selection.
>
> config TASKS_RCU
> - def_bool PREEMPTION
> + def_bool 0

preferably
def_bool n

but the 0 probably works... :)

> + select IRQ_WORK
> help
> This option enables a task-based RCU implementation that uses
> only voluntary context switch (not preemption!), idle, and
> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> index 752ed89a293b..a7aaf150b704 100644
> --- a/kernel/trace/Kconfig
> +++ b/kernel/trace/Kconfig
> @@ -127,6 +127,7 @@ config TRACING
> select BINARY_PRINTF
> select EVENT_TRACING
> select TRACE_CLOCK
> + select TASKS_RCU if PREEMPTION
>
> config GENERIC_TRACER
> bool

--
~Randy

2022-03-17 21:02:16

by Paul E. McKenney

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 01:26:45PM -0700, Randy Dunlap wrote:
>
>
> On 3/17/22 10:36, Paul E. McKenney wrote:
> > On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
> >> On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> >>> On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> >>>> On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> >>>>> On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> >>>>>> Hello RCU folks,
> >>>>>>
>
> > ------------------------------------------------------------------------
> >
> > diff --git a/arch/Kconfig b/arch/Kconfig
> > index 678a80713b21..66c5b5543511 100644
> > --- a/arch/Kconfig
> > +++ b/arch/Kconfig
> > @@ -38,6 +38,7 @@ config KPROBES
> > depends on MODULES
> > depends on HAVE_KPROBES
> > select KALLSYMS
> > + select TASKS_RCU if PREEMPTION
> > help
> > Kprobes allows you to trap at almost any kernel address and
> > execute a callback function. register_kprobe() establishes
> > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> > index f559870fbf8b..4f665ae0cf55 100644
> > --- a/kernel/rcu/Kconfig
> > +++ b/kernel/rcu/Kconfig
> > @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
> > task-based RCU implementations. Not for manual selection.
> >
> > config TASKS_RCU
> > - def_bool PREEMPTION
> > + def_bool 0
>
> preferably
> def_bool n
>
> but the 0 probably works... :)

In a later commit, it ends up like this:

config TASKS_TRACE_RCU
bool "Enable Tasks Trace RCU"
depends on RCU_EXPERT
default n
select IRQ_WORK
help
This option enables a task-based RCU implementation that uses
explicit rcu_read_lock_trace() read-side markers, and allows
these readers to appear in the idle loop as well as on the CPU
hotplug code paths. It can force IPIs on online CPUs, including
idle ones, so use with caution.

The reason being to allow people to use rcutorture without having
to have TASKS_TRACE_RCU enabled.

So you got your wish! I think... ;-)

Thanx, Paul

> > + select IRQ_WORK
> > help
> > This option enables a task-based RCU implementation that uses
> > only voluntary context switch (not preemption!), idle, and
> > diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> > index 752ed89a293b..a7aaf150b704 100644
> > --- a/kernel/trace/Kconfig
> > +++ b/kernel/trace/Kconfig
> > @@ -127,6 +127,7 @@ config TRACING
> > select BINARY_PRINTF
> > select EVENT_TRACING
> > select TRACE_CLOCK
> > + select TASKS_RCU if PREEMPTION
> >
> > config GENERIC_TRACER
> > bool
>
> --
> ~Randy

2022-03-17 21:03:32

by Randy Dunlap

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue



On 3/17/22 13:29, Paul E. McKenney wrote:
> On Thu, Mar 17, 2022 at 01:26:45PM -0700, Randy Dunlap wrote:
>>
>>
>> On 3/17/22 10:36, Paul E. McKenney wrote:
>>> On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
>>>> On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
>>>>> On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
>>>>>> On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
>>>>>>> On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
>>>>>>>> Hello RCU folks,
>>>>>>>>
>>
>>> ------------------------------------------------------------------------
>>>
>>> diff --git a/arch/Kconfig b/arch/Kconfig
>>> index 678a80713b21..66c5b5543511 100644
>>> --- a/arch/Kconfig
>>> +++ b/arch/Kconfig
>>> @@ -38,6 +38,7 @@ config KPROBES
>>> depends on MODULES
>>> depends on HAVE_KPROBES
>>> select KALLSYMS
>>> + select TASKS_RCU if PREEMPTION
>>> help
>>> Kprobes allows you to trap at almost any kernel address and
>>> execute a callback function. register_kprobe() establishes
>>> diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
>>> index f559870fbf8b..4f665ae0cf55 100644
>>> --- a/kernel/rcu/Kconfig
>>> +++ b/kernel/rcu/Kconfig
>>> @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
>>> task-based RCU implementations. Not for manual selection.
>>>
>>> config TASKS_RCU
>>> - def_bool PREEMPTION
>>> + def_bool 0
>>
>> preferably
>> def_bool n
>>
>> but the 0 probably works... :)
>
> In a later commit, it ends up like this:
>
> config TASKS_TRACE_RCU
> bool "Enable Tasks Trace RCU"
> depends on RCU_EXPERT
> default n
> select IRQ_WORK
> help
> This option enables a task-based RCU implementation that uses
> explicit rcu_read_lock_trace() read-side markers, and allows
> these readers to appear in the idle loop as well as on the CPU
> hotplug code paths. It can force IPIs on online CPUs, including
> idle ones, so use with caution.
>
> The reason being to allow people to use rcutorture without having
> to have TASKS_TRACE_RCU enabled.
>
> So you got your wish! I think... ;-)
>
> Thanx, Paul

Yeah, thanks.

>>> + select IRQ_WORK
>>> help
>>> This option enables a task-based RCU implementation that uses
>>> only voluntary context switch (not preemption!), idle, and
>>> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
>>> index 752ed89a293b..a7aaf150b704 100644
>>> --- a/kernel/trace/Kconfig
>>> +++ b/kernel/trace/Kconfig
>>> @@ -127,6 +127,7 @@ config TRACING
>>> select BINARY_PRINTF
>>> select EVENT_TRACING
>>> select TRACE_CLOCK
>>> + select TASKS_RCU if PREEMPTION
>>>
>>> config GENERIC_TRACER
>>> bool
>>
>> --
>> ~Randy

--
~Randy

2022-03-17 21:12:01

by Zhouyi Zhou

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

hi

On Fri, Mar 18, 2022 at 4:20 AM Paul E. McKenney <[email protected]> wrote:
>
> On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
> > On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> > > On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> > > > On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > > > > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > > > > Hello RCU folks,
> > > > > >
> > > > > > I like to use minimal configuration for kernel development.
> > > > > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > > > > >
> > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > > >
> > > > > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> > > > >
> > > > > Indeed it does!
> > > > >
> > > > > And kernel/rcu/Kconfig shows why:
> > > > >
> > > > > config TASKS_TRACE_RCU
> > > > > def_bool 0
> > > > > select IRQ_WORK
> > > > > help
> > > > > This option enables a task-based RCU implementation that uses
> > > > > explicit rcu_read_lock_trace() read-side markers, and allows
> > > > > these readers to appear in the idle loop as well as on the CPU
> > > > > hotplug code paths. It can force IPIs on online CPUs, including
> > > > > idle ones, so use with caution.
> > > > >
> > > > > So the solution is to further minimize your configuration so as to
> > > > > deselect TASKS_TRACE_RCU.
> > > >
> > > > They are already not selected.
> > >
> > > Good, thank you.
> > >
> > > How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?
> >
> > TASKS_RUDE_RCU=n
> > TASKS_TRACE_RCU=n
> > TASKS_RCU_GENERIC=y
> > TASKS_RCU=y
> >
> > > > > This means making sure that both BPF and
> > > > > the various RCU torture tests are all deselected.
> > > >
> > > > I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> > > > selected, making it fail to build.
> > >
> > > I am guessing because TASKS_RCU_GENERIC is selected?
> > >
> >
> > Right.
> >
> > > If so, does the patch at the end of this email help?
> > >
> >
> > No. did not help.
> >
> > I think I found reason...
> > with PREEMPTION=y,
> >
> > in kernel/rcu/Kconfig:
> > config TASKS_RCU
> > def_bool PREEMPTION
> > help
> > This option enables a task-based RCU implementation that uses
> > only voluntary context switch (not preemption!), idle, and
> > user-mode execution as quiescent states. Not for manual selection.
> >
> > in kernel/rcu/Kconfig:
> > config TASKS_RCU_GENERIC
> > def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
> > select SRCU
> > help
> > This option enables generic infrastructure code supporting
> > task-based RCU implementations. Not for manual selection.
>
> Ah, this is because some of the tracing code uses TASKS_RCU only
> when PREEMPTION=y. That would be KPROBES and TRACING. Maybe also
> TRACE_CLOCK and TRACEPOINTS, but I would hope that TRACING would
> cover those. Adding the tracing guys for their thoughts.
>
> > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > >
> > > > Isn't it better to fix this build failure?
> > >
> > > But of course! However, first I need to know exactly what is causing your
> > > build failure. I cannot see your .config file, so I am having to guess.
> > >
> > > Don't get me wrong, I do have a lot of practice guessing, but it is still
> > > just guessing. ;-)
> >
> > Sorry to make you guess. Maybe too late, but added config as attachment ;)
>
> Perhaps I needed the practice. ;-)
>
> > > > It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> > > > and PREEMPT is selected.
> > > >
> > > > │ Symbol: TASKS_TRACE_RCU [=n] │
> > > > │ Type : bool │
> > > > │ Defined at kernel/rcu/Kconfig:96 │
> > > > │ Selects: IRQ_WORK [=n] │
> > > > │ Selected by [n]: │
> > > > │ - BPF_SYSCALL [=n] │
> > > > │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
> > > >
> > > > Thanks!
> > > >
> > > > >
> > > > > Or turn on IRQ_WORK, for example, if you need to use BPF.
> > >
> > > Or do you already have TASKS_RCU_GENERIC deselected?
> > >
> >
> > No, this is selected. TASKS_RCU_GENERIC=y. because of PREEMPTION=y.
>
> OK, the patch shown below allows me to get TASKS_RCU_GENERIC=n even
> with PREEMPTION=y. This might somehow subtly break tracing, but in
> that case further adjustments can be made. Untested other than
> generating a few .config combinations.
>
> Thoughts?
>
> Thanx, Paul
>
> ------------------------------------------------------------------------
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 678a80713b21..66c5b5543511 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -38,6 +38,7 @@ config KPROBES
> depends on MODULES
> depends on HAVE_KPROBES
> select KALLSYMS
> + select TASKS_RCU if PREEMPTION
> help
> Kprobes allows you to trap at almost any kernel address and
> execute a callback function. register_kprobe() establishes
> diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> index f559870fbf8b..4f665ae0cf55 100644
> --- a/kernel/rcu/Kconfig
> +++ b/kernel/rcu/Kconfig
> @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
> task-based RCU implementations. Not for manual selection.
>
> config TASKS_RCU
> - def_bool PREEMPTION
> + def_bool 0
> + select IRQ_WORK
> help
> This option enables a task-based RCU implementation that uses
> only voluntary context switch (not preemption!), idle, and
> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> index 752ed89a293b..a7aaf150b704 100644
> --- a/kernel/trace/Kconfig
> +++ b/kernel/trace/Kconfig
> @@ -127,6 +127,7 @@ config TRACING
> select BINARY_PRINTF
> select EVENT_TRACING
> select TRACE_CLOCK
> + select TASKS_RCU if PREEMPTION
>
> config GENERIC_TRACER
> bool
I apply above patch, and invoke
$make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
CC=aarch64-linux-gnu-gcc-10 tinyconfig
$make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
CC=aarch64-linux-gnu-gcc-10 -j 16
kernel build successful this time (without above patch, kernel build
will quit with undefined reference to `irq_work_queue'
Tested-by: Zhouyi Zhou<[email protected]>

Thanks
Zhouyi

2022-03-17 21:21:47

by Paul E. McKenney

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Fri, Mar 18, 2022 at 04:41:59AM +0800, Zhouyi Zhou wrote:
> hi
>
> On Fri, Mar 18, 2022 at 4:20 AM Paul E. McKenney <[email protected]> wrote:
> >
> > On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
> > > On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> > > > On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> > > > > On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > > > > > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > > > > > Hello RCU folks,
> > > > > > >
> > > > > > > I like to use minimal configuration for kernel development.
> > > > > > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > > > > > >
> > > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > > > >
> > > > > > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> > > > > >
> > > > > > Indeed it does!
> > > > > >
> > > > > > And kernel/rcu/Kconfig shows why:
> > > > > >
> > > > > > config TASKS_TRACE_RCU
> > > > > > def_bool 0
> > > > > > select IRQ_WORK
> > > > > > help
> > > > > > This option enables a task-based RCU implementation that uses
> > > > > > explicit rcu_read_lock_trace() read-side markers, and allows
> > > > > > these readers to appear in the idle loop as well as on the CPU
> > > > > > hotplug code paths. It can force IPIs on online CPUs, including
> > > > > > idle ones, so use with caution.
> > > > > >
> > > > > > So the solution is to further minimize your configuration so as to
> > > > > > deselect TASKS_TRACE_RCU.
> > > > >
> > > > > They are already not selected.
> > > >
> > > > Good, thank you.
> > > >
> > > > How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?
> > >
> > > TASKS_RUDE_RCU=n
> > > TASKS_TRACE_RCU=n
> > > TASKS_RCU_GENERIC=y
> > > TASKS_RCU=y
> > >
> > > > > > This means making sure that both BPF and
> > > > > > the various RCU torture tests are all deselected.
> > > > >
> > > > > I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> > > > > selected, making it fail to build.
> > > >
> > > > I am guessing because TASKS_RCU_GENERIC is selected?
> > > >
> > >
> > > Right.
> > >
> > > > If so, does the patch at the end of this email help?
> > > >
> > >
> > > No. did not help.
> > >
> > > I think I found reason...
> > > with PREEMPTION=y,
> > >
> > > in kernel/rcu/Kconfig:
> > > config TASKS_RCU
> > > def_bool PREEMPTION
> > > help
> > > This option enables a task-based RCU implementation that uses
> > > only voluntary context switch (not preemption!), idle, and
> > > user-mode execution as quiescent states. Not for manual selection.
> > >
> > > in kernel/rcu/Kconfig:
> > > config TASKS_RCU_GENERIC
> > > def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
> > > select SRCU
> > > help
> > > This option enables generic infrastructure code supporting
> > > task-based RCU implementations. Not for manual selection.
> >
> > Ah, this is because some of the tracing code uses TASKS_RCU only
> > when PREEMPTION=y. That would be KPROBES and TRACING. Maybe also
> > TRACE_CLOCK and TRACEPOINTS, but I would hope that TRACING would
> > cover those. Adding the tracing guys for their thoughts.
> >
> > > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > >
> > > > > Isn't it better to fix this build failure?
> > > >
> > > > But of course! However, first I need to know exactly what is causing your
> > > > build failure. I cannot see your .config file, so I am having to guess.
> > > >
> > > > Don't get me wrong, I do have a lot of practice guessing, but it is still
> > > > just guessing. ;-)
> > >
> > > Sorry to make you guess. Maybe too late, but added config as attachment ;)
> >
> > Perhaps I needed the practice. ;-)
> >
> > > > > It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> > > > > and PREEMPT is selected.
> > > > >
> > > > > │ Symbol: TASKS_TRACE_RCU [=n] │
> > > > > │ Type : bool │
> > > > > │ Defined at kernel/rcu/Kconfig:96 │
> > > > > │ Selects: IRQ_WORK [=n] │
> > > > > │ Selected by [n]: │
> > > > > │ - BPF_SYSCALL [=n] │
> > > > > │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > > │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > > │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
> > > > >
> > > > > Thanks!
> > > > >
> > > > > >
> > > > > > Or turn on IRQ_WORK, for example, if you need to use BPF.
> > > >
> > > > Or do you already have TASKS_RCU_GENERIC deselected?
> > > >
> > >
> > > No, this is selected. TASKS_RCU_GENERIC=y. because of PREEMPTION=y.
> >
> > OK, the patch shown below allows me to get TASKS_RCU_GENERIC=n even
> > with PREEMPTION=y. This might somehow subtly break tracing, but in
> > that case further adjustments can be made. Untested other than
> > generating a few .config combinations.
> >
> > Thoughts?
> >
> > Thanx, Paul
> >
> > ------------------------------------------------------------------------
> >
> > diff --git a/arch/Kconfig b/arch/Kconfig
> > index 678a80713b21..66c5b5543511 100644
> > --- a/arch/Kconfig
> > +++ b/arch/Kconfig
> > @@ -38,6 +38,7 @@ config KPROBES
> > depends on MODULES
> > depends on HAVE_KPROBES
> > select KALLSYMS
> > + select TASKS_RCU if PREEMPTION
> > help
> > Kprobes allows you to trap at almost any kernel address and
> > execute a callback function. register_kprobe() establishes
> > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> > index f559870fbf8b..4f665ae0cf55 100644
> > --- a/kernel/rcu/Kconfig
> > +++ b/kernel/rcu/Kconfig
> > @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
> > task-based RCU implementations. Not for manual selection.
> >
> > config TASKS_RCU
> > - def_bool PREEMPTION
> > + def_bool 0
> > + select IRQ_WORK
> > help
> > This option enables a task-based RCU implementation that uses
> > only voluntary context switch (not preemption!), idle, and
> > diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> > index 752ed89a293b..a7aaf150b704 100644
> > --- a/kernel/trace/Kconfig
> > +++ b/kernel/trace/Kconfig
> > @@ -127,6 +127,7 @@ config TRACING
> > select BINARY_PRINTF
> > select EVENT_TRACING
> > select TRACE_CLOCK
> > + select TASKS_RCU if PREEMPTION
> >
> > config GENERIC_TRACER
> > bool
> I apply above patch, and invoke
> $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> CC=aarch64-linux-gnu-gcc-10 tinyconfig
> $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> CC=aarch64-linux-gnu-gcc-10 -j 16
> kernel build successful this time (without above patch, kernel build
> will quit with undefined reference to `irq_work_queue'
> Tested-by: Zhouyi Zhou<[email protected]>

I will apply on my next rebase, thank you!

Thanx, Paul

2022-03-19 20:15:08

by Hyeonggon Yoo

[permalink] [raw]
Subject: Re: RCU: undefined reference to irq_work_queue

On Thu, Mar 17, 2022 at 01:53:39PM -0700, Paul E. McKenney wrote:
> On Fri, Mar 18, 2022 at 04:41:59AM +0800, Zhouyi Zhou wrote:
> > hi
> >
> > On Fri, Mar 18, 2022 at 4:20 AM Paul E. McKenney <[email protected]> wrote:
> > >
> > > On Thu, Mar 17, 2022 at 04:45:11PM +0000, Hyeonggon Yoo wrote:
> > > > On Thu, Mar 17, 2022 at 09:20:33AM -0700, Paul E. McKenney wrote:
> > > > > On Thu, Mar 17, 2022 at 03:24:42PM +0000, Hyeonggon Yoo wrote:
> > > > > > On Thu, Mar 17, 2022 at 07:00:00AM -0700, Paul E. McKenney wrote:
> > > > > > > On Thu, Mar 17, 2022 at 11:32:53AM +0000, Hyeonggon Yoo wrote:
> > > > > > > > Hello RCU folks,
> > > > > > > >
> > > > > > > > I like to use minimal configuration for kernel development.
> > > > > > > > when building with tinyconfig + CONFIG_PREEMPT=y on arm64:
> > > > > > > >
> > > > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > > > > >
> > > > > > > > It seems RCU calls irq_work_queue() without checking if CONFIG_IRQ_WORK is enabled.
> > > > > > >
> > > > > > > Indeed it does!
> > > > > > >
> > > > > > > And kernel/rcu/Kconfig shows why:
> > > > > > >
> > > > > > > config TASKS_TRACE_RCU
> > > > > > > def_bool 0
> > > > > > > select IRQ_WORK
> > > > > > > help
> > > > > > > This option enables a task-based RCU implementation that uses
> > > > > > > explicit rcu_read_lock_trace() read-side markers, and allows
> > > > > > > these readers to appear in the idle loop as well as on the CPU
> > > > > > > hotplug code paths. It can force IPIs on online CPUs, including
> > > > > > > idle ones, so use with caution.
> > > > > > >
> > > > > > > So the solution is to further minimize your configuration so as to
> > > > > > > deselect TASKS_TRACE_RCU.
> > > > > >
> > > > > > They are already not selected.
> > > > >
> > > > > Good, thank you.
> > > > >
> > > > > How about TASKS_RUDE_RCU, TASKS_TRACE_RCU, and TASKS_RCU_GENERIC?
> > > >
> > > > TASKS_RUDE_RCU=n
> > > > TASKS_TRACE_RCU=n
> > > > TASKS_RCU_GENERIC=y
> > > > TASKS_RCU=y
> > > >
> > > > > > > This means making sure that both BPF and
> > > > > > > the various RCU torture tests are all deselected.
> > > > > >
> > > > > > I wanted to say call_rcu_tasks() can be referenced even when IRQ_WORK is not
> > > > > > selected, making it fail to build.
> > > > >
> > > > > I am guessing because TASKS_RCU_GENERIC is selected?
> > > > >
> > > >
> > > > Right.
> > > >
> > > > > If so, does the patch at the end of this email help?
> > > > >
> > > >
> > > > No. did not help.
> > > >
> > > > I think I found reason...
> > > > with PREEMPTION=y,
> > > >
> > > > in kernel/rcu/Kconfig:
> > > > config TASKS_RCU
> > > > def_bool PREEMPTION
> > > > help
> > > > This option enables a task-based RCU implementation that uses
> > > > only voluntary context switch (not preemption!), idle, and
> > > > user-mode execution as quiescent states. Not for manual selection.
> > > >
> > > > in kernel/rcu/Kconfig:
> > > > config TASKS_RCU_GENERIC
> > > > def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
> > > > select SRCU
> > > > help
> > > > This option enables generic infrastructure code supporting
> > > > task-based RCU implementations. Not for manual selection.
> > >
> > > Ah, this is because some of the tracing code uses TASKS_RCU only
> > > when PREEMPTION=y. That would be KPROBES and TRACING. Maybe also
> > > TRACE_CLOCK and TRACEPOINTS, but I would hope that TRACING would
> > > cover those. Adding the tracing guys for their thoughts.
> > >
> > > > > > > > ld: kernel/rcu/update.o: in function `call_rcu_tasks':
> > > > > > > > update.c:(.text+0xb2c): undefined reference to `irq_work_queue'
> > > > > > > > update.c:(.text+0xb2c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `irq_work_queue'
> > > > > > > > make: *** [Makefile:1155: vmlinux] Error 1
> > > > > >
> > > > > > Isn't it better to fix this build failure?
> > > > >
> > > > > But of course! However, first I need to know exactly what is causing your
> > > > > build failure. I cannot see your .config file, so I am having to guess.
> > > > >
> > > > > Don't get me wrong, I do have a lot of practice guessing, but it is still
> > > > > just guessing. ;-)
> > > >
> > > > Sorry to make you guess. Maybe too late, but added config as attachment ;)
> > >
> > > Perhaps I needed the practice. ;-)
> > >
> > > > > > It fails to build when both TASKS_TRACE_RCU and IRQ_WORK are not selected
> > > > > > and PREEMPT is selected.
> > > > > >
> > > > > > │ Symbol: TASKS_TRACE_RCU [=n] │
> > > > > > │ Type : bool │
> > > > > > │ Defined at kernel/rcu/Kconfig:96 │
> > > > > > │ Selects: IRQ_WORK [=n] │
> > > > > > │ Selected by [n]: │
> > > > > > │ - BPF_SYSCALL [=n] │
> > > > > > │ - RCU_SCALE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > > > │ - RCU_TORTURE_TEST [=n] && DEBUG_KERNEL [=y] │
> > > > > > │ - RCU_REF_SCALE_TEST [=n] && DEBUG_KERNEL [=y]
> > > > > >
> > > > > > Thanks!
> > > > > >
> > > > > > >
> > > > > > > Or turn on IRQ_WORK, for example, if you need to use BPF.
> > > > >
> > > > > Or do you already have TASKS_RCU_GENERIC deselected?
> > > > >
> > > >
> > > > No, this is selected. TASKS_RCU_GENERIC=y. because of PREEMPTION=y.
> > >
> > > OK, the patch shown below allows me to get TASKS_RCU_GENERIC=n even
> > > with PREEMPTION=y. This might somehow subtly break tracing, but in
> > > that case further adjustments can be made. Untested other than
> > > generating a few .config combinations.
> > >
> > > Thoughts?
> > >
> > > Thanx, Paul
> > >
> > > ------------------------------------------------------------------------
> > >
> > > diff --git a/arch/Kconfig b/arch/Kconfig
> > > index 678a80713b21..66c5b5543511 100644
> > > --- a/arch/Kconfig
> > > +++ b/arch/Kconfig
> > > @@ -38,6 +38,7 @@ config KPROBES
> > > depends on MODULES
> > > depends on HAVE_KPROBES
> > > select KALLSYMS
> > > + select TASKS_RCU if PREEMPTION
> > > help
> > > Kprobes allows you to trap at almost any kernel address and
> > > execute a callback function. register_kprobe() establishes
> > > diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
> > > index f559870fbf8b..4f665ae0cf55 100644
> > > --- a/kernel/rcu/Kconfig
> > > +++ b/kernel/rcu/Kconfig
> > > @@ -78,7 +78,8 @@ config TASKS_RCU_GENERIC
> > > task-based RCU implementations. Not for manual selection.
> > >
> > > config TASKS_RCU
> > > - def_bool PREEMPTION
> > > + def_bool 0
> > > + select IRQ_WORK
> > > help
> > > This option enables a task-based RCU implementation that uses
> > > only voluntary context switch (not preemption!), idle, and
> > > diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> > > index 752ed89a293b..a7aaf150b704 100644
> > > --- a/kernel/trace/Kconfig
> > > +++ b/kernel/trace/Kconfig
> > > @@ -127,6 +127,7 @@ config TRACING
> > > select BINARY_PRINTF
> > > select EVENT_TRACING
> > > select TRACE_CLOCK
> > > + select TASKS_RCU if PREEMPTION
> > >
> > > config GENERIC_TRACER
> > > bool
> > I apply above patch, and invoke
> > $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> > CC=aarch64-linux-gnu-gcc-10 tinyconfig
> > $make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
> > CC=aarch64-linux-gnu-gcc-10 -j 16
> > kernel build successful this time (without above patch, kernel build
> > will quit with undefined reference to `irq_work_queue'
> > Tested-by: Zhouyi Zhou<[email protected]>
>
> I will apply on my next rebase, thank you!
>

Works for configurations I use.

Reported-and-tested-by: Hyeonggon Yoo <[email protected]>

Thanks!

> Thanx, Paul

--
Thank you, You are awesome!
Hyeonggon :-)