All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.