From patchwork Wed Sep 30 14:05:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 313899 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:1081:0:0:0:0 with SMTP id r1csp248908ilj; Wed, 30 Sep 2020 07:10:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz3pTbpYuCqZ6/tT/nAdx7n9utu6qSJ3p85RlNKId5NbmQP1pH9BeRt9KuicIrSmeYbPNft X-Received: by 2002:aa7:d697:: with SMTP id d23mr3046107edr.13.1601475037387; Wed, 30 Sep 2020 07:10:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601475037; cv=none; d=google.com; s=arc-20160816; b=MTHRaqtHUog5Nt1YrOmdRe6N5ZdwoAQW6KfYzkslyuHDv0I58p96eyS/H8UHLeQNnP x7HftALjNdUi0QUBTVWjSPi/JfqtT6yvFD8QF1bputs+q6HYylfAGQVUF5vlUH4Tx73n 5HZf1CC6M4+jlAkvuk+6zx/SRvRjYPPxX4n8Yjzs+uPMnwWMmL06XI4xJFOBovh122a1 E/+SEdUjGVPwmQQ3HKeDK4U/lp6fWjgxTimByBK4dzeO71YdeOELZy3V7SZ7vZAuKMOP owDDh1DWs5y/zWT4HZzLmioKxtfnvuQVgYS/ghOH8VkdYpSX9qI9s6cGfuDGWKyxfPqY 08BA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=ys/SeTm2r+IEMdgVhrZGBDxamy/CVslF4g2yd492TPQ=; b=t501kwrthsaQrLl0nTD4CltlkZKgVFt0V06MrySSTEBLEtVkHpNTrZI726tXFqTRj6 BbEnczDmz9mjkKLDhl/k8+v+1Iu+YAFeJ/RFzuGZcVK46p6FzduuCkISYlLjfgUzbNfr 3yIHZwOsHeXKgRonBE/7PYybTn6Q57Ccde0Ox7opozRsH4769J+T3DgIOup1cmjSm51C o7uPyFXzZvyVl0oYotxx2a4puRA8m8L1HIC/K+S9KhKjmS1kNBWMH6ARLG37jLauPrmA gjcGAUSXwpIOVq/M4Nmu64yFtDm/+TWJgbKTKy1PaHEl/W6qSi+9jC3ylUS5zNAoNADv oSVg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-acpi-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y9si1207121edp.443.2020.09.30.07.10.37; Wed, 30 Sep 2020 07:10:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-acpi-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-acpi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730261AbgI3OKd (ORCPT + 7 others); Wed, 30 Sep 2020 10:10:33 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:54676 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730188AbgI3OKd (ORCPT ); Wed, 30 Sep 2020 10:10:33 -0400 Received: from DGGEMS414-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id B3A89220FF08AE0B5235; Wed, 30 Sep 2020 22:10:30 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.487.0; Wed, 30 Sep 2020 22:10:23 +0800 From: Jonathan Cameron To: , , , , Lorenzo Pieralisi , , Ingo Molnar CC: Bjorn Helgaas , , Thomas Gleixner , , Dan Williams , Brice Goglin , "Sean V Kelley" , , "Borislav Petkov" , Hanjun Guo , Jonathan Cameron Subject: [PATCH v12 5/6] node: Add access1 class to represent CPU to memory characteristics Date: Wed, 30 Sep 2020 22:05:46 +0800 Message-ID: <20200930140547.840251-6-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20200930140547.840251-1-Jonathan.Cameron@huawei.com> References: <20200930140547.840251-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org New access1 class is nearly the same as access0, but always provides characteristics for CPUs to memory. The existing access0 class provides characteristics to nearest or direct connnect initiator which may be a Generic Initiator such as a GPU or network adapter. This new class allows thread placement on CPUs to be performed so as to give optimal access characteristics to memory, even if that memory is for example attached to a GPU or similar and only accessible to the CPU via an appropriate bus. Suggested-by: Dan Willaims Signed-off-by: Jonathan Cameron --- drivers/acpi/numa/hmat.c | 88 +++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 19 deletions(-) -- 2.19.1 diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 6a91a55229ae..3dc251264423 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -56,7 +56,7 @@ struct memory_target { unsigned int memory_pxm; unsigned int processor_pxm; struct resource memregions; - struct node_hmem_attrs hmem_attrs; + struct node_hmem_attrs hmem_attrs[2]; struct list_head caches; struct node_cache_attrs cache_attrs; bool registered; @@ -65,6 +65,7 @@ struct memory_target { struct memory_initiator { struct list_head node; unsigned int processor_pxm; + bool has_cpu; }; struct memory_locality { @@ -108,6 +109,7 @@ static __init void alloc_memory_initiator(unsigned int cpu_pxm) return; initiator->processor_pxm = cpu_pxm; + initiator->has_cpu = node_state(pxm_to_node(cpu_pxm), N_CPU); list_add_tail(&initiator->node, &initiators); } @@ -215,28 +217,28 @@ static u32 hmat_normalize(u16 entry, u64 base, u8 type) } static void hmat_update_target_access(struct memory_target *target, - u8 type, u32 value) + u8 type, u32 value, int access) { switch (type) { case ACPI_HMAT_ACCESS_LATENCY: - target->hmem_attrs.read_latency = value; - target->hmem_attrs.write_latency = value; + target->hmem_attrs[access].read_latency = value; + target->hmem_attrs[access].write_latency = value; break; case ACPI_HMAT_READ_LATENCY: - target->hmem_attrs.read_latency = value; + target->hmem_attrs[access].read_latency = value; break; case ACPI_HMAT_WRITE_LATENCY: - target->hmem_attrs.write_latency = value; + target->hmem_attrs[access].write_latency = value; break; case ACPI_HMAT_ACCESS_BANDWIDTH: - target->hmem_attrs.read_bandwidth = value; - target->hmem_attrs.write_bandwidth = value; + target->hmem_attrs[access].read_bandwidth = value; + target->hmem_attrs[access].write_bandwidth = value; break; case ACPI_HMAT_READ_BANDWIDTH: - target->hmem_attrs.read_bandwidth = value; + target->hmem_attrs[access].read_bandwidth = value; break; case ACPI_HMAT_WRITE_BANDWIDTH: - target->hmem_attrs.write_bandwidth = value; + target->hmem_attrs[access].write_bandwidth = value; break; default: break; @@ -329,8 +331,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header, 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 (target && target->processor_pxm == inits[init]) { + hmat_update_target_access(target, type, value, 0); + /* If the node has a CPU, update access 1 */ + if (node_state(pxm_to_node(inits[init]), N_CPU)) + hmat_update_target_access(target, type, value, 1); + } } } } @@ -567,6 +573,7 @@ static void hmat_register_target_initiators(struct memory_target *target) unsigned int mem_nid, cpu_nid; struct memory_locality *loc = NULL; u32 best = 0; + bool access0done = false; int i; mem_nid = pxm_to_node(target->memory_pxm); @@ -578,7 +585,11 @@ static void hmat_register_target_initiators(struct memory_target *target) 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; + access0done = true; + if (node_state(cpu_nid, N_CPU)) { + register_memory_node_under_compute_node(mem_nid, cpu_nid, 1); + return; + } } if (list_empty(&localities)) @@ -592,6 +603,41 @@ static void hmat_register_target_initiators(struct memory_target *target) */ bitmap_zero(p_nodes, MAX_NUMNODES); list_sort(p_nodes, &initiators, initiator_cmp); + if (!access0done) { + 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, 0); + } + + 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); + } + } + + /* Access 1 ignores Generic Initiators */ + bitmap_zero(p_nodes, MAX_NUMNODES); + list_sort(p_nodes, &initiators, initiator_cmp); + best = 0; for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { loc = localities_types[i]; if (!loc) @@ -601,6 +647,10 @@ static void hmat_register_target_initiators(struct memory_target *target) list_for_each_entry(initiator, &initiators, node) { u32 value; + if (!initiator->has_cpu) { + clear_bit(initiator->processor_pxm, p_nodes); + continue; + } if (!test_bit(initiator->processor_pxm, p_nodes)) continue; @@ -611,12 +661,11 @@ static void hmat_register_target_initiators(struct memory_target *target) clear_bit(initiator->processor_pxm, p_nodes); } if (best) - hmat_update_target_access(target, loc->hmat_loc->data_type, best); + hmat_update_target_access(target, loc->hmat_loc->data_type, best, 1); } - 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); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 1); } } @@ -629,10 +678,10 @@ static void hmat_register_target_cache(struct memory_target *target) node_add_cache(mem_nid, &tcache->cache_attrs); } -static void hmat_register_target_perf(struct memory_target *target) +static void hmat_register_target_perf(struct memory_target *target, int access) { unsigned mem_nid = pxm_to_node(target->memory_pxm); - node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0); + node_set_perf_attrs(mem_nid, &target->hmem_attrs[access], access); } static void hmat_register_target_device(struct memory_target *target, @@ -734,7 +783,8 @@ static void hmat_register_target(struct memory_target *target) if (!target->registered) { hmat_register_target_initiators(target); hmat_register_target_cache(target); - hmat_register_target_perf(target); + hmat_register_target_perf(target, 0); + hmat_register_target_perf(target, 1); target->registered = true; } mutex_unlock(&target_lock);