Received: by 2002:ab2:7a55:0:b0:1f4:4a7d:290d with SMTP id u21csp60608lqp; Thu, 4 Apr 2024 07:10:08 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCX3uqscFFqmW8LcT5R03IKZE0ml3LpDvnOADCYGOii7hUlJwBfHE/ZhtHPX8HGQBWpFheQdEpeGGkKKlwhplttspNO7Efooxa0bC+b/lQ== X-Google-Smtp-Source: AGHT+IH0AE/XUBnu85RQ8yN7K30Epw397c/KsVBmcV3F1eD4c2wVbRX1QQdgW5zRVco5rZoEnsbk X-Received: by 2002:a50:cd15:0:b0:56b:9025:44a5 with SMTP id z21-20020a50cd15000000b0056b902544a5mr2685615edi.11.1712239808780; Thu, 04 Apr 2024 07:10:08 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712239808; cv=pass; d=google.com; s=arc-20160816; b=XFcgyKJL2RvRh3RBsVse21pJT1G2ER8K8+nXfq9mF2wSZnmnb8g9rHXux0W+SIQ9hL AQiVUld+zlrxHxwE12o35esrrfS39BJN7KjdSteo4mqBQtyITWFicOoA5pywk9fHFb7i ZtU1tzSTwv95cIx4x7/QC4sz15RpVGyA80OQi1gWlHWTmD/HCy6ta8tTw20tfvwDQ+yN 36VOT+dZFLP1KrD2/ih35F9TDkXuAK0HCIX3MR0/IqrbJ2XW/UWCJCWUSMTMUY6MYdVf b/HY1HLsXhljNAhfyAcbLWuQ0lr2kxk7NPpTVlgCvJKkEO2PXpxq+QL9QvFcX/wcflxk Dv0A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=3mn3ip+JxJlPA1NiDX7DlAPgQ+QuE/ZeF2slYF7P1s4=; fh=VjryfJQxmpT4/AqTC6rNcc8wZSWTjiKZjmRGWIl3mXM=; b=EupdMmsDSull0UOQVwbp0efCW+B778F+c3qNxZo+vHjUgeyndRtJeKAYcGWGXJLeA7 06p66BTCzTNvw7wenfjWMmMq75BInBRmUuW71OPqVn4n+KevOpKAC2Ql/HClFXIiO/2z 0P323Sb95O8BBEk6/GYSiwWpTfe5rrST/K/IrqO4rW/7DE/BJK8Q36O1xfpzySW2Z+O6 wzgKh6nExhD/MrKKIgE1YQ01hpjyTPL7nSBoueFERTiXMPMGMKoYTSAi7PIuRA4oYIwk HDDQ2HEA5WtnXRco4ZtUbqwVNVUQtG5UwUyey0uUQAluzewz+etp6uu2r+ww3QFRNayF brVw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=M4ilw87K; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-131563-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-131563-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a10-20020a50c30a000000b0056dfbb4040bsi2157175edb.612.2024.04.04.07.10.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Apr 2024 07:10:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-131563-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=M4ilw87K; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-131563-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-131563-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 79C5B1F2BFD2 for ; Thu, 4 Apr 2024 14:09:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1DCFE12DDA4; Thu, 4 Apr 2024 14:07:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="M4ilw87K" Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CEEB12BF06 for ; Thu, 4 Apr 2024 14:07:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712239670; cv=none; b=uxV2SQQTvajxFcY2IYNUEtfq4BqjtoFh5mgmajRC7oKl5L4tS1Y94ulNq4IS9MtGAJ55aObA9gRMfIR77HOcwmA6pCjXU5MZ8KAedrO/IR3fjJ67WLRDUhEWW/weCvJL/2FI77bzbgegqpKe5iWS7VilcM37DAjQUUIvDXKhTLg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712239670; c=relaxed/simple; bh=2gmo/fpy1sUeMxYRU8IRq5WeNfc6Xtl1euu28QI9R3E=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dyPd+bDYtxuONvmYD8QYdjbuae+iYP47BQ10Gkc2075zpEZ0dh/WiPutsEtN9+Hps9eMUPI3CoNUNYPRWzREejly9HgQ0sD9FYzq2SNtWFlA6S6aEJbB14wPE/NShQT6lVbhxe0JRcIu/zhXRgL29OXBSdnZ8qjZVHMo2lQuhrA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=M4ilw87K; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712239668; x=1743775668; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2gmo/fpy1sUeMxYRU8IRq5WeNfc6Xtl1euu28QI9R3E=; b=M4ilw87K6RJZQMRzcM5oxF0OQa6OqqF0ERTk/QuzMbquJxeRlnMo5VAW VfnOYJHuXSQpJ+vYE9H87elPvyolpsfD1bEsuYlz2yO62cN6aFXpttpWw lNUGmsQvTPs+9alI8S02rxhbQivICagvz28WpAusKnxyq5JTG5yMNOZtD QQg8CzfkIpLfdLQpNjGtjZcEEXpKvhxXXNwxv6xHX82zQ1ftpKATLWSkX lncIBpqI9uFk424tFvbzGkRjtZI0oFQ/lOCqqhbaJCA1gtNJXYXRl89ln Nad5uD7b3uRiT/01KaathguMclr6Y/XU/sOFfaf04geLutBjuj3tbXoKj w==; X-CSE-ConnectionGUID: 5CiwRZZuQOaU4q/FKfH9Zw== X-CSE-MsgGUID: viF2w3iFQqqxjnhZrk1k0g== X-IronPort-AV: E=McAfee;i="6600,9927,11034"; a="11346545" X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="11346545" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 07:07:48 -0700 X-CSE-ConnectionGUID: 2Q4vSjHoRLWECwKBLFlANQ== X-CSE-MsgGUID: tXt0CLPQSAWwcuzZatA2ZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="23258901" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa005.fm.intel.com with ESMTP; 04 Apr 2024 07:07:47 -0700 From: kan.liang@linux.intel.com To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org, irogers@google.com, adrian.hunter@intel.com, alexander.shishkin@linux.intel.com, linux-kernel@vger.kernel.org Cc: ak@linux.intel.com, Kan Liang , Sandipan Das , Ravi Bangoria , silviazhao , CodyYao-oc Subject: [PATCH 08/12] perf/x86: Extend event update interface Date: Thu, 4 Apr 2024 07:06:33 -0700 Message-Id: <20240404140637.1232635-9-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240404140637.1232635-1-kan.liang@linux.intel.com> References: <20240404140637.1232635-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Kan Liang The current event update interface directly reads the values from the counter, but the values may not be the accurate ones users require. For example, the sample read feature wants the counter value of the member events when the leader event is overflow. But with the current implementation, the read (event update) actually happens in the NMI handler. There may be a small gap between the overflow and the NMI handler. The new Intel PEBS counters snapshotting feature can provide the accurate counter value in the overflow. The event update interface has to be updated to apply the given accurate values. Pass the accurate values via the event update interface. If the value is not available, still directly read the counter. For some cases, e.g., intel_update_topdown_event, there could be more than one counter/register are read. Using u64 * rather than u64 as the new parameter. Reviewed-by: Andi Kleen Signed-off-by: Kan Liang Cc: Sandipan Das Cc: Ravi Bangoria Cc: silviazhao Cc: CodyYao-oc --- arch/x86/events/amd/core.c | 2 +- arch/x86/events/core.c | 13 ++++++----- arch/x86/events/intel/core.c | 40 +++++++++++++++++++--------------- arch/x86/events/intel/p4.c | 2 +- arch/x86/events/perf_event.h | 4 ++-- arch/x86/events/zhaoxin/core.c | 2 +- 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 281273fbf621..d758d081520b 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -924,7 +924,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) event = cpuc->events[idx]; hwc = &event->hw; - x86_perf_event_update(event); + x86_perf_event_update(event, NULL); mask = BIT_ULL(idx); if (!(status & mask)) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 5380f7a84840..befb2f2e55b9 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -112,7 +112,7 @@ u64 __read_mostly hw_cache_extra_regs * Can only be executed on the CPU where the event is active. * Returns the delta events processed. */ -u64 x86_perf_event_update(struct perf_event *event) +u64 x86_perf_event_update(struct perf_event *event, u64 *val) { struct hw_perf_event *hwc = &event->hw; int shift = 64 - x86_pmu.cntval_bits; @@ -131,7 +131,10 @@ u64 x86_perf_event_update(struct perf_event *event) */ prev_raw_count = local64_read(&hwc->prev_count); do { - rdpmcl(hwc->event_base_rdpmc, new_raw_count); + if (!val) + rdpmcl(hwc->event_base_rdpmc, new_raw_count); + else + new_raw_count = *val; } while (!local64_try_cmpxchg(&hwc->prev_count, &prev_raw_count, new_raw_count)); @@ -1598,7 +1601,7 @@ void x86_pmu_stop(struct perf_event *event, int flags) * Drain the remaining delta count out of a event * that we are disabling: */ - static_call(x86_pmu_update)(event); + static_call(x86_pmu_update)(event, NULL); hwc->state |= PERF_HES_UPTODATE; } } @@ -1688,7 +1691,7 @@ int x86_pmu_handle_irq(struct pt_regs *regs) event = cpuc->events[idx]; - val = static_call(x86_pmu_update)(event); + val = static_call(x86_pmu_update)(event, NULL); if (val & (1ULL << (x86_pmu.cntval_bits - 1))) continue; @@ -2035,7 +2038,7 @@ static void x86_pmu_static_call_update(void) static void _x86_pmu_read(struct perf_event *event) { - static_call(x86_pmu_update)(event); + static_call(x86_pmu_update)(event, NULL); } void x86_pmu_show_pmu_cap(struct pmu *pmu) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index f9eccdf6eea6..5e0d22e5681d 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -2418,7 +2418,7 @@ static void intel_pmu_nhm_workaround(void) for (i = 0; i < 4; i++) { event = cpuc->events[i]; if (event) - static_call(x86_pmu_update)(event); + static_call(x86_pmu_update)(event, NULL); } for (i = 0; i < 4; i++) { @@ -2710,7 +2710,7 @@ static void update_saved_topdown_regs(struct perf_event *event, u64 slots, * modify by a NMI. PMU has to be disabled before calling this function. */ -static u64 intel_update_topdown_event(struct perf_event *event, int metric_end) +static u64 intel_update_topdown_event(struct perf_event *event, int metric_end, u64 *val) { struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct perf_event *other; @@ -2718,13 +2718,18 @@ static u64 intel_update_topdown_event(struct perf_event *event, int metric_end) bool reset = true; int idx; - /* read Fixed counter 3 */ - rdpmcl((3 | INTEL_PMC_FIXED_RDPMC_BASE), slots); - if (!slots) - return 0; + if (!val) { + /* read Fixed counter 3 */ + rdpmcl((3 | INTEL_PMC_FIXED_RDPMC_BASE), slots); + if (!slots) + return 0; - /* read PERF_METRICS */ - rdpmcl(INTEL_PMC_FIXED_RDPMC_METRICS, metrics); + /* read PERF_METRICS */ + rdpmcl(INTEL_PMC_FIXED_RDPMC_METRICS, metrics); + } else { + slots = val[0]; + metrics = val[1]; + } for_each_set_bit(idx, cpuc->active_mask, metric_end + 1) { if (!is_topdown_idx(idx)) @@ -2767,10 +2772,11 @@ static u64 intel_update_topdown_event(struct perf_event *event, int metric_end) return slots; } -static u64 icl_update_topdown_event(struct perf_event *event) +static u64 icl_update_topdown_event(struct perf_event *event, u64 *val) { return intel_update_topdown_event(event, INTEL_PMC_IDX_METRIC_BASE + - x86_pmu.num_topdown_events - 1); + x86_pmu.num_topdown_events - 1, + val); } DEFINE_STATIC_CALL(intel_pmu_update_topdown_event, x86_perf_event_update); @@ -2785,7 +2791,7 @@ static void intel_pmu_read_topdown_event(struct perf_event *event) return; perf_pmu_disable(event->pmu); - static_call(intel_pmu_update_topdown_event)(event); + static_call(intel_pmu_update_topdown_event)(event, NULL); perf_pmu_enable(event->pmu); } @@ -2796,7 +2802,7 @@ static void intel_pmu_read_event(struct perf_event *event) else if (is_topdown_count(event)) intel_pmu_read_topdown_event(event); else - x86_perf_event_update(event); + x86_perf_event_update(event, NULL); } static void intel_pmu_enable_fixed(struct perf_event *event) @@ -2899,7 +2905,7 @@ static void intel_pmu_add_event(struct perf_event *event) */ int intel_pmu_save_and_restart(struct perf_event *event) { - static_call(x86_pmu_update)(event); + static_call(x86_pmu_update)(event, NULL); /* * For a checkpointed counter always reset back to 0. This * avoids a situation where the counter overflows, aborts the @@ -2922,12 +2928,12 @@ static int intel_pmu_set_period(struct perf_event *event) return x86_perf_event_set_period(event); } -static u64 intel_pmu_update(struct perf_event *event) +static u64 intel_pmu_update(struct perf_event *event, u64 *val) { if (unlikely(is_topdown_count(event))) - return static_call(intel_pmu_update_topdown_event)(event); + return static_call(intel_pmu_update_topdown_event)(event, val); - return x86_perf_event_update(event); + return x86_perf_event_update(event, val); } static void intel_pmu_reset(void) @@ -3091,7 +3097,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) */ if (__test_and_clear_bit(GLOBAL_STATUS_PERF_METRICS_OVF_BIT, (unsigned long *)&status)) { handled++; - static_call(intel_pmu_update_topdown_event)(NULL); + static_call(intel_pmu_update_topdown_event)(NULL, NULL); } /* diff --git a/arch/x86/events/intel/p4.c b/arch/x86/events/intel/p4.c index 844bc4fc4724..3177be0dedd1 100644 --- a/arch/x86/events/intel/p4.c +++ b/arch/x86/events/intel/p4.c @@ -1058,7 +1058,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) /* it might be unflagged overflow */ overflow = p4_pmu_clear_cccr_ovf(hwc); - val = x86_perf_event_update(event); + val = x86_perf_event_update(event, NULL); if (!overflow && (val & (1ULL << (x86_pmu.cntval_bits - 1)))) continue; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index ebfa5eb75cd2..7f0544fe2444 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -782,7 +782,7 @@ struct x86_pmu { void (*del)(struct perf_event *); void (*read)(struct perf_event *event); int (*set_period)(struct perf_event *event); - u64 (*update)(struct perf_event *event); + u64 (*update)(struct perf_event *event, u64 *val); int (*hw_config)(struct perf_event *event); int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign); unsigned eventsel; @@ -1131,7 +1131,7 @@ extern u64 __read_mostly hw_cache_extra_regs [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX]; -u64 x86_perf_event_update(struct perf_event *event); +u64 x86_perf_event_update(struct perf_event *event, u64 *cntr); static inline unsigned int x86_pmu_config_addr(int index) { diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c index 2fd9b0cf9a5e..5fe3a9eed650 100644 --- a/arch/x86/events/zhaoxin/core.c +++ b/arch/x86/events/zhaoxin/core.c @@ -391,7 +391,7 @@ static int zhaoxin_pmu_handle_irq(struct pt_regs *regs) if (!test_bit(bit, cpuc->active_mask)) continue; - x86_perf_event_update(event); + x86_perf_event_update(event, NULL); perf_sample_data_init(&data, 0, event->hw.last_period); if (!x86_perf_event_set_period(event)) -- 2.35.1