* [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup
@ 2020-01-15 3:40 Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 1/2] kprobes: Suppress the suspicious RCU warning on kprobes Masami Hiramatsu
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Masami Hiramatsu @ 2020-01-15 3:40 UTC (permalink / raw)
To: Ingo Molnar
Cc: Anders Roxell, paulmck, joel, Naveen N . Rao,
Anil S Keshavamurthy, David Miller, Masami Hiramatsu,
Linux Kernel Mailing List
Hi,
Here is v3 patches which fix suspicious RCU usage warnings
in kprobes. In this version I just updated the series on top
of the latest -tip and add Joel's reviewed-by tag.
Thank you,
---
Masami Hiramatsu (2):
kprobes: Suppress the suspicious RCU warning on kprobes
kprobes: Use non RCU traversal APIs on kprobe_tables if possible
kernel/kprobes.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
--
Masami Hiramatsu (Linaro) <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH -tip V3 1/2] kprobes: Suppress the suspicious RCU warning on kprobes
2020-01-15 3:40 [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
@ 2020-01-15 3:40 ` Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 2/2] kprobes: Use non RCU traversal APIs on kprobe_tables if possible Masami Hiramatsu
2020-01-31 6:43 ` [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
2 siblings, 0 replies; 4+ messages in thread
From: Masami Hiramatsu @ 2020-01-15 3:40 UTC (permalink / raw)
To: Ingo Molnar
Cc: Anders Roxell, paulmck, joel, Naveen N . Rao,
Anil S Keshavamurthy, David Miller, Masami Hiramatsu,
Linux Kernel Mailing List
Anders reported that the lockdep warns that suspicious
RCU list usage in register_kprobe() (detected by
CONFIG_PROVE_RCU_LIST.) This is because get_kprobe()
access kprobe_table[] by hlist_for_each_entry_rcu()
without rcu_read_lock.
If we call get_kprobe() from the breakpoint handler context,
it is run with preempt disabled, so this is not a problem.
But in other cases, instead of rcu_read_lock(), we locks
kprobe_mutex so that the kprobe_table[] is not updated.
So, current code is safe, but still not good from the view
point of RCU.
Joel suggested that we can silent that warning by passing
lockdep_is_held() to the last argument of
hlist_for_each_entry_rcu().
Add lockdep_is_held(&kprobe_mutex) at the end of the
hlist_for_each_entry_rcu() to suppress the warning.
Reported-by: Anders Roxell <anders.roxell@linaro.org>
Suggested-by: Joel Fernandes <joel@joelfernandes.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
---
kernel/kprobes.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2625c241ac00..bd484392d789 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -326,7 +326,8 @@ struct kprobe *get_kprobe(void *addr)
struct kprobe *p;
head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
- hlist_for_each_entry_rcu(p, head, hlist) {
+ hlist_for_each_entry_rcu(p, head, hlist,
+ lockdep_is_held(&kprobe_mutex)) {
if (p->addr == addr)
return p;
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH -tip V3 2/2] kprobes: Use non RCU traversal APIs on kprobe_tables if possible
2020-01-15 3:40 [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 1/2] kprobes: Suppress the suspicious RCU warning on kprobes Masami Hiramatsu
@ 2020-01-15 3:40 ` Masami Hiramatsu
2020-01-31 6:43 ` [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
2 siblings, 0 replies; 4+ messages in thread
From: Masami Hiramatsu @ 2020-01-15 3:40 UTC (permalink / raw)
To: Ingo Molnar
Cc: Anders Roxell, paulmck, joel, Naveen N . Rao,
Anil S Keshavamurthy, David Miller, Masami Hiramatsu,
Linux Kernel Mailing List
Current kprobes uses RCU traversal APIs on kprobe_tables
even if it is safe because kprobe_mutex is locked.
Make those traversals to non-RCU APIs where the kprobe_mutex
is locked.
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
---
kernel/kprobes.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index bd484392d789..38d9a5d7c8a4 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -46,6 +46,11 @@
static int kprobes_initialized;
+/* kprobe_table can be accessed by
+ * - Normal hlist traversal and RCU add/del under kprobe_mutex is held.
+ * Or
+ * - RCU hlist traversal under disabling preempt (breakpoint handlers)
+ */
static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
@@ -850,7 +855,7 @@ static void optimize_all_kprobes(void)
kprobes_allow_optimization = true;
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
- hlist_for_each_entry_rcu(p, head, hlist)
+ hlist_for_each_entry(p, head, hlist)
if (!kprobe_disabled(p))
optimize_kprobe(p);
}
@@ -877,7 +882,7 @@ static void unoptimize_all_kprobes(void)
kprobes_allow_optimization = false;
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
- hlist_for_each_entry_rcu(p, head, hlist) {
+ hlist_for_each_entry(p, head, hlist) {
if (!kprobe_disabled(p))
unoptimize_kprobe(p, false);
}
@@ -1500,12 +1505,14 @@ static struct kprobe *__get_valid_kprobe(struct kprobe *p)
{
struct kprobe *ap, *list_p;
+ lockdep_assert_held(&kprobe_mutex);
+
ap = get_kprobe(p->addr);
if (unlikely(!ap))
return NULL;
if (p != ap) {
- list_for_each_entry_rcu(list_p, &ap->list, list)
+ list_for_each_entry(list_p, &ap->list, list)
if (list_p == p)
/* kprobe p is a valid probe */
goto valid;
@@ -1670,7 +1677,9 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
{
struct kprobe *kp;
- list_for_each_entry_rcu(kp, &ap->list, list)
+ lockdep_assert_held(&kprobe_mutex);
+
+ list_for_each_entry(kp, &ap->list, list)
if (!kprobe_disabled(kp))
/*
* There is an active probe on the list.
@@ -1749,7 +1758,7 @@ static int __unregister_kprobe_top(struct kprobe *p)
else {
/* If disabling probe has special handlers, update aggrprobe */
if (p->post_handler && !kprobe_gone(p)) {
- list_for_each_entry_rcu(list_p, &ap->list, list) {
+ list_for_each_entry(list_p, &ap->list, list) {
if ((list_p != p) && (list_p->post_handler))
goto noclean;
}
@@ -2063,13 +2072,15 @@ static void kill_kprobe(struct kprobe *p)
{
struct kprobe *kp;
+ lockdep_assert_held(&kprobe_mutex);
+
p->flags |= KPROBE_FLAG_GONE;
if (kprobe_aggrprobe(p)) {
/*
* If this is an aggr_kprobe, we have to list all the
* chained probes and mark them GONE.
*/
- list_for_each_entry_rcu(kp, &p->list, list)
+ list_for_each_entry(kp, &p->list, list)
kp->flags |= KPROBE_FLAG_GONE;
p->post_handler = NULL;
kill_optimized_kprobe(p);
@@ -2238,7 +2249,7 @@ static int kprobes_module_callback(struct notifier_block *nb,
mutex_lock(&kprobe_mutex);
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
- hlist_for_each_entry_rcu(p, head, hlist)
+ hlist_for_each_entry(p, head, hlist)
if (within_module_init((unsigned long)p->addr, mod) ||
(checkcore &&
within_module_core((unsigned long)p->addr, mod))) {
@@ -2489,7 +2500,7 @@ static int arm_all_kprobes(void)
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
/* Arm all kprobes on a best-effort basis */
- hlist_for_each_entry_rcu(p, head, hlist) {
+ hlist_for_each_entry(p, head, hlist) {
if (!kprobe_disabled(p)) {
err = arm_kprobe(p);
if (err) {
@@ -2532,7 +2543,7 @@ static int disarm_all_kprobes(void)
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
/* Disarm all kprobes on a best-effort basis */
- hlist_for_each_entry_rcu(p, head, hlist) {
+ hlist_for_each_entry(p, head, hlist) {
if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
err = disarm_kprobe(p, false);
if (err) {
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup
2020-01-15 3:40 [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 1/2] kprobes: Suppress the suspicious RCU warning on kprobes Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 2/2] kprobes: Use non RCU traversal APIs on kprobe_tables if possible Masami Hiramatsu
@ 2020-01-31 6:43 ` Masami Hiramatsu
2 siblings, 0 replies; 4+ messages in thread
From: Masami Hiramatsu @ 2020-01-31 6:43 UTC (permalink / raw)
To: Ingo Molnar
Cc: Ingo Molnar, Masami Hiramatsu, Anders Roxell, paulmck, joel,
Naveen N . Rao, Anil S Keshavamurthy, David Miller,
Linux Kernel Mailing List
Hi Ingo,
Could you pick these patches for fixing RCU warnings by
CONFIG_PROVE_RCU_LIST?
Thank you,
On Wed, 15 Jan 2020 12:40:35 +0900
Masami Hiramatsu <mhiramat@kernel.org> wrote:
> Hi,
>
> Here is v3 patches which fix suspicious RCU usage warnings
> in kprobes. In this version I just updated the series on top
> of the latest -tip and add Joel's reviewed-by tag.
>
> Thank you,
>
> ---
>
> Masami Hiramatsu (2):
> kprobes: Suppress the suspicious RCU warning on kprobes
> kprobes: Use non RCU traversal APIs on kprobe_tables if possible
>
>
> kernel/kprobes.c | 32 ++++++++++++++++++++++----------
> 1 file changed, 22 insertions(+), 10 deletions(-)
>
> --
> Masami Hiramatsu (Linaro) <mhiramat@kernel.org>
--
Masami Hiramatsu <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-01-31 6:43 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-15 3:40 [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 1/2] kprobes: Suppress the suspicious RCU warning on kprobes Masami Hiramatsu
2020-01-15 3:40 ` [PATCH -tip V3 2/2] kprobes: Use non RCU traversal APIs on kprobe_tables if possible Masami Hiramatsu
2020-01-31 6:43 ` [PATCH -tip V3 0/2] kprobes: Fix RCU warning and cleanup Masami Hiramatsu
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.