From patchwork Wed Feb 27 22:50:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832369 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5D1FA1669 for ; Wed, 27 Feb 2019 22:50:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B7D42E4E6 for ; Wed, 27 Feb 2019 22:50:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3EDF42E50C; Wed, 27 Feb 2019 22:50:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DC772E4F0 for ; Wed, 27 Feb 2019 22:50:37 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1F2A98E0001; Wed, 27 Feb 2019 17:50:32 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1CA648E0004; Wed, 27 Feb 2019 17:50:32 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EEA028E0001; Wed, 27 Feb 2019 17:50:31 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by kanga.kvack.org (Postfix) with ESMTP id 886918E0004 for ; Wed, 27 Feb 2019 17:50:31 -0500 (EST) Received: by mail-pl1-f199.google.com with SMTP id 38so13508584pld.6 for ; Wed, 27 Feb 2019 14:50:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=xY/LahxVPULVsTMg0L1GjyZvVLAXNgai3BFO+O/10dE=; b=XzAi4L4OjrNVhl2Fd29gE1j33qZAaphCCmKNIr0HL9WTmzcy0iRkQiSuz5i4mjw+A7 OmsPD2QRZSs/jsNcDa/QlmZUYniPhOYeBmV2Kg9f9ebprR/tQXAlWf8nKCDoPenlLuga DowJxHk3yfj+RKtzTd18XYI3e/H2BDMSC+ljVQXBFsmBibTwVuqNlrdahjPL/JnjnWWG GoC0eQTDFakZfAMWQY/XwUTJA6aEk0RjxxUwx9XYJRwIrMndcttB6sHah9zFHmF7ESvX bfDyThEOtDPKRmzykouMATyRqbVRSXRiVD061jsytpYXlD5qU4nlcZ+3ZeTlkQ6+IXzk asKA== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuYll6E13iEXtU0ahY3DUJUC7tn7wnAxvpPyKWxl9RKAtkjqLaJ/ Phym1ZnOWT+fXoMqGdbVMmzkSnDcDCULHZ0r04+DOTkLvSrTWZOpaIUJojtrZ+EgyqxFQLPZ/9d p8+omTjmJTdqAFEpjupoMVjTB/C48gms3qHTfWcbG7yJDxPgxyFVzqjD6hZbydvEprQ== X-Received: by 2002:a65:6294:: with SMTP id f20mr5264065pgv.174.1551307831024; Wed, 27 Feb 2019 14:50:31 -0800 (PST) X-Google-Smtp-Source: AHgI3IYLHYZJaecB2vPXRK0ZSGYMfvG4AfcRWnHq6SIzfN+m2ZI94g2h25o7M0RF41yxshO5VGTy X-Received: by 2002:a65:6294:: with SMTP id f20mr5263952pgv.174.1551307829390; Wed, 27 Feb 2019 14:50:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307829; cv=none; d=google.com; s=arc-20160816; b=yY8CiwfmE15iGMmOt8dTglvnuw2fvBIoRp6apuHmEYcSMGnDWRQMOsfyjQ+Qo20pv+ 2fhp4R/H8z9Gaz4y6f/ErIngyVuVmVCCOCc6lcwWE+pAI+AOG1A0rsrL4S1mogWjGeML qY4V5ilx13ONYrR7qwmelz1/4l9PvOCZ0afETN3d3TFuJyVFeGAze03K29kL0QtVE16j reJaG/JYFHxdXWkFfTm1jfyUMAoYrbSBeL5oovtfaK9b80AxUESODipzfK/AXEHBFH8b ZDD+O7RFiPvwfdyMcBeMkpbzm8EJAfTCDMHiFxAK1JaJ/wPkOKSd/N12r4v1fxf3rRKn EOuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=xY/LahxVPULVsTMg0L1GjyZvVLAXNgai3BFO+O/10dE=; b=FupM7CKXRFYwSt4Xq4tkbCI1jeGwlm3vQAKkiUdTIP4tpp6UpNxLIYsdkC6ytiQwOc 89yEaDPInsdSw9e056hQgsyHS33zih5gweaIlup/lgnpG/kTy7mtHPfssjLenfM8eToD yZeIvKA/Hvvua/HjJM0jbJjC1b6RLVyZg/g1zg4Av++S4xA6ZGcbccnlr69dQ1ETq/lP YEs3U9QajpptzGscfRZBJqcvwQymi/6utB5pzioO5pumtwfSUw5URd8MO3o5LF6+i/ni sO5x+oyPk7NbJDmn3CSm0ifMOqDFiIAq1b6mVSFPSR4Tb+v9/trUIgfVyG4J9YnM5OqR 8otg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:29 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349377" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:28 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 01/10] acpi: Create subtable parsing infrastructure Date: Wed, 27 Feb 2019 15:50:29 -0700 Message-Id: <20190227225038.20438-2-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Parsing entries in an ACPI table had assumed a generic header structure. There is no standard ACPI header, though, so less common layouts with different field sizes required custom parsers to go through their subtable entry list. Create the infrastructure for adding different table types so parsing the entries array may be more reused for all ACPI system tables and the common code doesn't need to be duplicated. Reviewed-by: Rafael J. Wysocki Cc: Dan Williams Signed-off-by: Keith Busch --- arch/arm64/kernel/acpi_numa.c | 2 +- arch/arm64/kernel/smp.c | 4 +- arch/ia64/kernel/acpi.c | 14 +++--- arch/x86/kernel/acpi/boot.c | 36 +++++++------- drivers/acpi/numa.c | 16 +++---- drivers/acpi/scan.c | 4 +- drivers/acpi/tables.c | 67 +++++++++++++++++++++++---- drivers/irqchip/irq-gic-v2m.c | 2 +- drivers/irqchip/irq-gic-v3-its-pci-msi.c | 2 +- drivers/irqchip/irq-gic-v3-its-platform-msi.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 6 +-- drivers/irqchip/irq-gic-v3.c | 10 ++-- drivers/irqchip/irq-gic.c | 4 +- drivers/mailbox/pcc.c | 2 +- include/linux/acpi.h | 5 +- 15 files changed, 113 insertions(+), 63 deletions(-) diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c index eac1d0cc595c..7ff800045434 100644 --- a/arch/arm64/kernel/acpi_numa.c +++ b/arch/arm64/kernel/acpi_numa.c @@ -45,7 +45,7 @@ static inline int get_cpu_for_acpi_id(u32 uid) return -EINVAL; } -static int __init acpi_parse_gicc_pxm(struct acpi_subtable_header *header, +static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_gicc_affinity *pa; diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 824de7038967..bb4b3f07761a 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -586,7 +586,7 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor) } static int __init -acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, +acpi_parse_gic_cpu_interface(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_interrupt *processor; @@ -595,7 +595,7 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, if (BAD_MADT_GICC_ENTRY(processor, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); acpi_map_gic_cpu_interface(processor); diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 41eb281709da..1435e7a1a8cd 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -177,7 +177,7 @@ struct acpi_table_madt *acpi_madt __initdata; static u8 has_8259; static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_local_apic_override *lapic; @@ -195,7 +195,7 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lsapic(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_local_sapic *lsapic; @@ -216,7 +216,7 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end) } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_local_apic_nmi *lacpi_nmi; @@ -230,7 +230,7 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e } static int __init -acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_iosapic(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_io_sapic *iosapic; @@ -245,7 +245,7 @@ acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end static unsigned int __initdata acpi_madt_rev; static int __init -acpi_parse_plat_int_src(struct acpi_subtable_header * header, +acpi_parse_plat_int_src(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_interrupt_source *plintsrc; @@ -329,7 +329,7 @@ unsigned int get_cpei_target_cpu(void) } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_interrupt_override *p; @@ -350,7 +350,7 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_nmi_source *nmi_src; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 8dcbf6890714..9fc92e4539d8 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -197,7 +197,7 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled) } static int __init -acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) +acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_local_x2apic *processor = NULL; #ifdef CONFIG_X86_X2APIC @@ -210,7 +210,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); #ifdef CONFIG_X86_X2APIC apic_id = processor->local_apic_id; @@ -242,7 +242,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) } static int __init -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_local_apic *processor = NULL; @@ -251,7 +251,7 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); /* Ignore invalid ID */ if (processor->id == 0xff) @@ -272,7 +272,7 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) } static int __init -acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned long end) +acpi_parse_sapic(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_local_sapic *processor = NULL; @@ -281,7 +281,7 @@ acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned long end) if (BAD_MADT_ENTRY(processor, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); acpi_register_lapic((processor->id << 8) | processor->eid,/* APIC ID */ processor->processor_id, /* ACPI ID */ @@ -291,7 +291,7 @@ acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned long end) } static int __init -acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, +acpi_parse_lapic_addr_ovr(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL; @@ -301,7 +301,7 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); acpi_lapic_addr = lapic_addr_ovr->address; @@ -309,7 +309,7 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, +acpi_parse_x2apic_nmi(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL; @@ -319,7 +319,7 @@ acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, if (BAD_MADT_ENTRY(x2apic_nmi, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); if (x2apic_nmi->lint != 1) printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); @@ -328,7 +328,7 @@ acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, } static int __init -acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; @@ -337,7 +337,7 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e if (BAD_MADT_ENTRY(lapic_nmi, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); if (lapic_nmi->lint != 1) printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); @@ -449,7 +449,7 @@ static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity, } static int __init -acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_ioapic(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_io_apic *ioapic = NULL; struct ioapic_domain_cfg cfg = { @@ -462,7 +462,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) if (BAD_MADT_ENTRY(ioapic, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); /* Statically assign IRQ numbers for IOAPICs hosting legacy IRQs */ if (ioapic->global_irq_base < nr_legacy_irqs()) @@ -508,7 +508,7 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, } static int __init -acpi_parse_int_src_ovr(struct acpi_subtable_header * header, +acpi_parse_int_src_ovr(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_interrupt_override *intsrc = NULL; @@ -518,7 +518,7 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, if (BAD_MADT_ENTRY(intsrc, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) { acpi_sci_ioapic_setup(intsrc->source_irq, @@ -550,7 +550,7 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, } static int __init -acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end) +acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_madt_nmi_source *nmi_src = NULL; @@ -559,7 +559,7 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end if (BAD_MADT_ENTRY(nmi_src, end)) return -EINVAL; - acpi_table_print_madt_entry(header); + acpi_table_print_madt_entry(&header->common); /* TBD: Support nimsrc entries? */ diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 867f6e3f2b4f..30995834ad70 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -339,7 +339,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) } static int __init -acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, +acpi_parse_x2apic_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_x2apic_cpu_affinity *processor_affinity; @@ -348,7 +348,7 @@ acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_x2apic_affinity_init(processor_affinity); @@ -357,7 +357,7 @@ acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, } static int __init -acpi_parse_processor_affinity(struct acpi_subtable_header *header, +acpi_parse_processor_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_cpu_affinity *processor_affinity; @@ -366,7 +366,7 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_processor_affinity_init(processor_affinity); @@ -375,7 +375,7 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, } static int __init -acpi_parse_gicc_affinity(struct acpi_subtable_header *header, +acpi_parse_gicc_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_gicc_affinity *processor_affinity; @@ -384,7 +384,7 @@ acpi_parse_gicc_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_gicc_affinity_init(processor_affinity); @@ -395,7 +395,7 @@ acpi_parse_gicc_affinity(struct acpi_subtable_header *header, static int __initdata parsed_numa_memblks; static int __init -acpi_parse_memory_affinity(struct acpi_subtable_header * header, +acpi_parse_memory_affinity(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_srat_mem_affinity *memory_affinity; @@ -404,7 +404,7 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, if (!memory_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ if (!acpi_numa_memory_affinity_init(memory_affinity)) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 446c959a8f08..f7771a3b4a3e 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2241,10 +2241,10 @@ static struct acpi_probe_entry *ape; static int acpi_probe_count; static DEFINE_MUTEX(acpi_probe_mutex); -static int __init acpi_match_madt(struct acpi_subtable_header *header, +static int __init acpi_match_madt(union acpi_subtable_headers *header, const unsigned long end) { - if (!ape->subtable_valid || ape->subtable_valid(header, ape)) + if (!ape->subtable_valid || ape->subtable_valid(&header->common, ape)) if (!ape->probe_subtbl(header, end)) acpi_probe_count++; diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8fccbe49612a..7553774a22b7 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -49,6 +49,15 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; static int acpi_apic_instance __initdata; +enum acpi_subtable_type { + ACPI_SUBTABLE_COMMON, +}; + +struct acpi_subtable_entry { + union acpi_subtable_headers *hdr; + enum acpi_subtable_type type; +}; + /* * Disable table checksum verification for the early stage due to the size * limitation of the current x86 early mapping implementation. @@ -217,6 +226,42 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } +static unsigned long __init +acpi_get_entry_type(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.type; + } + return 0; +} + +static unsigned long __init +acpi_get_entry_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.length; + } + return 0; +} + +static unsigned long __init +acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return sizeof(entry->hdr->common); + } + return 0; +} + +static enum acpi_subtable_type __init +acpi_get_subtable_type(char *id) +{ + return ACPI_SUBTABLE_COMMON; +} + /** * acpi_parse_entries_array - for each proc_num find a suitable subtable * @@ -246,8 +291,8 @@ acpi_parse_entries_array(char *id, unsigned long table_size, struct acpi_subtable_proc *proc, int proc_num, unsigned int max_entries) { - struct acpi_subtable_header *entry; - unsigned long table_end; + struct acpi_subtable_entry entry; + unsigned long table_end, subtable_len, entry_len; int count = 0; int errs = 0; int i; @@ -270,19 +315,20 @@ acpi_parse_entries_array(char *id, unsigned long table_size, /* Parse all entries looking for a match. */ - entry = (struct acpi_subtable_header *) + entry.type = acpi_get_subtable_type(id); + entry.hdr = (union acpi_subtable_headers *) ((unsigned long)table_header + table_size); + subtable_len = acpi_get_subtable_header_length(&entry); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + while (((unsigned long)entry.hdr) + subtable_len < table_end) { if (max_entries && count >= max_entries) break; for (i = 0; i < proc_num; i++) { - if (entry->type != proc[i].id) + if (acpi_get_entry_type(&entry) != proc[i].id) continue; if (!proc[i].handler || - (!errs && proc[i].handler(entry, table_end))) { + (!errs && proc[i].handler(entry.hdr, table_end))) { errs++; continue; } @@ -297,13 +343,14 @@ acpi_parse_entries_array(char *id, unsigned long table_size, * If entry->length is 0, break from this loop to avoid * infinite loop. */ - if (entry->length == 0) { + entry_len = acpi_get_entry_length(&entry); + if (entry_len == 0) { pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id); return -EINVAL; } - entry = (struct acpi_subtable_header *) - ((unsigned long)entry + entry->length); + entry.hdr = (union acpi_subtable_headers *) + ((unsigned long)entry.hdr + entry_len); } if (max_entries && count > max_entries) { diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index f5fe0100f9ff..de14e06fd9ec 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -446,7 +446,7 @@ static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev) } static int __init -acpi_parse_madt_msi(struct acpi_subtable_header *header, +acpi_parse_madt_msi(union acpi_subtable_headers *header, const unsigned long end) { int ret; diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c index 8d6d009d1d58..c81d5b81da56 100644 --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c @@ -159,7 +159,7 @@ static int __init its_pci_of_msi_init(void) #ifdef CONFIG_ACPI static int __init -its_pci_msi_parse_madt(struct acpi_subtable_header *header, +its_pci_msi_parse_madt(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_translator *its_entry; diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c index 7b8e87b493fe..9cdcda5bb3bd 100644 --- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c @@ -117,7 +117,7 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode, #ifdef CONFIG_ACPI static int __init -its_pmsi_parse_madt(struct acpi_subtable_header *header, +its_pmsi_parse_madt(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_translator *its_entry; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 2dd1ff0cf558..a430de946d99 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -3830,13 +3830,13 @@ static int __init acpi_get_its_numa_node(u32 its_id) return NUMA_NO_NODE; } -static int __init gic_acpi_match_srat_its(struct acpi_subtable_header *header, +static int __init gic_acpi_match_srat_its(union acpi_subtable_headers *header, const unsigned long end) { return 0; } -static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header, +static int __init gic_acpi_parse_srat_its(union acpi_subtable_headers *header, const unsigned long end) { int node; @@ -3903,7 +3903,7 @@ static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; } static void __init acpi_its_srat_maps_free(void) { } #endif -static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header, +static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_translator *its_entry; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 15e55d327505..f44cd89cfc40 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1593,7 +1593,7 @@ gic_acpi_register_redist(phys_addr_t phys_base, void __iomem *redist_base) } static int __init -gic_acpi_parse_madt_redist(struct acpi_subtable_header *header, +gic_acpi_parse_madt_redist(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_redistributor *redist = @@ -1611,7 +1611,7 @@ gic_acpi_parse_madt_redist(struct acpi_subtable_header *header, } static int __init -gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header, +gic_acpi_parse_madt_gicc(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_interrupt *gicc = @@ -1653,14 +1653,14 @@ static int __init gic_acpi_collect_gicr_base(void) return -ENODEV; } -static int __init gic_acpi_match_gicr(struct acpi_subtable_header *header, +static int __init gic_acpi_match_gicr(union acpi_subtable_headers *header, const unsigned long end) { /* Subtable presence means that redist exists, that's it */ return 0; } -static int __init gic_acpi_match_gicc(struct acpi_subtable_header *header, +static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_interrupt *gicc = @@ -1726,7 +1726,7 @@ static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header, return true; } -static int __init gic_acpi_parse_virt_madt_gicc(struct acpi_subtable_header *header, +static int __init gic_acpi_parse_virt_madt_gicc(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_interrupt *gicc = diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index ba2a37a27a54..a749d73f8337 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -1508,7 +1508,7 @@ static struct } acpi_data __initdata; static int __init -gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, +gic_acpi_parse_madt_cpu(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_madt_generic_interrupt *processor; @@ -1540,7 +1540,7 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, } /* The things you have to do to just *count* something... */ -static int __init acpi_dummy_func(struct acpi_subtable_header *header, +static int __init acpi_dummy_func(union acpi_subtable_headers *header, const unsigned long end) { return 0; diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 256f18b67e8a..08a0a3517138 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -382,7 +382,7 @@ static const struct mbox_chan_ops pcc_chan_ops = { * * This gets called for each entry in the PCC table. */ -static int parse_pcc_subspace(struct acpi_subtable_header *header, +static int parse_pcc_subspace(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d5dcebd7aad3..9494d42bf507 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -141,10 +141,13 @@ enum acpi_address_range_id { /* Table Handlers */ +union acpi_subtable_headers { + struct acpi_subtable_header common; +}; typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table); -typedef int (*acpi_tbl_entry_handler)(struct acpi_subtable_header *header, +typedef int (*acpi_tbl_entry_handler)(union acpi_subtable_headers *header, const unsigned long end); /* Debugger support */ From patchwork Wed Feb 27 22:50:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832367 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2986D1575 for ; Wed, 27 Feb 2019 22:50:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19D5C2E4DB for ; Wed, 27 Feb 2019 22:50:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1804A2E503; Wed, 27 Feb 2019 22:50:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A378A2E4DB for ; Wed, 27 Feb 2019 22:50:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C9F5E8E0007; Wed, 27 Feb 2019 17:50:31 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id C54B78E0001; Wed, 27 Feb 2019 17:50:31 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AC8468E0007; Wed, 27 Feb 2019 17:50:31 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by kanga.kvack.org (Postfix) with ESMTP id 6D6B68E0001 for ; Wed, 27 Feb 2019 17:50:31 -0500 (EST) Received: by mail-pl1-f199.google.com with SMTP id t1so13496836plo.20 for ; Wed, 27 Feb 2019 14:50:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=nQuXJ7LNYRRxRkGtcByfgDjWm6trYb32V1csoO7OD/Q=; b=Vwc+Hte3VEziqKSTW4ij0/1j5HiP0C/2uI8+epD8rJ44uFaDjmjrEnGVxXyK8nrSfZ /TFWV1iz8awU4yI+n/DF/IJmSTE9FeR4MDPzjdGGhStcU3ByTjBgBTaE3kmcWcDFE6EB Rqk7XgKx0I8yYMoiIXgaXvRNQLDDylEY9PAuv57nhpdVd7QaHXuEyP5XDAwxL2FQ1MMQ 9qxdgOJKRTM0fMdd63sovE1odFc5U4Bkyrn54qHGq7JfXpCRlh1vPzHgfdUDnIBRfjSo bFhKcaPzLKm991mMpNQKacyYz+WdAu5yzlNyqH+eqvgEJbohOfPTwnAIN+Avee2fm1vy nIhQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuZ/v5MLu9fWtQUhZODY2+53/u2V/Ol2z7hz9eT+ZYwK8HYOa08L 9Z5Rg4EuVGW6mOX1qd2cEUltCTliWVGFsyqo2AGNyjqeSOHTX5ya5HRf6dAZKiFccrybBJca7hy A6hWdpuXKBIrJShw6e1cvT+W+xzjPhAJK5yuU33lPcYqazBZ4mNanXPLbJ6jUj9r5zA== X-Received: by 2002:a62:b248:: with SMTP id x69mr4114190pfe.256.1551307831040; Wed, 27 Feb 2019 14:50:31 -0800 (PST) X-Google-Smtp-Source: AHgI3IaffC2Ar0aA7SbsAgBHwXiVeLRRQqnmuk5wiSDsEzcPdvGyIr4XWDzNVlZaVEbb5je0f0NG X-Received: by 2002:a62:b248:: with SMTP id x69mr4114135pfe.256.1551307830131; Wed, 27 Feb 2019 14:50:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307830; cv=none; d=google.com; s=arc-20160816; b=nSKjyDvb+BEcscLhQfJk5jt4ayJzoE2EM5KCdKtmpAA1kglKpfy1yN9Hm82P81Ngum +8hm/trg5vLgviCOQ/aazEndBC9eD2ENyJ6zXGHp3V6fu3rV8PCrBLU+PchSeojRx7Il ZQZ8fE17C9lUPOtZQYfidfffUG8QWQC87mkL3u+IJw4MFY84XiSjh2qk7HQA0sBej4Dq 9PXGvFAzMCBAV8jzPsOru04KtHAbA6+1t63UkVThbMbh2GuL4FaSm47dQJOIEQgylKqq E8S/VpJ2RQ7O3EV0dAxAuq1ZCqLq/9Nd0POsJA7Rm/HdILEwPbPoycAT5I2xpwXMMMee 4I2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=nQuXJ7LNYRRxRkGtcByfgDjWm6trYb32V1csoO7OD/Q=; b=NcGouC6gRGr3fgAgHOxECliDKSgzqUaFkqj/hxpyTvIjrrbBEArT7rtVcJJBOuN1RX 7ZAZDGWRRoNhjv0Pcah3q54DPqzjWLn/RLz7PveZVrMcYAmoAUyav+n1bdVDOzOOXLrR A/7BDiv9wiltpgE5L5Z7xaO8Klg1kJu9C6yyaHtQ5l5h16YTxOHXlHtfL4yErdJ3si5v ifz8JdSHt9wmnFziw0ykG99/5oGmOilfv/rDooInq1pQwYxny1iFfWFOCdSgrNk/DJbW KT3WVn2+RpS1+hiW3iwLAM+SmEjk5UWq3u8OXjZotsAMw71dDtBLiVeHO+7q7cdTa64X 8aSw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:30 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349389" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:28 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 02/10] acpi: Add HMAT to generic parsing tables Date: Wed, 27 Feb 2019 15:50:30 -0700 Message-Id: <20190227225038.20438-3-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000007, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP The Heterogeneous Memory Attribute Table (HMAT) header has different field lengths than the existing parsing uses. Add the HMAT type to the parsing rules so it may be generically parsed. Cc: Dan Williams Reviewed-by: Rafael J. Wysocki Signed-off-by: Keith Busch --- drivers/acpi/tables.c | 9 +++++++++ include/linux/acpi.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 7553774a22b7..3d0da38f94c6 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -51,6 +51,7 @@ static int acpi_apic_instance __initdata; enum acpi_subtable_type { ACPI_SUBTABLE_COMMON, + ACPI_SUBTABLE_HMAT, }; struct acpi_subtable_entry { @@ -232,6 +233,8 @@ acpi_get_entry_type(struct acpi_subtable_entry *entry) switch (entry->type) { case ACPI_SUBTABLE_COMMON: return entry->hdr->common.type; + case ACPI_SUBTABLE_HMAT: + return entry->hdr->hmat.type; } return 0; } @@ -242,6 +245,8 @@ acpi_get_entry_length(struct acpi_subtable_entry *entry) switch (entry->type) { case ACPI_SUBTABLE_COMMON: return entry->hdr->common.length; + case ACPI_SUBTABLE_HMAT: + return entry->hdr->hmat.length; } return 0; } @@ -252,6 +257,8 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) switch (entry->type) { case ACPI_SUBTABLE_COMMON: return sizeof(entry->hdr->common); + case ACPI_SUBTABLE_HMAT: + return sizeof(entry->hdr->hmat); } return 0; } @@ -259,6 +266,8 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) static enum acpi_subtable_type __init acpi_get_subtable_type(char *id) { + if (strncmp(id, ACPI_SIG_HMAT, 4) == 0) + return ACPI_SUBTABLE_HMAT; return ACPI_SUBTABLE_COMMON; } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 9494d42bf507..7c7515b0767e 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -143,6 +143,7 @@ enum acpi_address_range_id { /* Table Handlers */ union acpi_subtable_headers { struct acpi_subtable_header common; + struct acpi_hmat_structure hmat; }; typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table); From patchwork Wed Feb 27 22:50:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832371 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E212E1575 for ; Wed, 27 Feb 2019 22:50:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D04FB2E507 for ; Wed, 27 Feb 2019 22:50:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CE5B52E515; Wed, 27 Feb 2019 22:50:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A34A82E507 for ; Wed, 27 Feb 2019 22:50:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F11F88E0008; Wed, 27 Feb 2019 17:50:32 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id E99EA8E0004; Wed, 27 Feb 2019 17:50:32 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D88FA8E0008; Wed, 27 Feb 2019 17:50:32 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) by kanga.kvack.org (Postfix) with ESMTP id 9945C8E0004 for ; Wed, 27 Feb 2019 17:50:32 -0500 (EST) Received: by mail-pg1-f199.google.com with SMTP id h68so1307565pgc.3 for ; Wed, 27 Feb 2019 14:50:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=bUS1uO/cYSLbPkWpVFR7LXJ4nDHKbykGywBLXSWGn0k=; b=F2vIeRl0QK1R6aFlTYMf4gDnvogSkMmulra+D6zV/2EEGqgmnTyu5x5aUHkug6EDqc PVeX18hcXHketo9W+O/bcUpIGKguaYo+YN6XXvQ6rj7iMWGcC/xa/9CjmQNZIJmJdZSI JBntXBXCSMOBOdnyB9BkevQf1gfLYQTLCbKp9t9MFbriIaBm37onC15MJXTwLV9XYNo4 2BsRO7A+/NBlZLVOA/RVfvkP9VB3zBwz+8oZ/mCDVD+B5mcP056OLXNlLgVf9lj3W4r5 D2Sa9/Yn1Xan4iMp1Q7HLQdKq4jkpMKC9eQZ0pb9Klmuz+zrVhQLEvfLtSzX7JpyeSCP cwFg== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAub+Z3gwhuZpwU8N2n5metZpF1y7xHWFSgUuOAfs71cJGniLSlqf CR9JZTzul2OrgzOAtZfcDKCIXAZX3pwfgjNx6ZHvYD2oHt7kUlHKxdh4U8t6F0kvTBWv+WOX694 7hCCpH8RtgOZ3cpO6npi1JneOx/xHm06d67MHP472HJH11E58a1uNkW21COnJ3phqlg== X-Received: by 2002:a63:d49:: with SMTP id 9mr5282723pgn.27.1551307832208; Wed, 27 Feb 2019 14:50:32 -0800 (PST) X-Google-Smtp-Source: AHgI3IYsVGSfMAISkh47BVnF3LweLuQsbREnEYX9KQLkgOVARSCoMKAh9IDRwnXGF4dJ/rOfACW4 X-Received: by 2002:a63:d49:: with SMTP id 9mr5282633pgn.27.1551307830977; Wed, 27 Feb 2019 14:50:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307830; cv=none; d=google.com; s=arc-20160816; b=S4jLxz5OMtq9FthPGNsJp08G54W2rZ5KIgGM3rl/9Osb3dBX40gTLG3EXg5TaOf2fs /r9DIoAXDXsCV3JcPwPz4Q5xcvPiNLTPOh5nleh8zZV4QBng9QbYmMJpFE4Nij4o9/xi LM9p3KCf8fQ5sujYXSVWoxjA1+/bx2GIDK60Yr4mqXVmMGYxP4Ioxv0kZkgEfAL1kmGS WEzCy4clYfNr1LlsgQdfpwJrolmvrMVy8Chee5HrGrOcXCfxKo9p6m5I8CYxxGgEe9Wt zqWoi+pltKEaJQL+K9wEASXucirUikCyblm3x8naUuK5o3+jEDaAVn0olZqvDMxuzkt7 q4/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=bUS1uO/cYSLbPkWpVFR7LXJ4nDHKbykGywBLXSWGn0k=; b=PHe/nG0xloUDx+U82NFrNwC5yQ8s0+5xBx0NlbSWOoRJXoW6lt/MdwK8M5jZOVW93U cxiwh+VNfVsod5q+qNSV7YdrMq0esiy4DwKebIyHxD4E6hryU20i/5t7WdeA11WztPXq Uc/u3E1cKyViXfYm8WroXlEvslH29CkDLlxslfbGpFG0qc2xC+lE+U2DM2dtvwZxOuAA y+1VEhzFKh6GR1hY8JMG6dnAtJnJhVckL6Epp50tWOqQKhyw0yrm1p0ufhClFXzclEW8 OL3KkoafvIZ9sQZdvZbX0vHtJsifp2cDtMVN8l9EbGMuRIKJ0hqQsD47AiMDM4HCcfa1 /+3w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:30 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349399" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:29 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 03/10] acpi/hmat: Parse and report heterogeneous memory Date: Wed, 27 Feb 2019 15:50:31 -0700 Message-Id: <20190227225038.20438-4-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Systems may provide different memory types and export this information in the ACPI Heterogeneous Memory Attribute Table (HMAT). Parse these tables provided by the platform and report the memory access and caching attributes to the kernel messages. Reviewed-by: Rafael J. Wysocki Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/acpi/Kconfig | 1 + drivers/acpi/Makefile | 1 + drivers/acpi/hmat/Kconfig | 7 ++ drivers/acpi/hmat/Makefile | 1 + drivers/acpi/hmat/hmat.c | 237 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+) create mode 100644 drivers/acpi/hmat/Kconfig create mode 100644 drivers/acpi/hmat/Makefile create mode 100644 drivers/acpi/hmat/hmat.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 4e015c77e48e..283ee94224c6 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -475,6 +475,7 @@ config ACPI_REDUCED_HARDWARE_ONLY If you are unsure what to do, do not enable this option. source "drivers/acpi/nfit/Kconfig" +source "drivers/acpi/hmat/Kconfig" source "drivers/acpi/apei/Kconfig" source "drivers/acpi/dptf/Kconfig" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index bb857421c2e8..5d361e4e3405 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-$(CONFIG_ACPI_NFIT) += nfit/ +obj-$(CONFIG_ACPI_HMAT) += hmat/ obj-$(CONFIG_ACPI) += acpi_memhotplug.o obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o obj-$(CONFIG_ACPI_BATTERY) += battery.o diff --git a/drivers/acpi/hmat/Kconfig b/drivers/acpi/hmat/Kconfig new file mode 100644 index 000000000000..2f7111b7af62 --- /dev/null +++ b/drivers/acpi/hmat/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +config ACPI_HMAT + bool "ACPI Heterogeneous Memory Attribute Table Support" + depends on ACPI_NUMA + help + If set, this option has the kernel parse and report the + platform's ACPI HMAT (Heterogeneous Memory Attributes Table). diff --git a/drivers/acpi/hmat/Makefile b/drivers/acpi/hmat/Makefile new file mode 100644 index 000000000000..e909051d3d00 --- /dev/null +++ b/drivers/acpi/hmat/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ACPI_HMAT) := hmat.o diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c new file mode 100644 index 000000000000..99f711420f6d --- /dev/null +++ b/drivers/acpi/hmat/hmat.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Intel Corporation. + * + * Heterogeneous Memory Attributes Table (HMAT) representation + * + * This program parses and reports the platform's HMAT tables, and registers + * the applicable attributes with the node's interfaces. + */ + +#include +#include +#include +#include +#include +#include +#include + +static __initdata u8 hmat_revision; + +static __init const char *hmat_data_type(u8 type) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + return "Access Latency"; + case ACPI_HMAT_READ_LATENCY: + return "Read Latency"; + case ACPI_HMAT_WRITE_LATENCY: + return "Write Latency"; + case ACPI_HMAT_ACCESS_BANDWIDTH: + return "Access Bandwidth"; + case ACPI_HMAT_READ_BANDWIDTH: + return "Read Bandwidth"; + case ACPI_HMAT_WRITE_BANDWIDTH: + return "Write Bandwidth"; + default: + return "Reserved"; + } +} + +static __init const char *hmat_data_type_suffix(u8 type) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + return " nsec"; + case ACPI_HMAT_ACCESS_BANDWIDTH: + case ACPI_HMAT_READ_BANDWIDTH: + case ACPI_HMAT_WRITE_BANDWIDTH: + return " MB/s"; + default: + return ""; + } +} + +static __init u32 hmat_normalize(u16 entry, u64 base, u8 type) +{ + u32 value; + + /* + * Check for invalid and overflow values + */ + if (entry == 0xffff || !entry) + return 0; + else if (base > (UINT_MAX / (entry))) + return 0; + + /* + * Divide by the base unit for version 1, convert latency from + * picosenonds to nanoseconds if revision 2. + */ + value = entry * base; + if (hmat_revision == 1) { + if (value < 10) + return 0; + value = DIV_ROUND_UP(value, 10); + } else if (hmat_revision == 2) { + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + value = DIV_ROUND_UP(value, 1000); + break; + default: + break; + } + } + return value; +} + +static __init int hmat_parse_locality(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_locality *hmat_loc = (void *)header; + unsigned int init, targ, total_size, ipds, tpds; + u32 *inits, *targs, value; + u16 *entries; + u8 type; + + if (hmat_loc->header.length < sizeof(*hmat_loc)) { + pr_notice("HMAT: Unexpected locality header length: %d\n", + hmat_loc->header.length); + return -EINVAL; + } + + type = hmat_loc->data_type; + ipds = hmat_loc->number_of_initiator_Pds; + tpds = hmat_loc->number_of_target_Pds; + total_size = sizeof(*hmat_loc) + sizeof(*entries) * ipds * tpds + + sizeof(*inits) * ipds + sizeof(*targs) * tpds; + if (hmat_loc->header.length < total_size) { + pr_notice("HMAT: Unexpected locality header length:%d, minimum required:%d\n", + hmat_loc->header.length, total_size); + return -EINVAL; + } + + pr_info("HMAT: Locality: Flags:%02x Type:%s Initiator Domains:%d Target Domains:%d Base:%lld\n", + hmat_loc->flags, hmat_data_type(type), ipds, tpds, + hmat_loc->entry_base_unit); + + inits = (u32 *)(hmat_loc + 1); + targs = inits + ipds; + entries = (u16 *)(targs + tpds); + for (init = 0; init < ipds; init++) { + for (targ = 0; targ < tpds; targ++) { + value = hmat_normalize(entries[init * tpds + targ], + hmat_loc->entry_base_unit, + type); + pr_info(" Initiator-Target[%d-%d]:%d%s\n", + inits[init], targs[targ], value, + hmat_data_type_suffix(type)); + } + } + + return 0; +} + +static __init int hmat_parse_cache(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_cache *cache = (void *)header; + u32 attrs; + + if (cache->header.length < sizeof(*cache)) { + pr_notice("HMAT: Unexpected cache header length: %d\n", + cache->header.length); + return -EINVAL; + } + + attrs = cache->cache_attributes; + pr_info("HMAT: Cache: Domain:%d Size:%llu Attrs:%08x SMBIOS Handles:%d\n", + cache->memory_PD, cache->cache_size, attrs, + cache->number_of_SMBIOShandles); + + return 0; +} + +static int __init hmat_parse_address_range(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_proximity_domain *p = (void *)header; + struct memory_target *target = NULL; + + if (p->header.length != sizeof(*p)) { + pr_notice("HMAT: Unexpected address range header length: %d\n", + p->header.length); + return -EINVAL; + } + + if (hmat_revision == 1) + pr_info("HMAT: Memory (%#llx length %#llx) Flags:%04x Processor Domain:%d Memory Domain:%d\n", + p->reserved3, p->reserved4, p->flags, p->processor_PD, + p->memory_PD); + else + pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", + p->flags, p->processor_PD, p->memory_PD); + + return 0; +} + +static int __init hmat_parse_subtable(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_structure *hdr = (void *)header; + + if (!hdr) + return -EINVAL; + + switch (hdr->type) { + case ACPI_HMAT_TYPE_ADDRESS_RANGE: + return hmat_parse_address_range(header, end); + case ACPI_HMAT_TYPE_LOCALITY: + return hmat_parse_locality(header, end); + case ACPI_HMAT_TYPE_CACHE: + return hmat_parse_cache(header, end); + default: + return -EINVAL; + } +} + +static __init int hmat_init(void) +{ + struct acpi_table_header *tbl; + enum acpi_hmat_type i; + acpi_status status; + + if (srat_disabled()) + return 0; + + status = acpi_get_table(ACPI_SIG_HMAT, 0, &tbl); + if (ACPI_FAILURE(status)) + return 0; + + hmat_revision = tbl->revision; + switch (hmat_revision) { + case 1: + case 2: + break; + default: + pr_notice("Ignoring HMAT: Unknown revision:%d\n", hmat_revision); + goto out_put; + } + + for (i = ACPI_HMAT_TYPE_ADDRESS_RANGE; i < ACPI_HMAT_TYPE_RESERVED; i++) { + if (acpi_table_parse_entries(ACPI_SIG_HMAT, + sizeof(struct acpi_table_hmat), i, + hmat_parse_subtable, 0) < 0) { + pr_notice("Ignoring HMAT: Invalid table"); + goto out_put; + } + } +out_put: + acpi_put_table(tbl); + return 0; +} +subsys_initcall(hmat_init); From patchwork Wed Feb 27 22:50:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832373 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 595CD1575 for ; Wed, 27 Feb 2019 22:50:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 467B22E516 for ; Wed, 27 Feb 2019 22:50:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3A7A12E517; Wed, 27 Feb 2019 22:50:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 489512E516 for ; Wed, 27 Feb 2019 22:50:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B1A298E000B; Wed, 27 Feb 2019 17:50:34 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A7D288E0004; Wed, 27 Feb 2019 17:50:34 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8D0BF8E000A; Wed, 27 Feb 2019 17:50:34 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) by kanga.kvack.org (Postfix) with ESMTP id 46C198E0004 for ; Wed, 27 Feb 2019 17:50:34 -0500 (EST) Received: by mail-pf1-f197.google.com with SMTP id b15so14380200pfo.12 for ; Wed, 27 Feb 2019 14:50:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=4FnxMkSMns1stK+JdFF7HgFm+jH045Y2bIyh/LxZ+OQ=; b=BUX4zZlF4O/zWobP6LbMaPvIUui91EmyNGVrokfOI2wIOWzuVtmv3XbwMKLztu3EI7 1K1L29MrewT2pBmnFuVbfEs+A36kHtscKyws6f+ue5my5ae5Aj6NXw29MHwzygba+1MI obVYn1mge3ihWcsWcQaxAgU3WTaR/0z7IUoDJVMHo0gcMuJMHNV7isMnjxCtUgBvmQYL HoSmu69nmtc2+b73udmqsBDlqVsiiPGWoJTdqPdnF+VmFW2guQIDqgiYJ/GXiQxXcj5g hgVadZWgMbM+Np1XwkKwsTTO7uJ+WKLI/eyPEz5IkGUuXOk/tQsbga3nn/5nYvF2wOKP bNng== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuY4gAktd8/52N6rULqDEeHd0f/b6OemUwoRmn1pQiksVAtG60fu FX3n5gFrk46jjKhgOal9XMrA2rFhRY5e6lx+xNRls36KCORU1MoayU5gjG3fJQS5qmHc0f9lm5n 6HPJP8H8JC0yejhcHip+0DYdPi39LEEYl+3cPiCYG68HUy4H90QHPxF6nxy3iZUJHww== X-Received: by 2002:a63:360e:: with SMTP id d14mr5351638pga.179.1551307833908; Wed, 27 Feb 2019 14:50:33 -0800 (PST) X-Google-Smtp-Source: AHgI3IauEpNZjYqQaIXAU+/6BhEaoz7SFZIrwc1DaGVEtMtnm/69w2sle0GGiISf6U4IrG2+PFfw X-Received: by 2002:a63:360e:: with SMTP id d14mr5351526pga.179.1551307832318; Wed, 27 Feb 2019 14:50:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307832; cv=none; d=google.com; s=arc-20160816; b=AMARt/75YKbLzCiRr9wr8ucM3y46yqtwrYqwJVq2lJqiodRyC9UEfEsNw4IK5KUkRv o3S3DsGFuENPN9fk33WI/0PhY4HBqiQPziIBP9gXYUXWK/IRR3j/qE8rp8emyR6akWyq 4k1uRObzeMQ5SbR6RE/PDHo3qv7Jat7jBooPWwyUKL77pDLvqJ+03oFfgHb5moRGFGzE 1VcsX6oOlADkHOvV/dHtAME1w51Jx1DZWzPjEPFosp5j39oasm4g9QJGbUABaRVI53Eo LLyrcHvYLf1D6eWxSuepd82qJNDnOGt6No7787rfGCAHfv2zzya7qBMRev4+WNDbcQAg AzVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=4FnxMkSMns1stK+JdFF7HgFm+jH045Y2bIyh/LxZ+OQ=; b=u5xSGKshwtz4sZrHfimN1nRWF62cl71OtObJy4uESNkHaVEyLIeZRc8IqNopCcu5bS EsvaRUY98cQ+V1uu74HTbOvZM7Fg8o3UzP6XkbxQSJxKxgH1cvFS9miTbRIEkov6F53b OGaZQXnSFbBLNhzLTz5KHRZ52PlDYgNKO+mJ9MmXBFmCCXc0BRrJ8NAoUtWdbF6PcFWR Kn5NEqVeivjmBlF23A4afmUjposS6z6ElQdbhZVqr65/ojQ6r9kCdpWv8+ZsvS0BgF/u D8AKds5QnVwXURvptoSPCF/VSApo8BCTUphLQ48jys8ziGwOmcADXmlnnvgg5a2fp/qC 5iQw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:32 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:31 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349406" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:30 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 04/10] node: Link memory nodes to their compute nodes Date: Wed, 27 Feb 2019 15:50:32 -0700 Message-Id: <20190227225038.20438-5-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Systems may be constructed with various specialized nodes. Some nodes may provide memory, some provide compute devices that access and use that memory, and others may provide both. Nodes that provide memory are referred to as memory targets, and nodes that can initiate memory access are referred to as memory initiators. Memory targets will often have varying access characteristics from different initiators, and platforms may have ways to express those relationships. In preparation for these systems, provide interfaces for the kernel to export the memory relationship among different nodes memory targets and their initiators with symlinks to each other. If a system provides access locality for each initiator-target pair, nodes may be grouped into ranked access classes relative to other nodes. The new interface allows a subsystem to register relationships of varying classes if available and desired to be exported. A memory initiator may have multiple memory targets in the same access class. The target memory's initiators in a given class indicate the nodes access characteristics share the same performance relative to other linked initiator nodes. Each target within an initiator's access class, though, do not necessarily perform the same as each other. A memory target node may have multiple memory initiators. All linked initiators in a target's class have the same access characteristics to that target. The following example show the nodes' new sysfs hierarchy for a memory target node 'Y' with access class 0 from initiator node 'X': # symlinks -v /sys/devices/system/node/nodeX/access0/ relative: /sys/devices/system/node/nodeX/access0/targets/nodeY -> ../../nodeY # symlinks -v /sys/devices/system/node/nodeY/access0/ relative: /sys/devices/system/node/nodeY/access0/initiators/nodeX -> ../../nodeX The new attributes are added to the sysfs stable documentation. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- Documentation/ABI/stable/sysfs-devices-node | 25 ++++- drivers/base/node.c | 142 +++++++++++++++++++++++++++- include/linux/node.h | 7 +- 3 files changed, 171 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node index 3e90e1f3bf0a..fb843222a281 100644 --- a/Documentation/ABI/stable/sysfs-devices-node +++ b/Documentation/ABI/stable/sysfs-devices-node @@ -90,4 +90,27 @@ Date: December 2009 Contact: Lee Schermerhorn Description: The node's huge page size control/query attributes. - See Documentation/admin-guide/mm/hugetlbpage.rst \ No newline at end of file + See Documentation/admin-guide/mm/hugetlbpage.rst + +What: /sys/devices/system/node/nodeX/accessY/ +Date: December 2018 +Contact: Keith Busch +Description: + The node's relationship to other nodes for access class "Y". + +What: /sys/devices/system/node/nodeX/accessY/initiators/ +Date: December 2018 +Contact: Keith Busch +Description: + The directory containing symlinks to memory initiator + nodes that have class "Y" access to this target node's + memory. CPUs and other memory initiators in nodes not in + the list accessing this node's memory may have different + performance. + +What: /sys/devices/system/node/nodeX/classY/targets/ +Date: December 2018 +Contact: Keith Busch +Description: + The directory containing symlinks to memory targets that + this initiator node has class "Y" access. diff --git a/drivers/base/node.c b/drivers/base/node.c index 86d6cd92ce3d..6f4097680580 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,94 @@ static inline ssize_t node_read_cpulist(struct device *dev, static DEVICE_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL); static DEVICE_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); +/** + * struct node_access_nodes - Access class device to hold user visible + * relationships to other nodes. + * @dev: Device for this memory access class + * @list_node: List element in the node's access list + * @access: The access class rank + */ +struct node_access_nodes { + struct device dev; + struct list_head list_node; + unsigned access; +}; +#define to_access_nodes(dev) container_of(dev, struct node_access_nodes, dev) + +static struct attribute *node_init_access_node_attrs[] = { + NULL, +}; + +static struct attribute *node_targ_access_node_attrs[] = { + NULL, +}; + +static const struct attribute_group initiators = { + .name = "initiators", + .attrs = node_init_access_node_attrs, +}; + +static const struct attribute_group targets = { + .name = "targets", + .attrs = node_targ_access_node_attrs, +}; + +static const struct attribute_group *node_access_node_groups[] = { + &initiators, + &targets, + NULL, +}; + +static void node_remove_accesses(struct node *node) +{ + struct node_access_nodes *c, *cnext; + + list_for_each_entry_safe(c, cnext, &node->access_list, list_node) { + list_del(&c->list_node); + device_unregister(&c->dev); + } +} + +static void node_access_release(struct device *dev) +{ + kfree(to_access_nodes(dev)); +} + +static struct node_access_nodes *node_init_node_access(struct node *node, + unsigned access) +{ + struct node_access_nodes *access_node; + struct device *dev; + + list_for_each_entry(access_node, &node->access_list, list_node) + if (access_node->access == access) + return access_node; + + access_node = kzalloc(sizeof(*access_node), GFP_KERNEL); + if (!access_node) + return NULL; + + access_node->access = access; + dev = &access_node->dev; + dev->parent = &node->dev; + dev->release = node_access_release; + dev->groups = node_access_node_groups; + if (dev_set_name(dev, "access%u", access)) + goto free; + + if (device_register(dev)) + goto free_name; + + pm_runtime_no_callbacks(dev); + list_add_tail(&access_node->list_node, &node->access_list); + return access_node; +free_name: + kfree_const(dev->kobj.name); +free: + kfree(access_node); + return NULL; +} + #define K(x) ((x) << (PAGE_SHIFT - 10)) static ssize_t node_read_meminfo(struct device *dev, struct device_attribute *attr, char *buf) @@ -340,7 +429,7 @@ static int register_node(struct node *node, int num) void unregister_node(struct node *node) { hugetlb_unregister_node(node); /* no-op, if memoryless node */ - + node_remove_accesses(node); device_unregister(&node->dev); } @@ -372,6 +461,56 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) kobject_name(&node_devices[nid]->dev.kobj)); } +/** + * register_memory_node_under_compute_node - link memory node to its compute + * node for a given access class. + * @mem_node: Memory node number + * @cpu_node: Cpu node number + * @access: Access class to register + * + * Description: + * For use with platforms that may have separate memory and compute nodes. + * This function will export node relationships linking which memory + * initiator nodes can access memory targets at a given ranked access + * class. + */ +int register_memory_node_under_compute_node(unsigned int mem_nid, + unsigned int cpu_nid, + unsigned access) +{ + struct node *init_node, *targ_node; + struct node_access_nodes *initiator, *target; + int ret; + + if (!node_online(cpu_nid) || !node_online(mem_nid)) + return -ENODEV; + + init_node = node_devices[cpu_nid]; + targ_node = node_devices[mem_nid]; + initiator = node_init_node_access(init_node, access); + target = node_init_node_access(targ_node, access); + if (!initiator || !target) + return -ENOMEM; + + ret = sysfs_add_link_to_group(&initiator->dev.kobj, "targets", + &targ_node->dev.kobj, + dev_name(&targ_node->dev)); + if (ret) + return ret; + + ret = sysfs_add_link_to_group(&target->dev.kobj, "initiators", + &init_node->dev.kobj, + dev_name(&init_node->dev)); + if (ret) + goto err; + + return 0; + err: + sysfs_remove_link_from_group(&initiator->dev.kobj, "targets", + dev_name(&targ_node->dev)); + return ret; +} + int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) { struct device *obj; @@ -580,6 +719,7 @@ int __register_one_node(int nid) register_cpu_under_node(cpu, nid); } + INIT_LIST_HEAD(&node_devices[nid]->access_list); /* initialize work queue for memory hot plug */ init_node_hugetlb_work(nid); diff --git a/include/linux/node.h b/include/linux/node.h index 257bb3d6d014..f34688a203c1 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -17,11 +17,12 @@ #include #include +#include #include struct node { struct device dev; - + struct list_head access_list; #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS) struct work_struct node_work; #endif @@ -75,6 +76,10 @@ extern int register_mem_sect_under_node(struct memory_block *mem_blk, extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, unsigned long phys_index); +extern int register_memory_node_under_compute_node(unsigned int mem_nid, + unsigned int cpu_nid, + unsigned access); + #ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister, node_registration_func_t unregister); From patchwork Wed Feb 27 22:50:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832375 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CF9FD1575 for ; Wed, 27 Feb 2019 22:50:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB30B2E4DA for ; Wed, 27 Feb 2019 22:50:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B94E72E4E6; Wed, 27 Feb 2019 22:50:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 113F92E4EA for ; Wed, 27 Feb 2019 22:50:46 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DFF758E0009; Wed, 27 Feb 2019 17:50:34 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id DB1538E0004; Wed, 27 Feb 2019 17:50:34 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B17308E000A; Wed, 27 Feb 2019 17:50:34 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by kanga.kvack.org (Postfix) with ESMTP id 68F058E0009 for ; Wed, 27 Feb 2019 17:50:34 -0500 (EST) Received: by mail-pl1-f199.google.com with SMTP id e2so13495544pln.12 for ; Wed, 27 Feb 2019 14:50:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=hz9w91aIPkE0E9ap/WrfhsBJuY4OqRXIHLZmUsGEF7E=; b=PcN9qE5vEepQ9v+trqH18OnJqrFJscwMRcXZz05gee7eiydh4jCF9fXCtqa5WD8Xfq Npev6HY7WCAXo37C2qQiaZwre0VL1APwNB9ODrb85twX3tZbMKOeVNEXpwhMU6+avEXl CNK4F0mOD2Nm+elVYlXLXpTnTdBfK/k5z92HNfYppXIkM7uGpLJoFWjxnTxWXbm8caRl XVlvsdga1m6m/orRsJ7RxKVo+0Iqca2QGsM+xVJ8ODw5xaHmKT+NxUjjLPCWI6RNRkvg aKz9eeGMHCntp7t/WRtJn8+4Hl8N7AtQe3rmEbphVwGk5YgnS80Atl8NNzWEPIxS7H35 uNxQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuaevupagATBmGpuBRKhaNAq33NoP10FGS30yzVEGk8+MFiqJQLz FjXjKvPXakLyaR3CWDvv5wYsijOX0gitviClBh7s641yNRvwbOUQD4Exk1XXfEXPIX7RuCk+oax KdTvTEDWoVWner4oXClyOUpx2ybK4PJ5pKL2awzjGD2R1pKKBQQHnk+8xR5t+CefD0w== X-Received: by 2002:a17:902:2f03:: with SMTP id s3mr4527383plb.277.1551307834085; Wed, 27 Feb 2019 14:50:34 -0800 (PST) X-Google-Smtp-Source: AHgI3IbCM16F/rQ6lUaObpr/c0Bffjynq6sg+tmIEGTvcyDTzfPjLfwy5JwsfgVei3FZM8PCElLN X-Received: by 2002:a17:902:2f03:: with SMTP id s3mr4527292plb.277.1551307832877; Wed, 27 Feb 2019 14:50:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307832; cv=none; d=google.com; s=arc-20160816; b=izm8/+qBlX9Q5uvM3mpZlTwg1NG+Wi7EKb9QOyWYQmDAocBVGV1bHDn3CZVuvwttkd yOqHA9dkFGTYIrMcfrHIRAsdJZF2fUacbMMybYpFI0s/fgvAKBFU2FaC2sM/rudbrTlb KHxDYb7ZDW0GNDIrS541ct17aNDzdSlsycvXLH6j3jU3HrvqCbVb8gVyFiq9JUrwQeCt WhIseE6JOQMLP1allo0Z418sTsctlSab9aAXD0gZfuevI7UdsULQM3huF8e80qjYpmgy WexxfbLJTeBvoKKB5dbH7w0Cox8GqH22CFBYKWc/AtFYAUjUMnfN1Rmi2DcyotLo5aSE Yd5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=hz9w91aIPkE0E9ap/WrfhsBJuY4OqRXIHLZmUsGEF7E=; b=k+X1OFIhw078wO0jfCwYvLNGdGF3dbtGDN3EET7trBdlc7h76dWJcX3SK1MdAig0KD 0LhvDvSX8Dslo0bN4Byojrmdwm/w1wS6iqagbVZpq4PEaKDr+UQFc9K6ZR9v/Q+AW9O2 MHB8P8iJqK1L2qmYR7JJkZPuV8v4E8zmNG7ofR4MEEgWBRAnYDc1/+smVl601Od+wUbc ZPCMxZPCPbTFBdXM7Q+QXhwZFMNJ294hTdH7l5rPE7xjgxqpB89CgKjNXJte86ZcfynU FAOj+gDzUpJRwsTutkIYELXi56P9xZsqx0k/8alr3a9mxU+djopL00U51JgMbJkm4yMk IGfQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:32 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349410" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:31 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 05/10] node: Add heterogenous memory access attributes Date: Wed, 27 Feb 2019 15:50:33 -0700 Message-Id: <20190227225038.20438-6-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Heterogeneous memory systems provide memory nodes with different latency and bandwidth performance attributes. Provide a new kernel interface for subsystems to register the attributes under the memory target node's initiator access class. If the system provides this information, applications may query these attributes when deciding which node to request memory. The following example shows the new sysfs hierarchy for a node exporting performance attributes: # tree -P "read*|write*"/sys/devices/system/node/nodeY/accessZ/initiators/ /sys/devices/system/node/nodeY/accessZ/initiators/ |-- read_bandwidth |-- read_latency |-- write_bandwidth `-- write_latency The bandwidth is exported as MB/s and latency is reported in nanoseconds. The values are taken from the platform as reported by the manufacturer. Memory accesses from an initiator node that is not one of the memory's access "Z" initiator nodes linked in the same directory may observe different performance than reported here. When a subsystem makes use of this interface, initiators of a different access number may not have the same performance relative to initiators in other access numbers, or omitted from the any access class' initiators. Descriptions for memory access initiator performance access attributes are added to sysfs stable documentation. Signed-off-by: Keith Busch --- Documentation/ABI/stable/sysfs-devices-node | 28 ++++++++++++++ drivers/base/Kconfig | 8 ++++ drivers/base/node.c | 59 +++++++++++++++++++++++++++++ include/linux/node.h | 26 +++++++++++++ 4 files changed, 121 insertions(+) diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node index fb843222a281..41cb9345e1e0 100644 --- a/Documentation/ABI/stable/sysfs-devices-node +++ b/Documentation/ABI/stable/sysfs-devices-node @@ -114,3 +114,31 @@ Contact: Keith Busch Description: The directory containing symlinks to memory targets that this initiator node has class "Y" access. + +What: /sys/devices/system/node/nodeX/accessY/initiators/read_bandwidth +Date: December 2018 +Contact: Keith Busch +Description: + This node's read bandwidth in MB/s when accessed from + nodes found in this access class's linked initiators. + +What: /sys/devices/system/node/nodeX/accessY/initiators/read_latency +Date: December 2018 +Contact: Keith Busch +Description: + This node's read latency in nanoseconds when accessed + from nodes found in this access class's linked initiators. + +What: /sys/devices/system/node/nodeX/accessY/initiators/write_bandwidth +Date: December 2018 +Contact: Keith Busch +Description: + This node's write bandwidth in MB/s when accessed from + found in this access class's linked initiators. + +What: /sys/devices/system/node/nodeX/accessY/initiators/write_latency +Date: December 2018 +Contact: Keith Busch +Description: + This node's write latency in nanoseconds when access + from nodes found in this class's linked initiators. diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 059700ea3521..a7438a58c250 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -149,6 +149,14 @@ config DEBUG_TEST_DRIVER_REMOVE unusable. You should say N here unless you are explicitly looking to test this functionality. +config HMEM_REPORTING + bool + default n + depends on NUMA + help + Enable reporting for heterogenous memory access attributes under + their non-uniform memory nodes. + source "drivers/base/test/Kconfig" config SYS_HYPERVISOR diff --git a/drivers/base/node.c b/drivers/base/node.c index 6f4097680580..2de546a040a5 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -71,6 +71,9 @@ struct node_access_nodes { struct device dev; struct list_head list_node; unsigned access; +#ifdef CONFIG_HMEM_REPORTING + struct node_hmem_attrs hmem_attrs; +#endif }; #define to_access_nodes(dev) container_of(dev, struct node_access_nodes, dev) @@ -148,6 +151,62 @@ static struct node_access_nodes *node_init_node_access(struct node *node, return NULL; } +#ifdef CONFIG_HMEM_REPORTING +#define ACCESS_ATTR(name) \ +static ssize_t name##_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + return sprintf(buf, "%u\n", to_access_nodes(dev)->hmem_attrs.name); \ +} \ +static DEVICE_ATTR_RO(name); + +ACCESS_ATTR(read_bandwidth) +ACCESS_ATTR(read_latency) +ACCESS_ATTR(write_bandwidth) +ACCESS_ATTR(write_latency) + +static struct attribute *access_attrs[] = { + &dev_attr_read_bandwidth.attr, + &dev_attr_read_latency.attr, + &dev_attr_write_bandwidth.attr, + &dev_attr_write_latency.attr, + NULL, +}; + +/** + * node_set_perf_attrs - Set the performance values for given access class + * @nid: Node identifier to be set + * @hmem_attrs: Heterogeneous memory performance attributes + * @access: The access class the for the given attributes + */ +void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, + unsigned access) +{ + struct node_access_nodes *c; + struct node *node; + int i; + + if (WARN_ON_ONCE(!node_online(nid))) + return; + + node = node_devices[nid]; + c = node_init_node_access(node, access); + if (!c) + return; + + c->hmem_attrs = *hmem_attrs; + for (i = 0; access_attrs[i] != NULL; i++) { + if (sysfs_add_file_to_group(&c->dev.kobj, access_attrs[i], + "initiators")) { + pr_info("failed to add performance attribute to node %d\n", + nid); + break; + } + } +} +#endif + #define K(x) ((x) << (PAGE_SHIFT - 10)) static ssize_t node_read_meminfo(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/include/linux/node.h b/include/linux/node.h index f34688a203c1..45e14e1e0c18 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -20,6 +20,32 @@ #include #include +/** + * struct node_hmem_attrs - heterogeneous memory performance attributes + * + * @read_bandwidth: Read bandwidth in MB/s + * @write_bandwidth: Write bandwidth in MB/s + * @read_latency: Read latency in nanoseconds + * @write_latency: Write latency in nanoseconds + */ +struct node_hmem_attrs { + unsigned int read_bandwidth; + unsigned int write_bandwidth; + unsigned int read_latency; + unsigned int write_latency; +}; + +#ifdef CONFIG_HMEM_REPORTING +void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, + unsigned access); +#else +static inline void node_set_perf_attrs(unsigned int nid, + struct node_hmem_attrs *hmem_attrs, + unsigned access) +{ +} +#endif + struct node { struct device dev; struct list_head access_list; From patchwork Wed Feb 27 22:50:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7531E1669 for ; Wed, 27 Feb 2019 22:50:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 643F02E4FF for ; Wed, 27 Feb 2019 22:50:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58B932E511; Wed, 27 Feb 2019 22:50:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89FB02E4FF for ; Wed, 27 Feb 2019 22:50:48 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1F1308E000A; Wed, 27 Feb 2019 17:50:36 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1A6248E0004; Wed, 27 Feb 2019 17:50:36 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E78978E000A; Wed, 27 Feb 2019 17:50:35 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by kanga.kvack.org (Postfix) with ESMTP id A1CAA8E0004 for ; Wed, 27 Feb 2019 17:50:35 -0500 (EST) Received: by mail-pf1-f199.google.com with SMTP id y66so14373150pfg.16 for ; Wed, 27 Feb 2019 14:50:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=17OD5DxVPEfXl7F6sLMWaqS7bcMAwEh9QfsaU/GPtRQ=; b=oFt3jiP+kEUDHGFd2a0OSgSo18D6LpCexUReXBgorNPl0Wu+PuEP502K36LdqL0dhP p9471hi6hy8UhZqrcJnF3VMjwVdF5jPWi8xHWyLTk1LmBNBsofLrUYYIleZgpxU8rXG7 4KzeGVK2M97JKYWs6p2UKZGDyDgkOmV6i3uDkII+I4l3+UjpFkyxJeiGAAfbqUoPJTfG zWJWp9Ib6qzcTbws4NEPzkVVYAC+vWO4cDN/+wAzujPl/MILYgMg9agMWrPYAHu2vza3 u9ZjKWSg8QiNJfcZEgKGHszsyMSbzGlNVD9cqWj6H6YzBZKqtETaZ5pujsjikvZ/RYc5 D3cA== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAubOis1qybYBXneS3u3HEZCGzIra0DADs99EYELXAj6kap95BXLK iGhveOXyrykWuioSllLjfvLHCoEnFGvJE7y9QZe/IMi7CJe+j8L4FX6LOoYu3QJOHnS5HlD2WH3 pekQiXqD/RC/zVfkDoUvmRP20wDVV5GA+Cfj0MsZyKRvhMwR0b/wlXPHl0krObKJvzQ== X-Received: by 2002:a63:545:: with SMTP id 66mr5283391pgf.102.1551307835260; Wed, 27 Feb 2019 14:50:35 -0800 (PST) X-Google-Smtp-Source: AHgI3IaBDbAQnDO5ifrw5Hqr7aQtf9/XmlDog9kY4Lr/Ec4JecZaSzCFuVKs4KXiCmrFXGIKLE/4 X-Received: by 2002:a63:545:: with SMTP id 66mr5283271pgf.102.1551307833600; Wed, 27 Feb 2019 14:50:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307833; cv=none; d=google.com; s=arc-20160816; b=0dgBH7fk2jclGa2LuSI006gZOqVfWVu4G7RMA78v3FRav/YR0Uwnw6XXJREyt0npri 8p+qWiu1CbEvjGFJcYDPF3NZHKcIeUIHhU++qfruYU1uJfXI1UcMzLVqcYLbIzN/n4YW 1yoOCbNT6HdbZm5DJS5KsU6PBUCEkfVJSKzK5djPFGlyP3o6tXaXXcoqUlKhpsN3VDkF 9O21JILKTU/LFiPB8EVJ8IHllKluapyxRb4YdTdmSVwP4CSE4X98B7ApLtdiI+T1RddJ Ngb6t6MWI9pf8yKgFYMxcZXKawPLThHiA7PUpRMKIBTo8IqIH7mClp2Vx4/NnYqI4sqf 3Q/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=17OD5DxVPEfXl7F6sLMWaqS7bcMAwEh9QfsaU/GPtRQ=; b=WrdVtr/ZoSBy3fIER2m/PuKuYU9eaVfFGLGWSFqD6E3KR9aaGFDgthzalgs7UESdFb JjG4dt12u85YBwROdW6C1GqSqiPmCeqDHpQmqTjLOp5xEIGY35Iq7abv9wnxbVebuobz Wye3V7hz3xRdGL3Q0CAL0BRXWVNSq0YfbwbZQQan7QxQ7Nt/DxdAqUzfl0N3e3mk1EYG jhZWRng/BPcqEgioe/GNW9MDSi6Ipsf9DRWZjTjhVwLr30SHTfrbQyStCUG4emPU/t1B E/hS0i3XYi2wVzTwFsN3kCpKPeWNsNE3XUWeVy+3qo/8HA2k1hOUlMNn/fv1Zy4Nw2/M mH8g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.33 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:33 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349415" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:32 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 06/10] node: Add memory-side caching attributes Date: Wed, 27 Feb 2019 15:50:34 -0700 Message-Id: <20190227225038.20438-7-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP System memory may have caches to help improve access speed to frequently requested address ranges. While the system provided cache is transparent to the software accessing these memory ranges, applications can optimize their own access based on cache attributes. Provide a new API for the kernel to register these memory-side caches under the memory node that provides it. The new sysfs representation is modeled from the existing cpu cacheinfo attributes, as seen from /sys/devices/system/cpu//cache/. Unlike CPU cacheinfo though, the node cache level is reported from the view of the memory. A higher level number is nearer to the CPU, while lower levels are closer to the last level memory. The exported attributes are the cache size, the line size, associativity indexing, and write back policy, and add the attributes for the system memory caches to sysfs stable documentation. Signed-off-by: Keith Busch --- Documentation/ABI/stable/sysfs-devices-node | 34 +++++++ drivers/base/node.c | 151 ++++++++++++++++++++++++++++ include/linux/node.h | 39 +++++++ 3 files changed, 224 insertions(+) diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node index 41cb9345e1e0..970fef47e6cd 100644 --- a/Documentation/ABI/stable/sysfs-devices-node +++ b/Documentation/ABI/stable/sysfs-devices-node @@ -142,3 +142,37 @@ Contact: Keith Busch Description: This node's write latency in nanoseconds when access from nodes found in this class's linked initiators. + +What: /sys/devices/system/node/nodeX/memory_side_cache/indexY/ +Date: December 2018 +Contact: Keith Busch +Description: + The directory containing attributes for the memory-side cache + level 'Y'. + +What: /sys/devices/system/node/nodeX/memory_side_cache/indexY/indexing +Date: December 2018 +Contact: Keith Busch +Description: + The caches associativity indexing: 0 for direct mapped, + non-zero if indexed. + +What: /sys/devices/system/node/nodeX/memory_side_cache/indexY/line_size +Date: December 2018 +Contact: Keith Busch +Description: + The number of bytes accessed from the next cache level on a + cache miss. + +What: /sys/devices/system/node/nodeX/memory_side_cache/indexY/size +Date: December 2018 +Contact: Keith Busch +Description: + The size of this memory side cache in bytes. + +What: /sys/devices/system/node/nodeX/memory_side_cache/indexY/write_policy +Date: December 2018 +Contact: Keith Busch +Description: + The cache write policy: 0 for write-back, 1 for write-through, + other or unknown. diff --git a/drivers/base/node.c b/drivers/base/node.c index 2de546a040a5..8598fcbd2a17 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -205,6 +205,155 @@ void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, } } } + +/** + * struct node_cache_info - Internal tracking for memory node caches + * @dev: Device represeting the cache level + * @node: List element for tracking in the node + * @cache_attrs:Attributes for this cache level + */ +struct node_cache_info { + struct device dev; + struct list_head node; + struct node_cache_attrs cache_attrs; +}; +#define to_cache_info(device) container_of(device, struct node_cache_info, dev) + +#define CACHE_ATTR(name, fmt) \ +static ssize_t name##_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + return sprintf(buf, fmt "\n", to_cache_info(dev)->cache_attrs.name);\ +} \ +DEVICE_ATTR_RO(name); + +CACHE_ATTR(size, "%llu") +CACHE_ATTR(line_size, "%u") +CACHE_ATTR(indexing, "%u") +CACHE_ATTR(write_policy, "%u") + +static struct attribute *cache_attrs[] = { + &dev_attr_indexing.attr, + &dev_attr_size.attr, + &dev_attr_line_size.attr, + &dev_attr_write_policy.attr, + NULL, +}; +ATTRIBUTE_GROUPS(cache); + +static void node_cache_release(struct device *dev) +{ + kfree(dev); +} + +static void node_cacheinfo_release(struct device *dev) +{ + struct node_cache_info *info = to_cache_info(dev); + kfree(info); +} + +static void node_init_cache_dev(struct node *node) +{ + struct device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return; + + dev->parent = &node->dev; + dev->release = node_cache_release; + if (dev_set_name(dev, "memory_side_cache")) + goto free_dev; + + if (device_register(dev)) + goto free_name; + + pm_runtime_no_callbacks(dev); + node->cache_dev = dev; + return; +free_name: + kfree_const(dev->kobj.name); +free_dev: + kfree(dev); +} + +/** + * node_add_cache() - add cache attribute to a memory node + * @nid: Node identifier that has new cache attributes + * @cache_attrs: Attributes for the cache being added + */ +void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs) +{ + struct node_cache_info *info; + struct device *dev; + struct node *node; + + if (!node_online(nid) || !node_devices[nid]) + return; + + node = node_devices[nid]; + list_for_each_entry(info, &node->cache_attrs, node) { + if (info->cache_attrs.level == cache_attrs->level) { + dev_warn(&node->dev, + "attempt to add duplicate cache level:%d\n", + cache_attrs->level); + return; + } + } + + if (!node->cache_dev) + node_init_cache_dev(node); + if (!node->cache_dev) + return; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return; + + dev = &info->dev; + dev->parent = node->cache_dev; + dev->release = node_cacheinfo_release; + dev->groups = cache_groups; + if (dev_set_name(dev, "index%d", cache_attrs->level)) + goto free_cache; + + info->cache_attrs = *cache_attrs; + if (device_register(dev)) { + dev_warn(&node->dev, "failed to add cache level:%d\n", + cache_attrs->level); + goto free_name; + } + pm_runtime_no_callbacks(dev); + list_add_tail(&info->node, &node->cache_attrs); + return; +free_name: + kfree_const(dev->kobj.name); +free_cache: + kfree(info); +} + +static void node_remove_caches(struct node *node) +{ + struct node_cache_info *info, *next; + + if (!node->cache_dev) + return; + + list_for_each_entry_safe(info, next, &node->cache_attrs, node) { + list_del(&info->node); + device_unregister(&info->dev); + } + device_unregister(node->cache_dev); +} + +static void node_init_caches(unsigned int nid) +{ + INIT_LIST_HEAD(&node_devices[nid]->cache_attrs); +} +#else +static void node_init_caches(unsigned int nid) { } +static void node_remove_caches(struct node *node) { } #endif #define K(x) ((x) << (PAGE_SHIFT - 10)) @@ -489,6 +638,7 @@ void unregister_node(struct node *node) { hugetlb_unregister_node(node); /* no-op, if memoryless node */ node_remove_accesses(node); + node_remove_caches(node); device_unregister(&node->dev); } @@ -781,6 +931,7 @@ int __register_one_node(int nid) INIT_LIST_HEAD(&node_devices[nid]->access_list); /* initialize work queue for memory hot plug */ init_node_hugetlb_work(nid); + node_init_caches(nid); return error; } diff --git a/include/linux/node.h b/include/linux/node.h index 45e14e1e0c18..8fa350e01acc 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -35,10 +35,45 @@ struct node_hmem_attrs { unsigned int write_latency; }; +enum cache_indexing { + NODE_CACHE_DIRECT_MAP, + NODE_CACHE_INDEXED, + NODE_CACHE_OTHER, +}; + +enum cache_write_policy { + NODE_CACHE_WRITE_BACK, + NODE_CACHE_WRITE_THROUGH, + NODE_CACHE_WRITE_OTHER, +}; + +/** + * struct node_cache_attrs - system memory caching attributes + * + * @indexing: The ways memory blocks may be placed in cache + * @write_policy: Write back or write through policy + * @size: Total size of cache in bytes + * @line_size: Number of bytes fetched on a cache miss + * @level: The cache hierarchy level + */ +struct node_cache_attrs { + enum cache_indexing indexing; + enum cache_write_policy write_policy; + u64 size; + u16 line_size; + u8 level; +}; + #ifdef CONFIG_HMEM_REPORTING +void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs); void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, unsigned access); #else +static inline void node_add_cache(unsigned int nid, + struct node_cache_attrs *cache_attrs) +{ +} + static inline void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, unsigned access) @@ -52,6 +87,10 @@ struct node { #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS) struct work_struct node_work; #endif +#ifdef CONFIG_HMEM_REPORTING + struct list_head cache_attrs; + struct device *cache_dev; +#endif }; struct memory_block; From patchwork Wed Feb 27 22:50:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832381 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C6491575 for ; Wed, 27 Feb 2019 22:50:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 263202E4D3 for ; Wed, 27 Feb 2019 22:50:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 248B82E506; Wed, 27 Feb 2019 22:50:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D5BC2E50C for ; Wed, 27 Feb 2019 22:50:54 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 096F68E000C; Wed, 27 Feb 2019 17:50:37 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id F3B258E0004; Wed, 27 Feb 2019 17:50:36 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C80878E000E; Wed, 27 Feb 2019 17:50:36 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by kanga.kvack.org (Postfix) with ESMTP id 7B7B38E000C for ; Wed, 27 Feb 2019 17:50:36 -0500 (EST) Received: by mail-pf1-f199.google.com with SMTP id q21so14354191pfi.17 for ; Wed, 27 Feb 2019 14:50:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=ndaO53js3iiP2Wak8ISaGGOPtY5GnKB1dyP3ekZhGro=; b=bMtj7XGKUH5FdEIdZbMnxCYZRsZH81ITSt305lwiw1uZYdbwI7sJHdtYba2O4dmgOF tWEmZI+kSLkTmzKcf8oQ7zSdNKlDaYejn49cU8IcoTsU1Gfx7XZ7vJBIz9vLDgbcJORI Ri/FqdgdY2ojhw5iiZVKgSuTD+T/pclIPGodKWtQVZsv7ezav71F4II8DVvuRpKiOWyv 16epxTa8nsKPIGu4kg06BeF/CCTyzP0ENPzAxeYuGi4bvVsmCVBB6fZI3hRBiUzUWM2G Z+wGa3AgnsZyVE7TdHtf+/S79XtNWrt1RqOL0LH2BRA7/bAWrft7bkisQARYHXdEB1SF AztQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuZn/gI1k3/Jup33bX8zbFcbyPHMTRIYNnB21Rd6OR/8+hWRIS1g 6m6Te8NdvqHsbD+ajqJosy81CDC+ftstN5KeTxpBiCEaheRTbIK/MzRG+Tq7xcPbFTPbfC3Dc4x Otj/3eoR2VvLwK+fLdnQBv3f0iD+m7i636I7FoGrZ4oUaf/KfbgKRuvJzHj5DbhaqLQ== X-Received: by 2002:a63:2a96:: with SMTP id q144mr5283103pgq.338.1551307836103; Wed, 27 Feb 2019 14:50:36 -0800 (PST) X-Google-Smtp-Source: AHgI3IY2TBDsnfhUoPvDQTghHCIMrnUx6H15BvQ5ZYmZ44e3x3QUHLn8azBemzgafFsGMdYMaCKR X-Received: by 2002:a63:2a96:: with SMTP id q144mr5282978pgq.338.1551307834473; Wed, 27 Feb 2019 14:50:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307834; cv=none; d=google.com; s=arc-20160816; b=0CH2z6/CFbYgt4FnDm7z74nzFHfTfbhom0J8XgewNcAY/dACGpf9/R1QVb+LVj89QH ENeo+h/HzFbZifpEGhQ52rfUQtaYYAM1IbtqasW7r92fvOw/S7AMA2xEhc8Qif02wJnT OUS4vTo6gy2LbJXeJHNnsRGq4RdrjnrQcDeWAOviFMJHxtL8dmZjt14balN9Ib+aGxop 3stwSxmMP1V9i01e8LeNb86Qn9H0r2/kIWURPbyhF7Y/TQ/ncNXgHr2nGNQwb+wHSOU6 /K02e2HVoE0yln0RMKbhtz//uXT2jQi6GV3ZFnoLKdfpZBNjhVSGVgSiE+C0hgZCrmZo w+fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=ndaO53js3iiP2Wak8ISaGGOPtY5GnKB1dyP3ekZhGro=; b=nPhzon7kXvuUuD8+LdK/th9dyizKXtRRzZPzzmW/OQqZgct7gcBsBm/yVCwmh3GyJi CE7rJAP9JX3hxhsbCC1L1DBJ0/PjpqDnDHe2/PpON47/YGkNxyLgSGgTVSI0gNJsrvpL hGr5UC1IDdHHqRGd9unRZ6B8Me4H8JN+4YuQVxXqGz+Kw7T/6UDeWB8J7EOMWqalYLW2 E/XOix7hcc0jINCBtdzYp3lMr+IdYWVDV5joy5IUjCO/tXu6tvv0zpnuvGixxlm9a4qs EuqAOA2ODKQwqhsoFa/PbZO33cpO+ppy3ojr7GIJVbXroxMlQM7uUVag3+yi7O5BNsKi jU4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:34 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349419" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:33 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 07/10] acpi/hmat: Register processor domain to its memory Date: Wed, 27 Feb 2019 15:50:35 -0700 Message-Id: <20190227225038.20438-8-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP If the HMAT Subsystem Address Range provides a valid processor proximity domain for a memory domain, or a processor domain matches the performance access of the valid processor proximity domain, register the memory target with that initiator so this relationship will be visible under the node's sysfs directory. Since HMAT requires valid address ranges have an equivalent SRAT entry, verify each memory target satisfies this requirement. Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- drivers/acpi/hmat/Kconfig | 3 +- drivers/acpi/hmat/hmat.c | 395 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 396 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/hmat/Kconfig b/drivers/acpi/hmat/Kconfig index 2f7111b7af62..13cddd612a52 100644 --- a/drivers/acpi/hmat/Kconfig +++ b/drivers/acpi/hmat/Kconfig @@ -4,4 +4,5 @@ config ACPI_HMAT depends on ACPI_NUMA help If set, this option has the kernel parse and report the - platform's ACPI HMAT (Heterogeneous Memory Attributes Table). + platform's ACPI HMAT (Heterogeneous Memory Attributes Table), + and register memory initiators with their targets. diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c index 99f711420f6d..bb6a11653729 100644 --- a/drivers/acpi/hmat/hmat.c +++ b/drivers/acpi/hmat/hmat.c @@ -13,11 +13,105 @@ #include #include #include +#include #include #include static __initdata u8 hmat_revision; +static __initdata LIST_HEAD(targets); +static __initdata LIST_HEAD(initiators); +static __initdata LIST_HEAD(localities); + +/* + * The defined enum order is used to prioritize attributes to break ties when + * selecting the best performing node. + */ +enum locality_types { + WRITE_LATENCY, + READ_LATENCY, + WRITE_BANDWIDTH, + READ_BANDWIDTH, +}; + +static struct memory_locality *localities_types[4]; + +struct memory_target { + struct list_head node; + unsigned int memory_pxm; + unsigned int processor_pxm; + struct node_hmem_attrs hmem_attrs; +}; + +struct memory_initiator { + struct list_head node; + unsigned int processor_pxm; +}; + +struct memory_locality { + struct list_head node; + struct acpi_hmat_locality *hmat_loc; +}; + +static __init struct memory_initiator *find_mem_initiator(unsigned int cpu_pxm) +{ + struct memory_initiator *intitator; + + list_for_each_entry(intitator, &initiators, node) + if (intitator->processor_pxm == cpu_pxm) + return intitator; + return NULL; +} + +static __init struct memory_target *find_mem_target(unsigned int mem_pxm) +{ + struct memory_target *target; + + list_for_each_entry(target, &targets, node) + if (target->memory_pxm == mem_pxm) + return target; + return NULL; +} + +static __init void alloc_memory_initiator(unsigned int cpu_pxm) +{ + struct memory_initiator *intitator; + + if (pxm_to_node(cpu_pxm) == NUMA_NO_NODE) + return; + + intitator = find_mem_initiator(cpu_pxm); + if (intitator) + return; + + intitator = kzalloc(sizeof(*intitator), GFP_KERNEL); + if (!intitator) + return; + + intitator->processor_pxm = cpu_pxm; + list_add_tail(&intitator->node, &initiators); +} + +static __init void alloc_memory_target(unsigned int mem_pxm) +{ + struct memory_target *target; + + if (pxm_to_node(mem_pxm) == NUMA_NO_NODE) + return; + + target = find_mem_target(mem_pxm); + if (target) + return; + + target = kzalloc(sizeof(*target), GFP_KERNEL); + if (!target) + return; + + target->memory_pxm = mem_pxm; + target->processor_pxm = PXM_INVAL; + list_add_tail(&target->node, &targets); +} + static __init const char *hmat_data_type(u8 type) { switch (type) { @@ -89,14 +183,83 @@ static __init u32 hmat_normalize(u16 entry, u64 base, u8 type) return value; } +static __init void hmat_update_target_access(struct memory_target *target, + u8 type, u32 value) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + target->hmem_attrs.read_latency = value; + target->hmem_attrs.write_latency = value; + break; + case ACPI_HMAT_READ_LATENCY: + target->hmem_attrs.read_latency = value; + break; + case ACPI_HMAT_WRITE_LATENCY: + target->hmem_attrs.write_latency = value; + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + target->hmem_attrs.read_bandwidth = value; + target->hmem_attrs.write_bandwidth = value; + break; + case ACPI_HMAT_READ_BANDWIDTH: + target->hmem_attrs.read_bandwidth = value; + break; + case ACPI_HMAT_WRITE_BANDWIDTH: + target->hmem_attrs.write_bandwidth = value; + break; + default: + break; + } +} + +static __init void hmat_add_locality(struct acpi_hmat_locality *hmat_loc) +{ + struct memory_locality *loc; + + loc = kzalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { + pr_notice_once("Failed to allocate HMAT locality\n"); + return; + } + + loc->hmat_loc = hmat_loc; + list_add_tail(&loc->node, &localities); + + switch (hmat_loc->data_type) { + case ACPI_HMAT_ACCESS_LATENCY: + localities_types[READ_LATENCY] = loc; + localities_types[WRITE_LATENCY] = loc; + break; + case ACPI_HMAT_READ_LATENCY: + localities_types[READ_LATENCY] = loc; + break; + case ACPI_HMAT_WRITE_LATENCY: + localities_types[WRITE_LATENCY] = loc; + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + localities_types[READ_BANDWIDTH] = loc; + localities_types[WRITE_BANDWIDTH] = loc; + break; + case ACPI_HMAT_READ_BANDWIDTH: + localities_types[READ_BANDWIDTH] = loc; + break; + case ACPI_HMAT_WRITE_BANDWIDTH: + localities_types[WRITE_BANDWIDTH] = loc; + break; + default: + break; + } +} + static __init int hmat_parse_locality(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_hmat_locality *hmat_loc = (void *)header; + struct memory_target *target; unsigned int init, targ, total_size, ipds, tpds; u32 *inits, *targs, value; u16 *entries; - u8 type; + u8 type, mem_hier; if (hmat_loc->header.length < sizeof(*hmat_loc)) { pr_notice("HMAT: Unexpected locality header length: %d\n", @@ -105,6 +268,7 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, } type = hmat_loc->data_type; + mem_hier = hmat_loc->flags & ACPI_HMAT_MEMORY_HIERARCHY; ipds = hmat_loc->number_of_initiator_Pds; tpds = hmat_loc->number_of_target_Pds; total_size = sizeof(*hmat_loc) + sizeof(*entries) * ipds * tpds + @@ -123,6 +287,7 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, targs = inits + ipds; entries = (u16 *)(targs + tpds); for (init = 0; init < ipds; init++) { + alloc_memory_initiator(inits[init]); for (targ = 0; targ < tpds; targ++) { value = hmat_normalize(entries[init * tpds + targ], hmat_loc->entry_base_unit, @@ -130,9 +295,18 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, pr_info(" Initiator-Target[%d-%d]:%d%s\n", inits[init], targs[targ], value, hmat_data_type_suffix(type)); + + if (mem_hier == ACPI_HMAT_MEMORY) { + target = find_mem_target(targs[targ]); + if (target && target->processor_pxm == inits[init]) + hmat_update_target_access(target, type, value); + } } } + if (mem_hier == ACPI_HMAT_MEMORY) + hmat_add_locality(hmat_loc); + return 0; } @@ -176,6 +350,23 @@ static int __init hmat_parse_address_range(union acpi_subtable_headers *header, pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", p->flags, p->processor_PD, p->memory_PD); + if (p->flags & ACPI_HMAT_MEMORY_PD_VALID) { + target = find_mem_target(p->memory_PD); + if (!target) { + pr_debug("HMAT: Memory Domain missing from SRAT\n"); + return -EINVAL; + } + } + if (target && p->flags & ACPI_HMAT_PROCESSOR_PD_VALID) { + int p_node = pxm_to_node(p->processor_PD); + + if (p_node == NUMA_NO_NODE) { + pr_debug("HMAT: Invalid Processor Domain\n"); + return -EINVAL; + } + target->processor_pxm = p_node; + } + return 0; } @@ -199,6 +390,195 @@ static int __init hmat_parse_subtable(union acpi_subtable_headers *header, } } +static __init int srat_parse_mem_affinity(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_srat_mem_affinity *ma = (void *)header; + + if (!ma) + return -EINVAL; + if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) + return 0; + alloc_memory_target(ma->proximity_domain); + return 0; +} + +static __init u32 hmat_initiator_perf(struct memory_target *target, + struct memory_initiator *initiator, + struct acpi_hmat_locality *hmat_loc) +{ + unsigned int ipds, tpds, i, idx = 0, tdx = 0; + u32 *inits, *targs; + u16 *entries; + + ipds = hmat_loc->number_of_initiator_Pds; + tpds = hmat_loc->number_of_target_Pds; + inits = (u32 *)(hmat_loc + 1); + targs = inits + ipds; + entries = (u16 *)(targs + tpds); + + for (i = 0; i < ipds; i++) { + if (inits[i] == initiator->processor_pxm) { + idx = i; + break; + } + } + + if (i == ipds) + return 0; + + for (i = 0; i < tpds; i++) { + if (targs[i] == target->memory_pxm) { + tdx = i; + break; + } + } + if (i == tpds) + return 0; + + return hmat_normalize(entries[idx * tpds + tdx], + hmat_loc->entry_base_unit, + hmat_loc->data_type); +} + +static __init bool hmat_update_best(u8 type, u32 value, u32 *best) +{ + bool updated = false; + + if (!value) + return false; + + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + if (!*best || *best > value) { + *best = value; + updated = true; + } + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + case ACPI_HMAT_READ_BANDWIDTH: + case ACPI_HMAT_WRITE_BANDWIDTH: + if (!*best || *best < value) { + *best = value; + updated = true; + } + break; + } + + return updated; +} + +static int initiator_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct memory_initiator *ia; + struct memory_initiator *ib; + unsigned long *p_nodes = priv; + + ia = list_entry(a, struct memory_initiator, node); + ib = list_entry(b, struct memory_initiator, node); + + set_bit(ia->processor_pxm, p_nodes); + set_bit(ib->processor_pxm, p_nodes); + + return ia->processor_pxm - ib->processor_pxm; +} + +static __init void hmat_register_target_initiators(struct memory_target *target) +{ + static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); + struct memory_initiator *initiator; + unsigned int mem_nid, cpu_nid; + struct memory_locality *loc = NULL; + u32 best = 0; + int i; + + if (target->processor_pxm == PXM_INVAL) + return; + + mem_nid = pxm_to_node(target->memory_pxm); + + /* + * If the Address Range Structure provides a local processor pxm, link + * only that one. Otherwise, find the best performance attribtes and + * register all initiators that match. + */ + if (target->processor_pxm != PXM_INVAL) { + cpu_nid = pxm_to_node(target->processor_pxm); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + return; + } + + if (list_empty(&localities)) + return; + + /* + * We need the initiator list iteration sorted so we can use + * bitmap_clear for previously set initiators when we find a better + * memory accessor. We'll also use the sorting to prime the candidate + * nodes with known initiators. + */ + bitmap_zero(p_nodes, MAX_NUMNODES); + list_sort(p_nodes, &initiators, initiator_cmp); + for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { + loc = localities_types[i]; + if (!loc) + continue; + + best = 0; + list_for_each_entry(initiator, &initiators, node) { + u32 value; + + if (!test_bit(initiator->processor_pxm, p_nodes)) + continue; + + value = hmat_initiator_perf(target, initiator, loc->hmat_loc); + if (hmat_update_best(loc->hmat_loc->data_type, value, &best)) + bitmap_clear(p_nodes, 0, initiator->processor_pxm); + if (value != best) + clear_bit(initiator->processor_pxm, p_nodes); + } + if (best) + hmat_update_target_access(target, loc->hmat_loc->data_type, best); + } + + for_each_set_bit(i, p_nodes, MAX_NUMNODES) { + cpu_nid = pxm_to_node(i); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + } +} + +static __init void hmat_register_targets(void) +{ + struct memory_target *target; + + list_for_each_entry(target, &targets, node) + hmat_register_target_initiators(target); +} + +static __init void hmat_free_structures(void) +{ + struct memory_target *target, *tnext; + struct memory_locality *loc, *lnext; + struct memory_initiator *intitator, *inext; + + list_for_each_entry_safe(target, tnext, &targets, node) { + list_del(&target->node); + kfree(target); + } + + list_for_each_entry_safe(intitator, inext, &initiators, node) { + list_del(&intitator->node); + kfree(intitator); + } + + list_for_each_entry_safe(loc, lnext, &localities, node) { + list_del(&loc->node); + kfree(loc); + } +} + static __init int hmat_init(void) { struct acpi_table_header *tbl; @@ -208,6 +588,17 @@ static __init int hmat_init(void) if (srat_disabled()) return 0; + status = acpi_get_table(ACPI_SIG_SRAT, 0, &tbl); + if (ACPI_FAILURE(status)) + return 0; + + if (acpi_table_parse_entries(ACPI_SIG_SRAT, + sizeof(struct acpi_table_srat), + ACPI_SRAT_TYPE_MEMORY_AFFINITY, + srat_parse_mem_affinity, 0) < 0) + goto out_put; + acpi_put_table(tbl); + status = acpi_get_table(ACPI_SIG_HMAT, 0, &tbl); if (ACPI_FAILURE(status)) return 0; @@ -230,7 +621,9 @@ static __init int hmat_init(void) goto out_put; } } + hmat_register_targets(); out_put: + hmat_free_structures(); acpi_put_table(tbl); return 0; } From patchwork Wed Feb 27 22:50:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832379 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A8AF81669 for ; Wed, 27 Feb 2019 22:50:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93C632C58B for ; Wed, 27 Feb 2019 22:50:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9216C2E51D; Wed, 27 Feb 2019 22:50:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 317D52C58B for ; Wed, 27 Feb 2019 22:50:51 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C046C8E000D; Wed, 27 Feb 2019 17:50:36 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id BB7E38E0004; Wed, 27 Feb 2019 17:50:36 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A2F348E000D; Wed, 27 Feb 2019 17:50:36 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by kanga.kvack.org (Postfix) with ESMTP id 5ECA78E0004 for ; Wed, 27 Feb 2019 17:50:36 -0500 (EST) Received: by mail-pl1-f199.google.com with SMTP id f10so13475816plr.18 for ; Wed, 27 Feb 2019 14:50:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=7Kvu3Pt4lGB8xApQX5Now06Jiasc8XtxmSQBuYXB1Sk=; b=lg4TfG3N6fgY9F2JAqbabzQp3B8o+gplUoPYGiLJhiaIUuvo2zyilI6FveD06UcB6I jY8WMPabxt1pD/zvSdwZsr44kp9hN3eIWiRSJTUlrZQCvF9p1s+quBmuvJJFO4B38RCt MEUx3RTKMQ+m9Cikks2Re4xcgduTkA3+Vdgjv58CDMgZK+f3mpYzm/UDf2+WNBTXoqQZ p5jkaBBdmAF2B7lZHEB9IMyet1qEQvHXJHWGHDtKJgzpC46OURJSN/BQ0TD+jXc3UYit vn5ZupZ5LEmWWZlEbIPc/FHbvB8yFZgFicbzi6A25IQ40V2nd7XYYeEekDfWx9OJS2Jb yGQw== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuZ+lxmOVY22KMdOjJ1aeFLB0X8D98KJOcD4jBjms3WzQK4EL6+v WJZdFHV0Q5nrPN0GKOAvws2QApUO9fmRE3kEaLjgRY/wcvkWBY4OBbJkc4WW94B/pVamXz8Xtne NRaToNfG5zoyG0OEES+CM2Wo6Wcw7bSVrB+q5ITqBFOG/docPg0AnE9MPG5Ks3GW3aw== X-Received: by 2002:a63:1a25:: with SMTP id a37mr5489621pga.428.1551307836048; Wed, 27 Feb 2019 14:50:36 -0800 (PST) X-Google-Smtp-Source: AHgI3Ib10yt62+HSza1SZfu0mO4fnQg1ESKf/o+uMOWna1QWNHMYiGkcjT1oKRw6EqkwkILpPIcv X-Received: by 2002:a63:1a25:: with SMTP id a37mr5489557pga.428.1551307835193; Wed, 27 Feb 2019 14:50:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307835; cv=none; d=google.com; s=arc-20160816; b=U+O4mu8tpr7ixyMtPfQQS7i4/vcoZBjaJ+bRhalXA2nr99EsduXB5+4YngZdjuFR6u pmEWSMbgTAk6FE95bc9npB2MX2rcuaKTsPCmMpYOcoajhbz2xr5tB//CGQHnkfKCfSCz NXIFDgHYYBpMOBraoGt5B+4j2gJYeEwPC5y7SJiH9meqZ0w2Nuh9akylLw9nhbBc5QPn DsncFmXKfz3BvpTODAAMdgvxEKEPuXSNr0jnssHhdsxLrpBuc4bQsZWhEB1hFhBl/s/B Yql6R63qEIB2Exz4hXNCWWhlv4qWVqDooClsinV7QUO9SO1ByJtbg6Kj+GBKnovsW0co hisA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=7Kvu3Pt4lGB8xApQX5Now06Jiasc8XtxmSQBuYXB1Sk=; b=PS1lM9YLLbDce3vJcAp8jN+0npYIO+vq0yqTVDyfZ3iZsD61yG7xoUHea7RoeiXX3C VER+NM2n5yq4QR1xqRkn12ZUrEOODUaz1UGepovTfWuy6xJWeiHX7lUDT9HW6lewgwAs h5cQ5hMtQkqD1z5HxANr6uZwHnFbD9Ejv3vl9tFtLjT6Ezvp474MD7+l8DBwlACdePaX Ncilhxgwk/szLc7Jw+LK+RKRZOr7dnKmxp53N14ZCnsMD4V6HtVF8kb6nBRTQv9mi25q pvUax5JJKKGHWBYtI0KCltPG3tbvBNS8hdjbXe2rRt4v0qnPXLsnoLGmGn7Rq7F3PsSO J8NQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:35 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349425" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:33 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 08/10] acpi/hmat: Register performance attributes Date: Wed, 27 Feb 2019 15:50:36 -0700 Message-Id: <20190227225038.20438-9-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Save the best performace access attributes and register these with the memory's node if HMAT provides the locality table. While HMAT does make it possible to know performance for all possible initiator-target pairings, we export only the local pairings at this time. Acked-by: Rafael J. Wysocki Signed-off-by: Keith Busch --- drivers/acpi/hmat/Kconfig | 5 ++++- drivers/acpi/hmat/hmat.c | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/hmat/Kconfig b/drivers/acpi/hmat/Kconfig index 13cddd612a52..95a29964dbea 100644 --- a/drivers/acpi/hmat/Kconfig +++ b/drivers/acpi/hmat/Kconfig @@ -2,7 +2,10 @@ config ACPI_HMAT bool "ACPI Heterogeneous Memory Attribute Table Support" depends on ACPI_NUMA + select HMEM_REPORTING help If set, this option has the kernel parse and report the platform's ACPI HMAT (Heterogeneous Memory Attributes Table), - and register memory initiators with their targets. + register memory initiators with their targets, and export + performance attributes through the node's sysfs device if + provided. diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c index bb6a11653729..5b469c98a454 100644 --- a/drivers/acpi/hmat/hmat.c +++ b/drivers/acpi/hmat/hmat.c @@ -549,12 +549,20 @@ static __init void hmat_register_target_initiators(struct memory_target *target) } } +static __init void hmat_register_target_perf(struct memory_target *target) +{ + unsigned mem_nid = pxm_to_node(target->memory_pxm); + node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0); +} + static __init void hmat_register_targets(void) { struct memory_target *target; - list_for_each_entry(target, &targets, node) + list_for_each_entry(target, &targets, node) { hmat_register_target_initiators(target); + hmat_register_target_perf(target); + } } static __init void hmat_free_structures(void) From patchwork Wed Feb 27 22:50:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832383 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 593421669 for ; Wed, 27 Feb 2019 22:50:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4943C2E4EF for ; Wed, 27 Feb 2019 22:50:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D6A02E522; Wed, 27 Feb 2019 22:50:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9BD72E4EF for ; Wed, 27 Feb 2019 22:50:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B8EB28E000E; Wed, 27 Feb 2019 17:50:37 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B44CB8E0004; Wed, 27 Feb 2019 17:50:37 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 96A6B8E000E; Wed, 27 Feb 2019 17:50:37 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by kanga.kvack.org (Postfix) with ESMTP id 5080A8E0004 for ; Wed, 27 Feb 2019 17:50:37 -0500 (EST) Received: by mail-pg1-f198.google.com with SMTP id 2so13289364pgg.21 for ; Wed, 27 Feb 2019 14:50:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=0HjwwT6eQeqhzAbFDcuq0ldWENBawT6qQh3pTSR0FdA=; b=FrE4pajLWaQk8cu5UJCl+dvG0OOimz2p17YBL4Q35FoGQZgjQtkzKRK5Pe24DnTaWR EtScaXZPrHyVTHYI6ckQYUQPo0owOJXLJulhKRkAQD9eYuxhBDJQKitxi+aJp6CebOIQ hTaxzEsf/MTUCuKpZNjoMMuQfFem+dKpCPZKSF1zY4BaZcglT4fespkyTJfsFexBcvHc 8BKSuvrrV9Z7TGlyptGJVRxJaFCj0sxai2BAl0O7egTPUqWb2qvjN1j6i7DQqjC7A0US eO1rS53z2+x3jmqP5lsP4pFoH3YU204TTGd0lSKASDjH4sDdKZDSj0e3+bzbreK2wj6X 6mmg== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuYAFQnSepe982NEngMGS/Q4pV1jnu9FHeqtU9QjKpuJO3ZG8xkz X/0uqN6ipODjJeFxmOyKjqiAy7QViBKqSTVmf93AePKnEaECQvTklLJoGdEbUpJXOj1lS2GEhio SNA/zdBS/Euvde8m1JgmhIHUZJ7oc2Cdkv74fLty+0V94dv97UCkNtm6yY2ZquLd88A== X-Received: by 2002:a62:b2d9:: with SMTP id z86mr4139941pfl.255.1551307836984; Wed, 27 Feb 2019 14:50:36 -0800 (PST) X-Google-Smtp-Source: AHgI3IbNBMG9mxUNFCX91naF5L+5S6xvQOJ/V73m6Uw9JHjQd2tPcUSOvpXXyRJffG2aZVr07Y8f X-Received: by 2002:a62:b2d9:: with SMTP id z86mr4139871pfl.255.1551307835979; Wed, 27 Feb 2019 14:50:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307835; cv=none; d=google.com; s=arc-20160816; b=FPXR/BOmWjtZidWquqUpDyqjQdivDhvAcfjoLkJzg/sQPCWPUz1GpzDVmIqDTOjgco bZgxqHTaQ7ulM/pmeflveWuJrIEXz8jFM+vl42axNCskhw1yeDAtMPGT3Kgpz7MB/APT qqm2ci2yi0UNY9hS2GNxhYOLb5IfkhfscYT2QNScWhYXj4FToMXRnoyzL0NlHXH0P/Xi uUtqEwPWi2lZ4LpgumS9rC5m3VEr/2VHTM8uVGKQsqq63PT0r4e48MIDBEa4KZ70cR0w 9a7lNW+WeqfAI05Kqk5S6U2nQ5LlJ0iNq3efNI6tcxHHEplHMZMghH6xrNlIxIdHW7KO HTAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=0HjwwT6eQeqhzAbFDcuq0ldWENBawT6qQh3pTSR0FdA=; b=TXIBtvUECp9k7DG59qRQOxPsZMJicCQFtdH6DxTmrOHwwT6mdKshKy5zykR2Ls7WnV FuUWBXCDauNzhgEZG2g3UNood+oXvgKXYmigdmtcyKbHp8LbKVAckPaP5ze3XHen37+X gU6E87kP1cftjYsx/G81Tq6XMGiYuBNNK3oQV2r57krI4NfMrCLS+xXCqWSd0bcYyZBN b6hz4fCU+l2wIrIJtuWwadIAAncMxisWLRodd8dozay+ngVakDUfsIMst95jEoq7jEd3 O8ymtF37aEy3uEAc7nZRANt0Pl4P/Xhy/HU03Q1OeJbxrNMbudkz+KVuYP9KVol0lOOl 87+Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:35 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349436" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:34 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 09/10] acpi/hmat: Register memory side cache attributes Date: Wed, 27 Feb 2019 15:50:37 -0700 Message-Id: <20190227225038.20438-10-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Register memory side cache attributes with the memory's node if HMAT provides the side cache iniformation table. Acked-by: Rafael J. Wysocki Signed-off-by: Keith Busch --- drivers/acpi/hmat/hmat.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c index 5b469c98a454..f3b182bf3595 100644 --- a/drivers/acpi/hmat/hmat.c +++ b/drivers/acpi/hmat/hmat.c @@ -314,6 +314,7 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_hmat_cache *cache = (void *)header; + struct node_cache_attrs cache_attrs; u32 attrs; if (cache->header.length < sizeof(*cache)) { @@ -327,6 +328,37 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header, cache->memory_PD, cache->cache_size, attrs, cache->number_of_SMBIOShandles); + cache_attrs.size = cache->cache_size; + cache_attrs.level = (attrs & ACPI_HMAT_CACHE_LEVEL) >> 4; + cache_attrs.line_size = (attrs & ACPI_HMAT_CACHE_LINE_SIZE) >> 16; + + switch ((attrs & ACPI_HMAT_CACHE_ASSOCIATIVITY) >> 8) { + case ACPI_HMAT_CA_DIRECT_MAPPED: + cache_attrs.indexing = NODE_CACHE_DIRECT_MAP; + break; + case ACPI_HMAT_CA_COMPLEX_CACHE_INDEXING: + cache_attrs.indexing = NODE_CACHE_INDEXED; + break; + case ACPI_HMAT_CA_NONE: + default: + cache_attrs.indexing = NODE_CACHE_OTHER; + break; + } + + switch ((attrs & ACPI_HMAT_WRITE_POLICY) >> 12) { + case ACPI_HMAT_CP_WB: + cache_attrs.write_policy = NODE_CACHE_WRITE_BACK; + break; + case ACPI_HMAT_CP_WT: + cache_attrs.write_policy = NODE_CACHE_WRITE_THROUGH; + break; + case ACPI_HMAT_CP_NONE: + default: + cache_attrs.write_policy = NODE_CACHE_WRITE_OTHER; + break; + } + + node_add_cache(pxm_to_node(cache->memory_PD), &cache_attrs); return 0; } From patchwork Wed Feb 27 22:50:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 10832385 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9B2B91575 for ; Wed, 27 Feb 2019 22:51:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 88D952E4D3 for ; Wed, 27 Feb 2019 22:51:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D5E42E4EF; Wed, 27 Feb 2019 22:51:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B411A2E4E1 for ; Wed, 27 Feb 2019 22:51:04 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D15B58E000F; Wed, 27 Feb 2019 17:50:39 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id CC4878E0004; Wed, 27 Feb 2019 17:50:39 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B43628E000F; Wed, 27 Feb 2019 17:50:39 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by kanga.kvack.org (Postfix) with ESMTP id 66FC68E0004 for ; Wed, 27 Feb 2019 17:50:39 -0500 (EST) Received: by mail-pg1-f197.google.com with SMTP id t26so13291394pgu.18 for ; Wed, 27 Feb 2019 14:50:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=MlJfY+EuivLFltIs7JFcxPfmegeGxi4DJ5D83gg3O88=; b=DBjLPpLSHgy8DdusezkhTFUEEPSAYui5Fz+8NvoxvtefObjjy7SY77vt1F1CGRnMp6 FkE2+WICXx6P4qXVwTCrAMvRk3jRj5U9Y5VP9quV0VVu7UwnfXyZtZF4jammSI41gfa/ gbIV1NOPwcv/dHuYyrD84Yx+LlurRxX7HKvNsmKNevF2uQzy5TyFW8TPFajhWDvd0FF1 hNNl33mXwOGTxM0+xhbdNecC1nUnlx+I4jZ3wpiB5c9xy5ya1oc2+k2oDdL1Ts2T4HQA QltnkkCUUSLSgCVj7d+rYHpIPwqPOO/UHUoY50ITx9Ri6n2kr0X4VzR4EL2BgHEo+omf xxuA== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AHQUAuZTTHALvmPEjmIt8sBa3D77nT6B8FozpfrzjHfPWZsdmSWZ+76n OKWikKj8OwjrC0GIMEwBaJMpLVUDm/Lc/uPbb0RuQs0oijPtbWYuDiErsJZ8cKf4/ur2ecZkt7N D2KWZnblQoggR2+JP2USOX5TgaP8/warLzBGWYTBmcLl0RmLia3TrJMIklIQfIVZHAw== X-Received: by 2002:a63:eb56:: with SMTP id b22mr5321965pgk.287.1551307838863; Wed, 27 Feb 2019 14:50:38 -0800 (PST) X-Google-Smtp-Source: AHgI3IYrBYBiU8Iz2qt+zorvtYVzoUXAP/pgJBjIVorBNSWIBZle6Rdjl4/sWGZ3/V50gl+M/2Fb X-Received: by 2002:a63:eb56:: with SMTP id b22mr5321839pgk.287.1551307837313; Wed, 27 Feb 2019 14:50:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551307837; cv=none; d=google.com; s=arc-20160816; b=mg3kv/IgXCCR8hBCgXNGb4TPlDWHGOWeGH2jBvayPdGd+sK/4hV8ZXp9LOVkaZ+n6s A3YTRhuKHynC/yAyuJj9mW0QTyB0PUF8pD0zxT5oRLs/MqnYujzr7H+JtTDcH2tMqaZl T5AKr78L3YMahi1TB8+/SptTy/0sOs411W+FjZoucHQopel8JaxzYxTfAMuNS67VGRaj +8E/GGzjiYJ6mrjkICi6bbpwEg7rHcw4rA9T/DYtLzA+RzO5faxJ9T31s/AAuPBM+LuM vEQwY4kvMkmcQdoXGe3D6xcJkUSj14q9PB6sBB+V697NU354waYSshpaTbvOTKkZuZKU CCZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=MlJfY+EuivLFltIs7JFcxPfmegeGxi4DJ5D83gg3O88=; b=X2ssZAhjdEfgvszpF8SKglnu01p7dS3Tw1M0VT//TRc/oY/FzmYDoqxBzTe7e9AmNK fBc5cN8UNCufFS+ODtWKLenW31Nxj8LSWxF+K5+6jTceYyaypABJzDe+uJRR5ISpwylu nv8ewJ7D1M3KRTY3uf7wMu00aLa7Ce+qe8Bs1gWKQ0H80P2OSLvpBjVaUYs3cQRTijs5 WXg8bvFHAW1dkC5c4wv21HPavs+FgchnUPlhO1BY6IiGEX0SuF0bDxkfTSuwvgVqmd3b l9Bfi8LsokcrKXaYT5mMPZHHXLR/Er7mi09TffGWl4o/3HtOAnKcRVmVMYUWfrYsNG8i an/Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga17.intel.com (mga17.intel.com. [192.55.52.151]) by mx.google.com with ESMTPS id z20si10836901pgf.324.2019.02.27.14.50.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Feb 2019 14:50:37 -0800 (PST) Received-SPF: pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) client-ip=192.55.52.151; Authentication-Results: mx.google.com; spf=pass (google.com: domain of keith.busch@intel.com designates 192.55.52.151 as permitted sender) smtp.mailfrom=keith.busch@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2019 14:50:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,420,1544515200"; d="scan'208";a="121349447" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by orsmga008.jf.intel.com with ESMTP; 27 Feb 2019 14:50:35 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-api@vger.kernel.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCHv7 10/10] doc/mm: New documentation for memory performance Date: Wed, 27 Feb 2019 15:50:38 -0700 Message-Id: <20190227225038.20438-11-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190227225038.20438-1-keith.busch@intel.com> References: <20190227225038.20438-1-keith.busch@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Platforms may provide system memory where some physical address ranges perform differently than others, or is side cached by the system. Add documentation describing a high level overview of such systems and the perforamnce and caching attributes the kernel provides for applications wishing to query this information. Reviewed-by: Mike Rapoport Signed-off-by: Keith Busch Reviewed-by: Jonathan Cameron --- Documentation/admin-guide/mm/numaperf.rst | 164 ++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Documentation/admin-guide/mm/numaperf.rst diff --git a/Documentation/admin-guide/mm/numaperf.rst b/Documentation/admin-guide/mm/numaperf.rst new file mode 100644 index 000000000000..d32756b9be48 --- /dev/null +++ b/Documentation/admin-guide/mm/numaperf.rst @@ -0,0 +1,164 @@ +.. _numaperf: + +============= +NUMA Locality +============= + +Some platforms may have multiple types of memory attached to a compute +node. These disparate memory ranges may share some characteristics, such +as CPU cache coherence, but may have different performance. For example, +different media types and buses affect bandwidth and latency. + +A system supports such heterogeneous memory by grouping each memory type +under different domains, or "nodes", based on locality and performance +characteristics. Some memory may share the same node as a CPU, and others +are provided as memory only nodes. While memory only nodes do not provide +CPUs, they may still be local to one or more compute nodes relative to +other nodes. The following diagram shows one such example of two compute +nodes with local memory and a memory only node for each of compute node: + + +------------------+ +------------------+ + | Compute Node 0 +-----+ Compute Node 1 | + | Local Node0 Mem | | Local Node1 Mem | + +--------+---------+ +--------+---------+ + | | + +--------+---------+ +--------+---------+ + | Slower Node2 Mem | | Slower Node3 Mem | + +------------------+ +--------+---------+ + +A "memory initiator" is a node containing one or more devices such as +CPUs or separate memory I/O devices that can initiate memory requests. +A "memory target" is a node containing one or more physical address +ranges accessible from one or more memory initiators. + +When multiple memory initiators exist, they may not all have the same +performance when accessing a given memory target. Each initiator-target +pair may be organized into different ranked access classes to represent +this relationship. The highest performing initiator to a given target +is considered to be one of that target's local initiators, and given +the highest access class, 0. Any given target may have one or more +local initiators, and any given initiator may have multiple local +memory targets. + +To aid applications matching memory targets with their initiators, the +kernel provides symlinks to each other. The following example lists the +relationship for the access class "0" memory initiators and targets, which is +the of nodes with the highest performing access relationship:: + + # symlinks -v /sys/devices/system/node/nodeX/access0/targets/ + relative: /sys/devices/system/node/nodeX/access0/targets/nodeY -> ../../nodeY + + # symlinks -v /sys/devices/system/node/nodeY/access0/initiators/ + relative: /sys/devices/system/node/nodeY/access0/initiators/nodeX -> ../../nodeX + +================ +NUMA Performance +================ + +Applications may wish to consider which node they want their memory to +be allocated from based on the node's performance characteristics. If +the system provides these attributes, the kernel exports them under the +node sysfs hierarchy by appending the attributes directory under the +memory node's access class 0 initiators as follows:: + + /sys/devices/system/node/nodeY/access0/initiators/ + +These attributes apply only when accessed from nodes that have the +are linked under the this access's inititiators. + +The performance characteristics the kernel provides for the local initiators +are exported are as follows:: + + # tree -P "read*|write*" /sys/devices/system/node/nodeY/access0/initiators/ + /sys/devices/system/node/nodeY/access0/initiators/ + |-- read_bandwidth + |-- read_latency + |-- write_bandwidth + `-- write_latency + +The bandwidth attributes are provided in MiB/second. + +The latency attributes are provided in nanoseconds. + +The values reported here correspond to the rated latency and bandwidth +for the platform. + +========== +NUMA Cache +========== + +System memory may be constructed in a hierarchy of elements with various +performance characteristics in order to provide large address space of +slower performing memory cached by a smaller higher performing memory. The +system physical addresses memory initiators are aware of are provided +by the last memory level in the hierarchy. The system meanwhile uses +higher performing memory to transparently cache access to progressively +slower levels. + +The term "far memory" is used to denote the last level memory in the +hierarchy. Each increasing cache level provides higher performing +initiator access, and the term "near memory" represents the fastest +cache provided by the system. + +This numbering is different than CPU caches where the cache level (ex: +L1, L2, L3) uses the CPU-side view where each increased level is lower +performing. In contrast, the memory cache level is centric to the last +level memory, so the higher numbered cache level corresponds to memory +nearer to the CPU, and further from far memory. + +The memory-side caches are not directly addressable by software. When +software accesses a system address, the system will return it from the +near memory cache if it is present. If it is not present, the system +accesses the next level of memory until there is either a hit in that +cache level, or it reaches far memory. + +An application does not need to know about caching attributes in order +to use the system. Software may optionally query the memory cache +attributes in order to maximize the performance out of such a setup. +If the system provides a way for the kernel to discover this information, +for example with ACPI HMAT (Heterogeneous Memory Attribute Table), +the kernel will append these attributes to the NUMA node memory target. + +When the kernel first registers a memory cache with a node, the kernel +will create the following directory:: + + /sys/devices/system/node/nodeX/memory_side_cache/ + +If that directory is not present, the system either does not not provide +a memory-side cache, or that information is not accessible to the kernel. + +The attributes for each level of cache is provided under its cache +level index:: + + /sys/devices/system/node/nodeX/memory_side_cache/indexA/ + /sys/devices/system/node/nodeX/memory_side_cache/indexB/ + /sys/devices/system/node/nodeX/memory_side_cache/indexC/ + +Each cache level's directory provides its attributes. For example, the +following shows a single cache level and the attributes available for +software to query:: + + # tree sys/devices/system/node/node0/memory_side_cache/ + /sys/devices/system/node/node0/memory_side_cache/ + |-- index1 + | |-- indexing + | |-- line_size + | |-- size + | `-- write_policy + +The "indexing" will be 0 if it is a direct-mapped cache, and non-zero +for any other indexed based, multi-way associativity. + +The "line_size" is the number of bytes accessed from the next cache +level on a miss. + +The "size" is the number of bytes provided by this cache level. + +The "write_policy" will be 0 for write-back, and non-zero for +write-through caching. + +======== +See Also +======== +.. [1] https://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf + Section 5.2.27