From nobody Fri Dec 19 07:33:05 2025 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 AE040BA3F for ; Fri, 14 Jun 2024 13:47:54 +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=1718372876; cv=none; b=s4vI/abhcBqf+7FeB8+X13wYnpraWKAhQeEEKDnN/pW7r+7IzNrof4XmwG8sa8GDiE6BToKOqneRbSSVmj/rHvFYBTc4vjEnunvz3C4W9eYdYgjkQ5XxmqOf8NMBqChinr3sqmIR1D/CwvmP99qDlWt2PYWbE+HwvI+kQaIxJGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718372876; c=relaxed/simple; bh=G0WAMaS8lWiXupJuM5xWq0CW2JZAbbASeVbkXWN5a84=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=c5ut+ZBWnPMin94f/YQCX59N95CkYoR4Lpgdhb9h1zpbuQ6Ta1UbtTd6YvKNEyvm0j1L0Niish1aPawjmHXAdIRtRUIyjNP9THYwOua/moBRi+fwPhufnWTyBsCU9vFqs0PcUyNcVMlv+KhzgRnAqPUxE14IPXKYc56YLuPbGFs= 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=n0wTejHa; 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="n0wTejHa" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1718372875; x=1749908875; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=G0WAMaS8lWiXupJuM5xWq0CW2JZAbbASeVbkXWN5a84=; b=n0wTejHaix+cwpO41NRtqz6PuvkWu6M+K7JVdtZhZDZArlkgREIeAfVD CQ4XulPuiUmEDUJtO3B8VfeAAostGYkscDAayH/hjwrKsHuNULRjIr5GG soZyRKrrRPpq2N31Qh/xHWMMVXCQmbCWsFoc9PgIv4k1qDsMoMV/XslB8 HtFyCQ77GenIPz/JV/eGY/2TTzvkZLd/4+aS4tDUWEzKm3IQCQQhRXLfN oVtAbAmeKlfkRydMHKSUYty/IjbO8chNWyDNj7O9v9GEbU4uQTDh1bXvF ypcestVramcHyt2RX0THx0dh4qNx4sFxzsn7KF8jyFMjSrvTgEuJZE+4X Q==; X-CSE-ConnectionGUID: gPr1sgc6T06JYbae/2PwuA== X-CSE-MsgGUID: 3EuwcH4eRnSpgnE2UDW6Rg== X-IronPort-AV: E=McAfee;i="6700,10204,11103"; a="19079167" X-IronPort-AV: E=Sophos;i="6.08,237,1712646000"; d="scan'208";a="19079167" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jun 2024 06:47:53 -0700 X-CSE-ConnectionGUID: wtqlkvibRE+0++McLdz7gA== X-CSE-MsgGUID: z95rfbgPQ2adW6HczCZOjw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,237,1712646000"; d="scan'208";a="40386683" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa006.fm.intel.com with ESMTP; 14 Jun 2024 06:47:51 -0700 From: kan.liang@linux.intel.com To: peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org Cc: acme@kernel.org, namhyung@kernel.org, irogers@google.com, eranian@google.com, ak@linux.intel.com, yunying.sun@intel.com, tim.c.chen@linux.intel.com, Kan Liang Subject: [PATCH V2 6/8] perf/x86/uncore: Apply the unit control RB tree to PCI uncore units Date: Fri, 14 Jun 2024 06:46:29 -0700 Message-Id: <20240614134631.1092359-7-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240614134631.1092359-1-kan.liang@linux.intel.com> References: <20240614134631.1092359-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: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang The unit control RB tree has the unit control and unit ID information for all the PCI units. Use them to replace the box_ctls/pci_offsets to get an accurate unit control address for PCI uncore units. The UPI/M3UPI units in the discovery table are ignored. Please see the commit 65248a9a9ee1 ("perf/x86/uncore: Add a quirk for UPI on SPR"). Manually allocate a unit control RB tree for UPI/M3UPI. Add cleanup_extra_boxes to release such manual allocation. Tested-by: Yunying Sun Signed-off-by: Kan Liang --- arch/x86/events/intel/uncore.c | 53 +++++++++++----------- arch/x86/events/intel/uncore.h | 4 ++ arch/x86/events/intel/uncore_discovery.c | 26 ++++++++--- arch/x86/events/intel/uncore_discovery.h | 2 + arch/x86/events/intel/uncore_snbep.c | 57 ++++++++++++++++++------ 5 files changed, 94 insertions(+), 48 deletions(-) diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index f48c7049d2ed..79449c5b9256 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -969,6 +969,9 @@ static void uncore_type_exit(struct intel_uncore_type *= type) if (type->cleanup_mapping) type->cleanup_mapping(type); =20 + if (type->cleanup_extra_boxes) + type->cleanup_extra_boxes(type); + if (pmu) { for (i =3D 0; i < type->num_boxes; i++, pmu++) { uncore_pmu_unregister(pmu); @@ -1084,22 +1087,19 @@ static struct intel_uncore_pmu * uncore_pci_find_dev_pmu_from_types(struct pci_dev *pdev) { struct intel_uncore_type **types =3D uncore_pci_uncores; + struct intel_uncore_discovery_unit *unit; struct intel_uncore_type *type; - u64 box_ctl; - int i, die; + struct rb_node *node; =20 for (; *types; types++) { type =3D *types; - for (die =3D 0; die < __uncore_max_dies; die++) { - for (i =3D 0; i < type->num_boxes; i++) { - if (!type->box_ctls[die]) - continue; - box_ctl =3D type->box_ctls[die] + type->pci_offsets[i]; - if (pdev->devfn =3D=3D UNCORE_DISCOVERY_PCI_DEVFN(box_ctl) && - pdev->bus->number =3D=3D UNCORE_DISCOVERY_PCI_BUS(box_ctl) && - pci_domain_nr(pdev->bus) =3D=3D UNCORE_DISCOVERY_PCI_DOMAIN(box_ct= l)) - return &type->pmus[i]; - } + + for (node =3D rb_first(type->boxes); node; node =3D rb_next(node)) { + unit =3D rb_entry(node, struct intel_uncore_discovery_unit, node); + if (pdev->devfn =3D=3D UNCORE_DISCOVERY_PCI_DEVFN(unit->addr) && + pdev->bus->number =3D=3D UNCORE_DISCOVERY_PCI_BUS(unit->addr) && + pci_domain_nr(pdev->bus) =3D=3D UNCORE_DISCOVERY_PCI_DOMAIN(unit->a= ddr)) + return &type->pmus[unit->pmu_idx]; } } =20 @@ -1375,28 +1375,25 @@ static struct notifier_block uncore_pci_notifier = =3D { static void uncore_pci_pmus_register(void) { struct intel_uncore_type **types =3D uncore_pci_uncores; + struct intel_uncore_discovery_unit *unit; struct intel_uncore_type *type; struct intel_uncore_pmu *pmu; + struct rb_node *node; struct pci_dev *pdev; - u64 box_ctl; - int i, die; =20 for (; *types; types++) { type =3D *types; - for (die =3D 0; die < __uncore_max_dies; die++) { - for (i =3D 0; i < type->num_boxes; i++) { - if (!type->box_ctls[die]) - continue; - box_ctl =3D type->box_ctls[die] + type->pci_offsets[i]; - pdev =3D pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(box_c= tl), - UNCORE_DISCOVERY_PCI_BUS(box_ctl), - UNCORE_DISCOVERY_PCI_DEVFN(box_ctl)); - if (!pdev) - continue; - pmu =3D &type->pmus[i]; - - uncore_pci_pmu_register(pdev, type, pmu, die); - } + + for (node =3D rb_first(type->boxes); node; node =3D rb_next(node)) { + unit =3D rb_entry(node, struct intel_uncore_discovery_unit, node); + pdev =3D pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(unit->= addr), + UNCORE_DISCOVERY_PCI_BUS(unit->addr), + UNCORE_DISCOVERY_PCI_DEVFN(unit->addr)); + + if (!pdev) + continue; + pmu =3D &type->pmus[unit->pmu_idx]; + uncore_pci_pmu_register(pdev, type, pmu, unit->die); } } =20 diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index 0a49e304fe40..05c429c8cb93 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -99,6 +99,10 @@ struct intel_uncore_type { int (*get_topology)(struct intel_uncore_type *type); void (*set_mapping)(struct intel_uncore_type *type); void (*cleanup_mapping)(struct intel_uncore_type *type); + /* + * Optional callbacks for extra uncore units cleanup + */ + void (*cleanup_extra_boxes)(struct intel_uncore_type *type); }; =20 #define pmu_group attr_groups[0] diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/int= el/uncore_discovery.c index 076ec1efe9cc..866493fda47c 100644 --- a/arch/x86/events/intel/uncore_discovery.c +++ b/arch/x86/events/intel/uncore_discovery.c @@ -215,8 +215,8 @@ uncore_find_unit(struct rb_root *root, unsigned int id) return NULL; } =20 -static void uncore_find_add_unit(struct intel_uncore_discovery_unit *node, - struct rb_root *root, u16 *num_units) +void uncore_find_add_unit(struct intel_uncore_discovery_unit *node, + struct rb_root *root, u16 *num_units) { struct intel_uncore_discovery_unit *unit =3D uncore_find_unit(root, node-= >id); =20 @@ -560,7 +560,7 @@ bool intel_generic_uncore_assign_hw_event(struct perf_e= vent *event, if (!box->pmu->type->boxes) return false; =20 - if (box->pci_dev || box->io_addr) { + if (box->io_addr) { hwc->config_base =3D uncore_pci_event_ctl(box, hwc->idx); hwc->event_base =3D uncore_pci_perf_ctr(box, hwc->idx); return true; @@ -570,16 +570,28 @@ bool intel_generic_uncore_assign_hw_event(struct perf= _event *event, if (!box_ctl) return false; =20 + if (box->pci_dev) { + box_ctl =3D UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl); + hwc->config_base =3D box_ctl + uncore_pci_event_ctl(box, hwc->idx); + hwc->event_base =3D box_ctl + uncore_pci_perf_ctr(box, hwc->idx); + return true; + } + hwc->config_base =3D box_ctl + box->pmu->type->event_ctl + hwc->idx; hwc->event_base =3D box_ctl + box->pmu->type->perf_ctr + hwc->idx; =20 return true; } =20 +static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box) +{ + return UNCORE_DISCOVERY_PCI_BOX_CTRL(intel_generic_uncore_box_ctl(box)); +} + void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box) { struct pci_dev *pdev =3D box->pci_dev; - int box_ctl =3D uncore_pci_box_ctl(box); + int box_ctl =3D intel_pci_uncore_box_ctl(box); =20 __set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags); pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT); @@ -588,7 +600,7 @@ void intel_generic_uncore_pci_init_box(struct intel_unc= ore_box *box) void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box) { struct pci_dev *pdev =3D box->pci_dev; - int box_ctl =3D uncore_pci_box_ctl(box); + int box_ctl =3D intel_pci_uncore_box_ctl(box); =20 pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ); } @@ -596,7 +608,7 @@ void intel_generic_uncore_pci_disable_box(struct intel_= uncore_box *box) void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box) { struct pci_dev *pdev =3D box->pci_dev; - int box_ctl =3D uncore_pci_box_ctl(box); + int box_ctl =3D intel_pci_uncore_box_ctl(box); =20 pci_write_config_dword(pdev, box_ctl, 0); } @@ -748,6 +760,8 @@ static bool uncore_update_uncore_type(enum uncore_acces= s_type type_id, uncore->box_ctl =3D (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->bo= x_ctrl); uncore->box_ctls =3D type->box_ctrl_die; uncore->pci_offsets =3D type->box_offset; + uncore->boxes =3D &type->units; + uncore->num_boxes =3D type->num_units; break; case UNCORE_ACCESS_MMIO: uncore->ops =3D &generic_uncore_mmio_ops; diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/int= el/uncore_discovery.h index 4a7a7c819d6f..0acf9b681f3b 100644 --- a/arch/x86/events/intel/uncore_discovery.h +++ b/arch/x86/events/intel/uncore_discovery.h @@ -171,3 +171,5 @@ int intel_uncore_find_discovery_unit_id(struct rb_root = *units, int die, unsigned int pmu_idx); bool intel_generic_uncore_assign_hw_event(struct perf_event *event, struct intel_uncore_box *box); +void uncore_find_add_unit(struct intel_uncore_discovery_unit *node, + struct rb_root *root, u16 *num_units); diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/u= ncore_snbep.c index c42b170886d2..fbafc6ea198f 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -6198,6 +6198,24 @@ static u64 spr_upi_pci_offsets[SPR_UNCORE_UPI_NUM_BO= XES] =3D { 0, 0x8000, 0x10000, 0x18000 }; =20 +static void spr_extra_boxes_cleanup(struct intel_uncore_type *type) +{ + struct intel_uncore_discovery_unit *pos; + struct rb_node *node; + + if (!type->boxes) + return; + + while (!RB_EMPTY_ROOT(type->boxes)) { + node =3D rb_first(type->boxes); + pos =3D rb_entry(node, struct intel_uncore_discovery_unit, node); + rb_erase(node, type->boxes); + kfree(pos); + } + kfree(type->boxes); + type->boxes =3D NULL; +} + static struct intel_uncore_type spr_uncore_upi =3D { .event_mask =3D SNBEP_PMON_RAW_EVENT_MASK, .event_mask_ext =3D SPR_RAW_EVENT_MASK_EXT, @@ -6212,10 +6230,11 @@ static struct intel_uncore_type spr_uncore_upi =3D { .num_counters =3D 4, .num_boxes =3D SPR_UNCORE_UPI_NUM_BOXES, .perf_ctr_bits =3D 48, - .perf_ctr =3D ICX_UPI_PCI_PMON_CTR0, - .event_ctl =3D ICX_UPI_PCI_PMON_CTL0, + .perf_ctr =3D ICX_UPI_PCI_PMON_CTR0 - ICX_UPI_PCI_PMON_BOX_CTL, + .event_ctl =3D ICX_UPI_PCI_PMON_CTL0 - ICX_UPI_PCI_PMON_BOX_CTL, .box_ctl =3D ICX_UPI_PCI_PMON_BOX_CTL, .pci_offsets =3D spr_upi_pci_offsets, + .cleanup_extra_boxes =3D spr_extra_boxes_cleanup, }; =20 static struct intel_uncore_type spr_uncore_m3upi =3D { @@ -6225,11 +6244,12 @@ static struct intel_uncore_type spr_uncore_m3upi = =3D { .num_counters =3D 4, .num_boxes =3D SPR_UNCORE_UPI_NUM_BOXES, .perf_ctr_bits =3D 48, - .perf_ctr =3D ICX_M3UPI_PCI_PMON_CTR0, - .event_ctl =3D ICX_M3UPI_PCI_PMON_CTL0, + .perf_ctr =3D ICX_M3UPI_PCI_PMON_CTR0 - ICX_M3UPI_PCI_PMON_BOX_CTL, + .event_ctl =3D ICX_M3UPI_PCI_PMON_CTL0 - ICX_M3UPI_PCI_PMON_BOX_CTL, .box_ctl =3D ICX_M3UPI_PCI_PMON_BOX_CTL, .pci_offsets =3D spr_upi_pci_offsets, .constraints =3D icx_uncore_m3upi_constraints, + .cleanup_extra_boxes =3D spr_extra_boxes_cleanup, }; =20 enum perf_uncore_spr_iio_freerunning_type_id { @@ -6516,10 +6536,11 @@ void spr_uncore_cpu_init(void) =20 static void spr_update_device_location(int type_id) { + struct intel_uncore_discovery_unit *unit; struct intel_uncore_type *type; struct pci_dev *dev =3D NULL; + struct rb_root *root; u32 device, devfn; - u64 *ctls; int die; =20 if (type_id =3D=3D UNCORE_SPR_UPI) { @@ -6533,27 +6554,35 @@ static void spr_update_device_location(int type_id) } else return; =20 - ctls =3D kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL); - if (!ctls) { + root =3D kzalloc(sizeof(struct rb_root), GFP_KERNEL); + if (!root) { type->num_boxes =3D 0; return; } + *root =3D RB_ROOT; =20 while ((dev =3D pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) !=3D NU= LL) { - if (devfn !=3D dev->devfn) - continue; =20 die =3D uncore_device_to_die(dev); if (die < 0) continue; =20 - ctls[die] =3D pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFF= SET | - dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET | - devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET | - type->box_ctl; + unit =3D kzalloc(sizeof(*unit), GFP_KERNEL); + if (!unit) + continue; + unit->die =3D die; + unit->id =3D PCI_SLOT(dev->devfn) - PCI_SLOT(devfn); + unit->addr =3D pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OF= FSET | + dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET | + devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET | + type->box_ctl; + + unit->pmu_idx =3D unit->id; + + uncore_find_add_unit(unit, root, NULL); } =20 - type->box_ctls =3D ctls; + type->boxes =3D root; } =20 int spr_uncore_pci_init(void) --=20 2.35.1