From nobody Sat Dec 27 18:37:21 2025 Received: from mail-oa1-f41.google.com (mail-oa1-f41.google.com [209.85.160.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0BC66FAA; Sat, 16 Dec 2023 07:28:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="i972+3lo" Received: by mail-oa1-f41.google.com with SMTP id 586e51a60fabf-203349901d5so1005652fac.0; Fri, 15 Dec 2023 23:28:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702711712; x=1703316512; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:from:to:cc:subject:date:message-id:reply-to; bh=RSFhQuqLdRSJiFgcG2RcKezbLQH979C+mk+iCh6NLz0=; b=i972+3lo3DR2Zu614ug2OdXLQ5KfildMJQqXhjT5dq9kbREv87nXehNqUnarLrb1uf mMlVSVa5sYpCQBS+YS0uHpZZGlSi+Yejsd9nMc5xAqI/PLUTT2iE9NjAcGl8AY7fpy6f x9t5Io7gaDdk5YBRHTHQe0FDKtbejXqHGVC5vGvV6P6iSW6cG3zhpNrzXeuAgdTbRpFJ 7ilwhqYFEXNybWafYRpiSYIy+pHJqW8EWWrVC8yzptmDOpIoQOOl4maeqt6qDwZLIJM4 80NM+ttew4QuyW9oJfC0TbEv3RgxAny++eOAw14GyULHEKJAibtHx607j+xMl3gKfq7P +N0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702711712; x=1703316512; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=RSFhQuqLdRSJiFgcG2RcKezbLQH979C+mk+iCh6NLz0=; b=QCSKhLtba7kxvmBXm8o+HnXpNk59p5YILjgPJ/qxpG/Vh4qvfRN6MDUJLs4R07pGxL GRReOmaVYE/JCFC0pIS0kJMOJmPG4vBldxm3/rsuS5DnrszXUJ61rjszLP+Dlwt/r3uV vwDCi+1y13g89I/xI6CKpgIxeNZM50QiCvz5qL2tToaLwuGIuh9Qi/Xwcx/sRRgoYCFS 7+alT3G31q3kNh3iFQDGRepKrc7NPDpBudL5y2xrHKGt0ISzd7iPVVlzeAusOxDAfS7o j8rDDTSbsbg+wL+bEpTLjlX0rkAH36c45dAeUgNGV1T2nPdjnKX6rKQ313zgv8xwkyW0 ROAw== X-Gm-Message-State: AOJu0YzJSAPKZS/32e+seeYf24OZ5Qc9yBuk5YS8ehBJNOFWmeGoWhHO V0w/l4sBKry1svj7ht5+H2Q= X-Google-Smtp-Source: AGHT+IHzjFUEHdZsTee8x3eqe883NXONc4kpL2SuLpFGLoAbAsIoJoQJenn7ksReVgKVvaNTsQcUwQ== X-Received: by 2002:a05:6871:2307:b0:203:55f0:caa4 with SMTP id sf7-20020a056871230700b0020355f0caa4mr4782425oab.101.1702711712421; Fri, 15 Dec 2023 23:28:32 -0800 (PST) Received: from bangji.hsd1.ca.comcast.net ([2601:647:6780:42e0:8afe:d11b:778:2238]) by smtp.gmail.com with ESMTPSA id z21-20020a656115000000b0059d219cb359sm12507812pgu.9.2023.12.15.23.28.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 23:28:32 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Peter Zijlstra , Ingo Molnar Cc: Mark Rutland , Alexander Shishkin , Arnaldo Carvalho de Melo , LKML , Stephane Eranian , Kan Liang , stable@vger.kernel.org Subject: [PATCH] perf/x86: Fix out of range data Date: Fri, 15 Dec 2023 23:28:30 -0800 Message-ID: <20231216072830.1009339-1-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On x86 each cpu_hw_events maintains a table for counter assignment but it missed to update one for the deleted event in x86_pmu_del(). This can make perf_clear_dirty_counters() reset used counter if it's called before event scheduling or enabling. Then it would return out of range data which doesn't make sense. The following code can reproduce the problem. $ cat repro.c #include #include #include #include #include #include #include #include struct perf_event_attr attr =3D { .type =3D PERF_TYPE_HARDWARE, .config =3D PERF_COUNT_HW_CPU_CYCLES, .disabled =3D 1, }; void *worker(void *arg) { int cpu =3D (long)arg; int fd1 =3D syscall(SYS_perf_event_open, &attr, -1, cpu, -1, 0); int fd2 =3D syscall(SYS_perf_event_open, &attr, -1, cpu, -1, 0); void *p; do { ioctl(fd1, PERF_EVENT_IOC_ENABLE, 0); p =3D mmap(NULL, 4096, PROT_READ, MAP_SHARED, fd1, 0); ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0); ioctl(fd2, PERF_EVENT_IOC_DISABLE, 0); munmap(p, 4096); ioctl(fd1, PERF_EVENT_IOC_DISABLE, 0); } while (1); return NULL; } int main(void) { int i; int n =3D sysconf(_SC_NPROCESSORS_ONLN); pthread_t *th =3D calloc(n, sizeof(*th)); for (i =3D 0; i < n; i++) pthread_create(&th[i], NULL, worker, (void *)(long)i); for (i =3D 0; i < n; i++) pthread_join(th[i], NULL); free(th); return 0; } And you can see the out of range data using perf stat like this. Probably it'd be easier to see on a large machine. $ gcc -o repro repro.c -pthread $ ./repro & $ sudo perf stat -A -I 1000 2>&1 | awk '{ if (length($3) > 15) print }' 1.001028462 CPU6 196,719,295,683,763 cycles = # 194290.996 GHz (71.54%) 1.001028462 CPU3 396,077,485,787,730 branch-misses = # 15804359784.80% of all branches (71.07%) 1.001028462 CPU17 197,608,350,727,877 branch-misses = # 14594186554.56% of all branches (71.22%) 2.020064073 CPU4 198,372,472,612,140 cycles = # 194681.113 GHz (70.95%) 2.020064073 CPU6 199,419,277,896,696 cycles = # 195720.007 GHz (70.57%) 2.020064073 CPU20 198,147,174,025,639 cycles = # 194474.654 GHz (71.03%) 2.020064073 CPU20 198,421,240,580,145 stalled-cycles-frontend = # 100.14% frontend cycles idle (70.93%) 3.037443155 CPU4 197,382,689,923,416 cycles = # 194043.065 GHz (71.30%) 3.037443155 CPU20 196,324,797,879,414 cycles = # 193003.773 GHz (71.69%) 3.037443155 CPU5 197,679,956,608,205 stalled-cycles-backend = # 1315606428.66% backend cycles idle (71.19%) 3.037443155 CPU5 198,571,860,474,851 instructions = # 13215422.58 insn per cycle It should move the contents in the cpuc->assign as well. Fixes: 5471eea5d3bf ("perf/x86: Reset the dirty counter to prevent the leak= for an RDPMC task") Cc: Kan Liang Cc: stable@vger.kernel.org Signed-off-by: Namhyung Kim Reviewed-by: Kan Liang --- arch/x86/events/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 09050641ce5d..5b0dd07b1ef1 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1644,6 +1644,7 @@ static void x86_pmu_del(struct perf_event *event, int= flags) while (++i < cpuc->n_events) { cpuc->event_list[i-1] =3D cpuc->event_list[i]; cpuc->event_constraint[i-1] =3D cpuc->event_constraint[i]; + cpuc->assign[i-1] =3D cpuc->assign[i]; } cpuc->event_constraint[i-1] =3D NULL; --cpuc->n_events; --=20 2.43.0.472.g3155946c3a-goog