Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tracing/user_events: Remove RCU lock while pinning pages

pin_user_pages_remote() can reschedule which means we cannot hold any
RCU lock while using it. Now that enablers are not exposed out to the
tracing register callbacks during fork(), there is clearly no need to
require the RCU lock as event_mutex is enough to protect changes.

Remove unneeded RCU usages when pinning pages and walking enablers with
event_mutex held. Cleanup a misleading "safe" list walk that is not
needed. During fork() duplication, remove unneeded RCU list add, since
the list is not exposed yet.

Link: https://lkml.kernel.org/r/20230519230741.669-3-beaub@linux.microsoft.com
Link: https://lore.kernel.org/linux-trace-kernel/CAHk-=wiiBfT4zNS29jA0XEsy8EmbqTH1hAPdRJCDAJMD8Gxt5A@mail.gmail.com/

Fixes: 7235759084a4 ("tracing/user_events: Use remote writes for event enablement")
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[ change log written by Beau Belgrave ]
Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Linus Torvalds and committed by
Steven Rostedt (Google)
aaecdaf9 3e0fea09

+7 -6
+7 -6
kernel/trace/trace_events_user.c
··· 439 439 unsigned long uaddr, unsigned char bit) 440 440 { 441 441 struct user_event_enabler *enabler; 442 - struct user_event_enabler *next; 443 442 444 - list_for_each_entry_safe(enabler, next, &mm->enablers, link) { 443 + list_for_each_entry(enabler, &mm->enablers, link) { 445 444 if (enabler->addr == uaddr && ENABLE_BIT(enabler) == bit) 446 445 return true; 447 446 } ··· 455 456 struct user_event_mm *next; 456 457 int attempt; 457 458 459 + lockdep_assert_held(&event_mutex); 460 + 458 461 while (mm) { 459 462 next = mm->next; 460 463 mmap_read_lock(mm->mm); 461 - rcu_read_lock(); 462 464 463 - list_for_each_entry_rcu(enabler, &mm->enablers, link) { 465 + list_for_each_entry(enabler, &mm->enablers, link) { 464 466 if (enabler->event == user) { 465 467 attempt = 0; 466 468 user_event_enabler_write(mm, enabler, true, &attempt); 467 469 } 468 470 } 469 471 470 - rcu_read_unlock(); 471 472 mmap_read_unlock(mm->mm); 472 473 user_event_mm_put(mm); 473 474 mm = next; ··· 495 496 enabler->values = orig->values & ENABLE_VAL_DUP_MASK; 496 497 497 498 refcount_inc(&enabler->event->refcnt); 498 - list_add_rcu(&enabler->link, &mm->enablers); 499 + 500 + /* Enablers not exposed yet, RCU not required */ 501 + list_add(&enabler->link, &mm->enablers); 499 502 500 503 return true; 501 504 }