From patchwork Mon Jan 13 19:03:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qian Cai X-Patchwork-Id: 11330773 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C3B1109A for ; Mon, 13 Jan 2020 19:03:58 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 2A88121556 for ; Mon, 13 Jan 2020 19:03:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=lca.pw header.i=@lca.pw header.b="j2LjWR32" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A88121556 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lca.pw Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 2832B8E0005; Mon, 13 Jan 2020 14:03:57 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 232678E0003; Mon, 13 Jan 2020 14:03:57 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 121DE8E0005; Mon, 13 Jan 2020 14:03:57 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0250.hostedemail.com [216.40.44.250]) by kanga.kvack.org (Postfix) with ESMTP id F0F688E0003 for ; Mon, 13 Jan 2020 14:03:56 -0500 (EST) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 8C1E0180AD81A for ; Mon, 13 Jan 2020 19:03:56 +0000 (UTC) X-FDA: 76373535672.23.bears93_225ceda572e51 X-Spam-Summary: 2,0,0,cc1d7745842c5be7,d41d8cd98f00b204,cai@lca.pw,:peterz@infradead.org:mingo@redhat.com:juri.lelli@redhat.com:vincent.guittot@linaro.org:dietmar.eggemann@arm.com:rostedt@goodmis.org:bsegall@google.com:mgorman@suse.de:paulmck@kernel.org:tglx@linutronix.de::linux-kernel@vger.kernel.org:cai@lca.pw,RULES_HIT:2:41:69:355:379:541:617:800:960:966:973:988:989:1260:1311:1314:1345:1437:1515:1535:1606:1730:1747:1777:1792:2194:2196:2199:2200:2393:2559:2562:2741:2904:3138:3139:3140:3141:3142:3165:3355:3503:3865:3867:3868:3870:3871:3872:3874:4119:4250:4321:4385:4605:5007:6261:6653:6742:7875:7903:7974:8660:9040:10004:11026:11658:11914:12043:12291:12296:12297:12438:12517:12519:12555:12679:12895:12986:13148:13153:13161:13228:13229:13230:13894:14018:14096:14394:21080:21433:21444:21451:21627:21740:21987:30054:30065:30075,0,RBL:209.85.160.196:@lca.pw:.lbl8.mailshell.net-62.14.0.100 66.201.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp, MSBL:0,D X-HE-Tag: bears93_225ceda572e51 X-Filterd-Recvd-Size: 8053 Received: from mail-qt1-f196.google.com (mail-qt1-f196.google.com [209.85.160.196]) by imf11.hostedemail.com (Postfix) with ESMTP for ; Mon, 13 Jan 2020 19:03:55 +0000 (UTC) Received: by mail-qt1-f196.google.com with SMTP id n15so10077513qtp.5 for ; Mon, 13 Jan 2020 11:03:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lca.pw; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+inUt/WmmI597eh2nymbH3BOL/mA5fX+C9DAAZpCYV0=; b=j2LjWR32DU63CHYJd7xM+PPZB4i/BwEVYEHuSXMkO+GgS2Lyc4ydxUahqYnOQMsosc sfY/fzh8rDlPyRr8mwo3MTMeVEHYAQA7stHRIPsf0odNoeJf4V62f1ny3QdwgblF8BVJ gnksW2k1X05Kfg2jI8ME2pYxAzy5peK6/mibDSz2z9AWG5s6JoRlkNsrCD2LUa5RDBM0 fUxCv/3kV96gIBgq63UomvYpMCWqcLY0rLq844aGwvpGAtWbSXqqGtKHSfrIKftbjAiX jMODc8sYxImHQIiFOxpCgrYI64VqMArYGRR8lCVtPX8GfkFgs5/2UZOsS2pkzh09onhY 86Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+inUt/WmmI597eh2nymbH3BOL/mA5fX+C9DAAZpCYV0=; b=T0a3Cm5YmJ728XUJyQmxvdE+PNkXyeP8btUNFO4da73bgSzaQ8wHsKT0sNXNnucsuS FfwoGhnwNqmJBofEl0KY3/5mr+ztoQeMjlioVYWPEZL6sPQFjABGAjnmCf4N+jhl8jZc Y2+UCs+HUpeU9NS5H1Zk8Xz9L3UcwwyDY5eHk/GAZySsHZmcJG/MEQCsfKNZ4O7AUnra 1JLJL2epFbjguCUlOtx2qtI3D1eb1HcZPG1XHPko1UqZ7CNlqzkbveBWn2RmmIioqgFQ pw0nUj4QFBEyD5USw9XCtBZet/BF1khNiCvtx0ty/DlDL/W8knrynxhe++lu6P9PqeWt rYcw== X-Gm-Message-State: APjAAAXrxGuK3dB7Raygz+tyWKFCbvZ4ogAGLdZvMWOztvGro+VN6KxJ 9jAdA/U9CfnWwYtq/5OBiVRbjQ== X-Google-Smtp-Source: APXvYqwzD68MzhfhsQmDyZdGGp10+0UPGB9aBZJ/wmrWgpbT9FsQopUFCl5/KI/PyEG/m6MUOVdvig== X-Received: by 2002:ac8:1730:: with SMTP id w45mr9073qtj.297.1578942235143; Mon, 13 Jan 2020 11:03:55 -0800 (PST) Received: from ovpn-120-31.rdu2.redhat.com (pool-71-184-117-43.bstnma.fios.verizon.net. [71.184.117.43]) by smtp.gmail.com with ESMTPSA id k29sm6154149qtu.54.2020.01.13.11.03.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Jan 2020 11:03:54 -0800 (PST) From: Qian Cai To: peterz@infradead.org, mingo@redhat.com Cc: juri.lelli@redhat.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, paulmck@kernel.org, tglx@linutronix.de, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Qian Cai Subject: [PATCH v2] sched/core: fix illegal RCU from offline CPUs Date: Mon, 13 Jan 2020 14:03:31 -0500 Message-Id: <20200113190331.12788-1-cai@lca.pw> X-Mailer: git-send-email 2.21.0 (Apple Git-122.2) MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: In the CPU-offline process, it calls mmdrop() after idle entry and the subsequent call to cpuhp_report_idle_dead(). Once execution passes the call to rcu_report_dead(), RCU is ignoring the CPU, which results in lockdep complaints when mmdrop() uses RCU from either memcg or debugobjects, so it by scheduling mmdrop() on another online CPU. According to the commit a79e53d85683 ("x86/mm: Fix pgd_lock deadlock"), mmdrop() is not interrupt-safe, and called from smp_call_function_single() could end up running mmdrop() from the IPI interrupt handler. Call Trace: mmdrop+0x58/0x80 flush_smp_call_function_queue+0x128/0x2e0 smp_ipi_demux_relaxed+0x84/0xf0 doorbell_exception+0x118/0x588 h_doorbell_common+0x124/0x130 --- interrupt: e81 at replay_interrupt_return+0x0/0x4 LR = arch_local_irq_restore.part.8+0x78/0x90 arch_local_irq_restore.part.8+0x34/0x90 (unreliable) _raw_spin_unlock_irq+0x50/0x80 finish_task_switch+0xd8/0x340 __schedule+0x4bc/0xba0 schedule_idle+0x38/0x70 do_idle+0x2a4/0x470 cpu_startup_entry+0x3c/0x40 start_secondary+0x7a8/0xa80 start_secondary_resume+0x10/0x14 Therefore, use mmdrop_async() instead to run mmdrop() from a process context similar to the commit 7283094ec3db ("kernel, oom: fix potential pgd_lock deadlock from __mmdrop"). ============================= WARNING: suspicious RCU usage ----------------------------- kernel/workqueue.c:710 RCU or wq_pool_mutex should be held! other info that might help us debug this: RCU used illegally from offline CPU! rcu_scheduler_active = 2, debug_locks = 1 2 locks held by swapper/37/0: #0: c0000000010af608 (rcu_read_lock){....}, at: percpu_ref_put_many+0x8/0x230 #1: c0000000010af608 (rcu_read_lock){....}, at: __queue_work+0x7c/0xca0 stack backtrace: Call Trace: dump_stack+0xf4/0x164 (unreliable) lockdep_rcu_suspicious+0x140/0x164 get_work_pool+0x110/0x150 __queue_work+0x1bc/0xca0 queue_work_on+0x114/0x120 css_release+0x9c/0xc0 percpu_ref_put_many+0x204/0x230 free_pcp_prepare+0x264/0x570 free_unref_page+0x38/0xf0 __mmdrop+0x21c/0x2c0 idle_task_exit+0x170/0x1b0 pnv_smp_cpu_kill_self+0x38/0x2e0 cpu_die+0x48/0x64 arch_cpu_idle_dead+0x30/0x50 do_idle+0x2f4/0x470 cpu_startup_entry+0x38/0x40 start_secondary+0x7a8/0xa80 start_secondary_resume+0x10/0x14 ============================= WARNING: suspicious RCU usage ----------------------------- kernel/sched/core.c:562 suspicious rcu_dereference_check() usage! other info that might help us debug this: RCU used illegally from offline CPU! rcu_scheduler_active = 2, debug_locks = 1 2 locks held by swapper/94/0: #0: c000201cc77dc118 (&base->lock){-.-.}, at: lock_timer_base+0x114/0x1f0 #1: c0000000010af608 (rcu_read_lock){....}, at: get_nohz_timer_target+0x3c/0x2d0 stack backtrace: Call Trace: dump_stack+0xf4/0x164 (unreliable) lockdep_rcu_suspicious+0x140/0x164 get_nohz_timer_target+0x248/0x2d0 add_timer+0x24c/0x470 __queue_delayed_work+0x8c/0x110 queue_delayed_work_on+0x128/0x130 __debug_check_no_obj_freed+0x2ec/0x320 free_pcp_prepare+0x1b4/0x570 free_unref_page+0x38/0xf0 __mmdrop+0x21c/0x2c0 idle_task_exit+0x170/0x1b0 pnv_smp_cpu_kill_self+0x38/0x2e0 cpu_die+0x48/0x64 arch_cpu_idle_dead+0x30/0x50 do_idle+0x2f4/0x470 cpu_startup_entry+0x38/0x40 start_secondary+0x7a8/0xa80 start_secondary_prolog+0x10/0x14 Signed-off-by: Qian Cai --- v2: use mmdrop_async() thanks to Tetsuo. include/linux/sched/mm.h | 2 ++ kernel/fork.c | 2 +- kernel/sched/core.c | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index c49257a3b510..205de134348c 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -49,6 +49,8 @@ static inline void mmdrop(struct mm_struct *mm) __mmdrop(mm); } +extern void mmdrop_async(struct mm_struct *mm); + /* * This has to be called after a get_task_mm()/mmget_not_zero() * followed by taking the mmap_sem for writing before modifying the diff --git a/kernel/fork.c b/kernel/fork.c index 080809560072..9a823a955b7c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -707,7 +707,7 @@ static void mmdrop_async_fn(struct work_struct *work) __mmdrop(mm); } -static void mmdrop_async(struct mm_struct *mm) +void mmdrop_async(struct mm_struct *mm) { if (unlikely(atomic_dec_and_test(&mm->mm_count))) { INIT_WORK(&mm->async_put_work, mmdrop_async_fn); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 90e4b00ace89..1863a6fc4d82 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6194,7 +6194,8 @@ void idle_task_exit(void) current->active_mm = &init_mm; finish_arch_post_lock_switch(); } - mmdrop(mm); + smp_call_function_single(cpumask_first(cpu_online_mask), + (void (*)(void *))mmdrop_async, mm, 0); } /*