From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752001AbdANLZY (ORCPT ); Sat, 14 Jan 2017 06:25:24 -0500 Received: from szxga02-in.huawei.com ([119.145.14.65]:27835 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751830AbdANLZW (ORCPT ); Sat, 14 Jan 2017 06:25:22 -0500 From: Zhou Chengming To: , CC: , , , , , , , , , , , Subject: [PATCH] fix race caused by hyperthreads when online an offline cpu Date: Sat, 14 Jan 2017 19:21:49 +0800 Message-ID: <1484392909-17796-1-git-send-email-zhouchengming1@huawei.com> X-Mailer: git-send-email 1.7.12.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.102.37] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020201.587A0A92.0293,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 498d3b3fc9e235531a8cf1c00552e5ee Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After online an offline cpu, cpu_hw_events.excl_thread_id will always be set to 1 in intel_pmu_cpu_starting() even when its sibling's excl_thread_id is also 1. Then the two siblings will use the same state in their shared cpu_hw_events.excl_cntrs, it will cause race problem. The race senario is like this: Two cpu (7 and 19) are siblings, excl_thread_id of 7 and 19 are 0 and 1. After offline and online cpu 7, intel_pmu_cpu_starting() will set excl_thread_id of cpu 7 to 1. Then both cpu 7 and 19 will use the same state in their shared cpu_hw_events.excl_cntrs. cpu7 cpu19 --- --- intel_start_scheduling() set state->sched_started = true intel_put_excl_constraints() { if (!state->sched_started) spin_lock // not executed intel_stop_scheduling() set state->sched_started = false if (!state->sched_started) spin_unlock // excuted Signed-off-by: NuoHan Qiao Signed-off-by: Zhou Chengming --- arch/x86/events/intel/core.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index a74a2db..593d8c9 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3164,13 +3164,16 @@ static void intel_pmu_cpu_starting(int cpu) if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { for_each_cpu(i, topology_sibling_cpumask(cpu)) { + struct cpu_hw_events *sibling; struct intel_excl_cntrs *c; - c = per_cpu(cpu_hw_events, i).excl_cntrs; + sibling = &per_cpu(cpu_hw_events, i); + c = sibling->excl_cntrs; if (c && c->core_id == core_id) { cpuc->kfree_on_online[1] = cpuc->excl_cntrs; cpuc->excl_cntrs = c; - cpuc->excl_thread_id = 1; + if (!sibling->excl_thread_id) + cpuc->excl_thread_id = 1; break; } } -- 1.7.7