Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp4055347ima; Mon, 4 Feb 2019 09:26:39 -0800 (PST) X-Google-Smtp-Source: AHgI3IYHNf5C9CKX03opbbckiOWkdJ2y9lx75SACWZLI3pVsD+pjXxwYXvCw0c4I1ELLd06jVj1b X-Received: by 2002:a63:f444:: with SMTP id p4mr443386pgk.124.1549301199055; Mon, 04 Feb 2019 09:26:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549301199; cv=none; d=google.com; s=arc-20160816; b=tApZR6rmK6SxFyGjuFgFq3m+4Ik7cV/k5YmttACYNqdNQXv3YDS65JyNQ4Ow1k612q rIaq+jcVN8hwdw1U4lFiWokiHuGEpb6Zpq7z6qhM04plZtwD/9poK4jQ3meyAYaKECxW 9AzEICmCsDwcyvShkQnjfJlxNKt8Vi94XzUWGhbnrlmvY79VzXEYmBio2ISITEBA0nCb vkl6c4v07X9krbwTa4G7377r2IVp+Pjp8R01NRaIrdIusWvbhJKDmCdiUYJ406Sx7pV8 5XanFQr4zgZ1kJpuCx4E+tCtdwW7erhNqz+x3MTr7J7jsma9sOD++A/WdvgRpA09KWYJ luUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=BTPTQyevdTYFy7p6yhxhHK7THEetl9tAy7JTZYPEMmc=; b=yfS7ZzneP/0e2DbyFBePRPvcFb/JbEvTXL0KS5emwvJljYzLO0GFm5WJDQI2a62CWH 4vyDM7vQV7DZOn/yf62RaOImW+8WzD9uK48m+qVz05PVWgr0GawJxkgs2aptA9XNYJIF FCT8bQXFDAcirXAb7MILZbHvU8WF8hsEH1sOYRkkcHgEQ2ib3b7jI6LMTIXeaxBcgswB eFgHjDFqr+d+zjqDVjblA897RXfWDmXZZj6vJ311k2NmK52rpufmy6FjXmm5Kn/G1cQa bE98TxNNv5HOnwBIFnU+JrOImIguCB974O/3HpntfviYv3XBgtdgAL2MIvBMweIavXOU QYmQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 38si480462pln.313.2019.02.04.09.26.22; Mon, 04 Feb 2019 09:26:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730464AbfBDRJn (ORCPT + 99 others); Mon, 4 Feb 2019 12:09:43 -0500 Received: from foss.arm.com ([217.140.101.70]:58656 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725992AbfBDRJm (ORCPT ); Mon, 4 Feb 2019 12:09:42 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C17A515AB; Mon, 4 Feb 2019 09:09:41 -0800 (PST) Received: from e110467-lin.cambridge.arm.com (e110467-lin.cambridge.arm.com [10.1.196.75]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 24BF13F589; Mon, 4 Feb 2019 09:09:40 -0800 (PST) From: Robin Murphy To: will.deacon@arm.com, mark.rutland@arm.com Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, suzuki.poulose@arm.com, peterz@infradead.org, tglx@linutronix.de, bigeasy@linutronix.de, "Li, Meng" Subject: [PATCH 1/5] perf/arm-cci: Fix CPU hotplug race avoidance Date: Mon, 4 Feb 2019 17:09:04 +0000 Message-Id: <606ff8c3f7f35ccdcb4b52a49f692fb20e27359c.1549299188.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.20.1.dirty In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The arm-cci probe logic faces a cyclic dependency wherein it has to pick a valid CPU to associate with before registering the PMU device, has to have the PMU state initialised before handling hotplug events in case it must be migrated, but has to have the hotplug notifier registered before the chosen CPU may go offline lest things get out of sync. The present code has tried to solve the races by using get_cpu() to pick the current CPU and prevent it from disappearing while the other two registrations are performed, but that results in taking mutexes with preemption disabled, which makes certain configurations very unhappy: [ 1.983337] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:2004 [ 1.983340] in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: swapper/0 [ 1.983342] Preemption disabled at: [ 1.983353] [] cci_pmu_probe+0x1dc/0x488 [ 1.983360] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.18.20-rt8-yocto-preempt-rt #1 [ 1.983362] Hardware name: ZynqMP ZCU102 Rev1.0 (DT) [ 1.983364] Call trace: [ 1.983369] dump_backtrace+0x0/0x158 [ 1.983372] show_stack+0x24/0x30 [ 1.983378] dump_stack+0x80/0xa4 [ 1.983383] ___might_sleep+0x138/0x160 [ 1.983386] __might_sleep+0x58/0x90 [ 1.983391] __rt_mutex_lock_state+0x30/0xc0 [ 1.983395] _mutex_lock+0x24/0x30 [ 1.983400] perf_pmu_register+0x2c/0x388 [ 1.983404] cci_pmu_probe+0x2bc/0x488 [ 1.983409] platform_drv_probe+0x58/0xa8 However, we don't actually mind being preempted or migrated at this point; all that really matters is that whichever CPU we pick does not get offlined before we're done. Thus, do the robust thing and instead take the lock to inhibit CPU hotplug for the duration. This also revealed an additional race in assigning the global pointer too late relative to the hotplug notifier, so that gets fixed in the process. Reported-by: "Li, Meng" Signed-off-by: Robin Murphy --- drivers/perf/arm-cci.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c index 1bfeb160c5b1..f6d9df07ec9b 100644 --- a/drivers/perf/arm-cci.c +++ b/drivers/perf/arm-cci.c @@ -1692,21 +1692,23 @@ static int cci_pmu_probe(struct platform_device *pdev) raw_spin_lock_init(&cci_pmu->hw_events.pmu_lock); mutex_init(&cci_pmu->reserve_mutex); atomic_set(&cci_pmu->active_events, 0); - cci_pmu->cpu = get_cpu(); + + cpus_read_lock(); + cci_pmu->cpu = smp_processor_id(); ret = cci_pmu_init(cci_pmu, pdev); - if (ret) { - put_cpu(); - return ret; - } + if (ret) + goto out; - cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_CCI_ONLINE, - "perf/arm/cci:online", NULL, - cci_pmu_offline_cpu); - put_cpu(); g_cci_pmu = cci_pmu; + cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_PERF_ARM_CCI_ONLINE, + "perf/arm/cci:online", NULL, + cci_pmu_offline_cpu); + pr_info("ARM %s PMU driver probed", cci_pmu->model->name); - return 0; +out: + cpus_read_unlock(); + return ret; } static int cci_pmu_remove(struct platform_device *pdev) -- 2.20.1.dirty