Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753052AbdCNCBN (ORCPT ); Mon, 13 Mar 2017 22:01:13 -0400 Received: from mail.windriver.com ([147.11.1.11]:41010 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751072AbdCNCBM (ORCPT ); Mon, 13 Mar 2017 22:01:12 -0400 From: Qi Hou To: , , CC: , , , Subject: [PATCH] lockdep: call time_hardirqs_off after clearing hardirqs_enabled Date: Tue, 14 Mar 2017 10:00:07 +0800 Message-ID: <1489456807-160132-1-git-send-email-qi.hou@windriver.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [128.224.153.75] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2306 Lines: 69 The current order of calls within trace_hardirqs_off_caller() would provoke an "unannotated irqs-off" WARNING. This warning was reported by check_flags() when it found that the hardirqs has been disabled but the irq-flags state, "hardirqs_enabled", has not been cleared. Check_flags() is called via trace_hardirqs_off(), and trace_hardirqs_off() will be called by functions kind of local_irq_disable() if CONFIG_TRACE_IRQFLAGS has been enabled. The calltrace from functions kind of local_irq_diasble() to check_flags() simplied as below: local_irq_disable() |- trace_hardirqs_off() |- trace_hardirqs_off_caller() |- time_hardirqs_off() |- trace_preemptirqsoff_hist_rcuidle() |- __DO_TRACE() |- rcu_dereference_sched() |- rcu_read_lock_sched_held() |- lock_is_held() |- check_flags() The order of calls within trace_hardirqs_off_caller() simplified as below: local_irq_disable() |- raw_local_irq_disable() |- trace_hardirqs_off() |- trace_hardirqs_off_caller() |- time_hardirqs_off() --> check_flags() |- hardirqs_enabled = 0 We could find that the call to check_flags() has been made between disabling hardirqs and clearing hardirqs_enabled. That will definitely cause an "unannotated irqs-off" warning. To fix this "unannotated irqs-off" warning, we must call time_hardirqs_off() after that we clear hardirqs_enabled. Signed-off-by: Qi Hou --- kernel/locking/lockdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 577f026..e8b35e4 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -2627,8 +2627,6 @@ __visible void trace_hardirqs_off_caller(unsigned long ip) { struct task_struct *curr = current; - time_hardirqs_off(CALLER_ADDR0, ip); - if (unlikely(!debug_locks || current->lockdep_recursion)) return; @@ -2649,6 +2647,8 @@ __visible void trace_hardirqs_off_caller(unsigned long ip) debug_atomic_inc(hardirqs_off_events); } else debug_atomic_inc(redundant_hardirqs_off); + + time_hardirqs_off(CALLER_ADDR0, ip); } EXPORT_SYMBOL(trace_hardirqs_off_caller); -- 1.9.1