read_file_mod_stats() dumps dup_failed_modules while holding module_mutex, but the loop uses list_for_each_entry_rcu() without telling lockdep about that non-RCU protection.
The same list is already traversed in try_add_failed_module() with lockdep_is_held(&module_mutex) as the RCU-list lockdep condition. Use the same condition for the debugfs stats dump so CONFIG_PROVE_RCU_LIST can see the documented protection. This was found by our static analysis tool and then manually reviewed against the current tree. The dynamic triage evidence is a target-matched CONFIG_PROVE_RCU_LIST warning; the change is limited to documenting the existing protection contract. This is a lockdep annotation cleanup. It does not change the list lifetime or serialization rules. Signed-off-by: Runyu Xiao <[email protected]> --- kernel/module/stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/module/stats.c b/kernel/module/stats.c index 3ba0e98b3c91..79c227a72a21 100644 --- a/kernel/module/stats.c +++ b/kernel/module/stats.c @@ -382,7 +382,8 @@ static ssize_t read_file_mod_stats(struct file *file, char __user *user_buf, mutex_lock(&module_mutex); - list_for_each_entry_rcu(mod_fail, &dup_failed_modules, list) { + list_for_each_entry_rcu(mod_fail, &dup_failed_modules, list, + lockdep_is_held(&module_mutex)) { if (WARN_ON_ONCE(++count_failed >= MAX_FAILED_MOD_PRINT)) goto out_unlock; len += scnprintf(buf + len, size - len, "%25s\t%15lu\t%25s\n", mod_fail->name, -- 2.34.1

