From patchwork Wed Aug 16 08:00:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Ying" X-Patchwork-Id: 13354646 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DCB7C001DF for ; Wed, 16 Aug 2023 08:00:59 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B3645280011; Wed, 16 Aug 2023 04:00:58 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id AE5A08D0021; Wed, 16 Aug 2023 04:00:58 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 914F5280011; Wed, 16 Aug 2023 04:00:58 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 7BBBD8D0021 for ; Wed, 16 Aug 2023 04:00:58 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 35C27140E50 for ; Wed, 16 Aug 2023 08:00:58 +0000 (UTC) X-FDA: 81129221796.21.21CA365 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.136]) by imf25.hostedemail.com (Postfix) with ESMTP id 1D320A0009 for ; Wed, 16 Aug 2023 08:00:55 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=Ye4HndDs; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf25.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.136 as permitted sender) smtp.mailfrom=ying.huang@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1692172856; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=7TQYdF6jynsjCMEBUA9q8WwQNgD8G0shT5J2hqS62VA=; b=ZnC6h6zb26knrJrvzXweP2r1M1twgEBYNK7LUP59VtQFLfXd09UJAjtn0luyUj6p3GIjRh 4reZVJN1S5XpOL5GbceWgtCAeDA5RJHWqFXscN546vUj6x8OEyPwTbmc9GvYx0TwNk62qy irG7Fwr/MEpFPqu/b4QmX3iGgURWCFI= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=Ye4HndDs; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf25.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.136 as permitted sender) smtp.mailfrom=ying.huang@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1692172856; a=rsa-sha256; cv=none; b=SbXBS22ZM9AWafiqOXcUh6r1bQJNh2C7+vodInlipg/P05KW++a90xkGtm5bUsCaX0ChWv Qc635EOMELwC34HiFgwybT4wxD6pZcKBBZEai2vYovFKg+YZik8S2+Jh7spzVlPSPq9JuW vGSxs4HymjBRdAAmtigHNnO3472cYpI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1692172856; x=1723708856; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PAXiM4QxwflvtLeQyOXin3qRlOkgjmcYey5dyC3C20E=; b=Ye4HndDsC92TXF4bIu6CkxVw1j4fXyUWq1dsJRTzcZUHBra4fpN4HJAf 88eSM4F/l7WiKUQt3/3kUrZaL0lSNZRjMzMYhPgIv9/DFgxkqm06nuHYJ GbrIby9ktGkCijsJWIn3S/iLSq4zrooyv0H6BBMgKOag2O+OZAzamdpd3 TumR2aYEm6/UvGgaQxs5Guq61phJVxO19YPZFyzPmN5eoi/5xXyw0hE8f Qja4d7L7dmUReBEqXEZTBHkWMSPkA8YTk84BGPmL9F+j+K/ZRuEj5pQfC Yqj4qGQdtDLAOT60nJYs7qdZEjaxCAfgjljE7AUT4eqraXVTwKfrqv6U6 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10803"; a="352058196" X-IronPort-AV: E=Sophos;i="6.01,176,1684825200"; d="scan'208";a="352058196" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Aug 2023 01:00:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10803"; a="804112805" X-IronPort-AV: E=Sophos;i="6.01,176,1684825200"; d="scan'208";a="804112805" Received: from yhuang6-mobl2.sh.intel.com ([10.238.6.30]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Aug 2023 01:00:49 -0700 From: Huang Ying To: Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Huang Ying , Bharata B Rao , "Aneesh Kumar K . V" , Wei Xu , Alistair Popple , Dan Williams , Dave Hansen , Davidlohr Bueso , Johannes Weiner , Jonathan Cameron , Michal Hocko , Yang Shi , Rafael J Wysocki Subject: [PATCH -V2 3/4] acpi, hmat: calculate abstract distance with HMAT Date: Wed, 16 Aug 2023 16:00:23 +0800 Message-Id: <20230816080024.105554-4-ying.huang@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230816080024.105554-1-ying.huang@intel.com> References: <20230816080024.105554-1-ying.huang@intel.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 1D320A0009 X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: 4fm3z8cso5kube7fsnrbhb86jzzdnhf6 X-HE-Tag: 1692172855-284902 X-HE-Meta: U2FsdGVkX19qBQZ8aX1tbRu+1s4H3ksi8L32MPE7pgnygIFRIWXrr4c2JDMI1WqpMjh+2zYYadxzJLhy1i3WfDMd0o/ntoQ1sNj78MXF9O+OLJ9pBDCoqqQvYWG8WfQM+i/zgOIZIe5JPQehINKoRDUqLIq62j2N5fRk2WhTcHiBwSwBCoqXeLA9X2EbDnz/4QPV7bskLetE/kPLmnxO9Vvd+deyCf5/9sAMeLJGoFAtPpRdIfHNMTc8o7y+wUiNuGuzHUSlaRZ7HkKrQt6BNGCl/azazXkz9OtGppVwctqeWhzHBLF/m71+le74aeQBNcnwvlImxyn1scML+YEanuOhL4dBtfJolGiWD0Ud01gpPBMyxjwtCirglb/9EZNm2+IOWrv46QTn2+wa8OQH6m7oYxpStcVU9MvPg8THXk1V03iT+FchV40yWYibWbyf74HrxLbqNF6cCVUGXAnpoZ6fooI5iLJ6FHjguZVoWX0e1StN8UgpVbLyY+6JrbU+JSupXq5om+0m6sY3X7rtNTN0PPZPBzGwsl65/4CqhWQGPQsi7WcqPINPZQGSBvp+0QPs4sdkp71qOeLj/Y1w8IL0bioAi/EKw+p98MWYHml78sd38wDiDEQtVWcAhZsaobDhUrmuV45hiTlpp2CntGU5LyNnVn2sQ/U6OGtsn52tCpDXn3AbJNRiUa/nEyXYN/c0LCgbBHCT0sw3z0g1BM6n6DeIdLe+Hlz7RF8ShkPbRPNlq1CegQLjbXZetluk/gTsMj2JlahiJrYtjiZ3Z4OJTJjPCnjOJkbskSTMvsa9ADR/hpjseELmnle7KRw4/vNAbNDvfGx5TAZP2D1/0sgn6jrL1TEciKPyrqf5LHQftb583WVPG3mSKPvuPqJwoxZpgcpgEBXQh+7HV3zxozLfL+MRRl9QEydKpKzvD6EjNMhWXUrZeickcouhbBNHW1dgroIbl+8IFZCuRRP Cjigtgw+ 9TqeM/sI05VNOH7u340G5XWIC5kyrm5uPqRnqKXK+1wLaGU+AajbksaoO/f0L3UMiN8R62+HtC4zkecds3PC9WbaYvnpzLdDjNSBKE3Iw+gOPBAZaFevaDVMni4FhhiYo3b/UicN+3vpO+skOagR6bwG6ihGVakejRhgTxtOxcbzn+cLCl9RPgDjpLRpdBNCWEevS/pqCYRrEsOAv28EfwkjBk/ZV6zdeDIaxNkTajvzPZohosER1S26YKSMBps8kgdGhwSzjfgvB1X39Bxf+xlRUt97er0kQunNE9FqZBA3JGYeV4PYdvS13+ii7Vu7YJ8Va8NrFIcAlMk6G5WeEi3l+uAuVT0E1vT9C3j7PmTB9aA8S0dJ7QhNY1eeotCl6tl1Mq2bU8qLtLb6VuQITXVdknXpYbpuZLuHVy3SvipO6OKhZ1AKdTIa1SRWLovekVepduMsUOOTCYnOmn/w1bEoUGGk3u4sjlxRD 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: A memory tiering abstract distance calculation algorithm based on ACPI HMAT is implemented. The basic idea is as follows. The performance attributes of system default DRAM nodes are recorded as the base line. Whose abstract distance is MEMTIER_ADISTANCE_DRAM. Then, the ratio of the abstract distance of a memory node (target) to MEMTIER_ADISTANCE_DRAM is scaled based on the ratio of the performance attributes of the node to that of the default DRAM nodes. Signed-off-by: "Huang, Ying" Tested-by: Bharata B Rao Cc: Aneesh Kumar K.V Cc: Wei Xu Cc: Alistair Popple Cc: Dan Williams Cc: Dave Hansen Cc: Davidlohr Bueso Cc: Johannes Weiner Cc: Jonathan Cameron Cc: Michal Hocko Cc: Yang Shi Cc: Rafael J Wysocki --- drivers/acpi/numa/hmat.c | 137 ++++++++++++++++++++++++++++++++++- include/linux/memory-tiers.h | 2 + mm/memory-tiers.c | 2 +- 3 files changed, 139 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 2dee0098f1a9..02114b376618 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -24,6 +24,7 @@ #include #include #include +#include static u8 hmat_revision; static int hmat_disable __initdata; @@ -759,6 +760,136 @@ static int hmat_callback(struct notifier_block *self, return NOTIFY_OK; } +static int hmat_adistance_disabled; +static struct node_hmem_attrs default_dram_attrs; + +static void dump_hmem_attrs(struct node_hmem_attrs *attrs) +{ + pr_cont("read_latency: %u, write_latency: %u, read_bandwidth: %u, write_bandwidth: %u\n", + attrs->read_latency, attrs->write_latency, + attrs->read_bandwidth, attrs->write_bandwidth); +} + +static void disable_hmat_adistance_algorithm(void) +{ + hmat_adistance_disabled = true; +} + +static int hmat_init_default_dram_attrs(void) +{ + struct memory_target *target; + struct node_hmem_attrs *attrs; + int nid, pxm; + int nid_dram = NUMA_NO_NODE; + + if (default_dram_attrs.read_latency + + default_dram_attrs.write_latency != 0) + return 0; + + if (!default_dram_type) + return -EIO; + + for_each_node_mask(nid, default_dram_type->nodes) { + pxm = node_to_pxm(nid); + target = find_mem_target(pxm); + if (!target) + continue; + attrs = &target->hmem_attrs[1]; + if (nid_dram == NUMA_NO_NODE) { + if (attrs->read_latency + attrs->write_latency == 0 || + attrs->read_bandwidth + attrs->write_bandwidth == 0) { + pr_info("hmat: invalid hmem attrs for default DRAM node: %d,\n", + nid); + pr_info(" "); + dump_hmem_attrs(attrs); + pr_info(" disable hmat based abstract distance algorithm.\n"); + disable_hmat_adistance_algorithm(); + return -EIO; + } + nid_dram = nid; + default_dram_attrs = *attrs; + continue; + } + + /* + * The performance of all default DRAM nodes is expected + * to be same (that is, the variation is less than 10%). + * And it will be used as base to calculate the abstract + * distance of other memory nodes. + */ + if (abs(attrs->read_latency - default_dram_attrs.read_latency) * 10 > + default_dram_attrs.read_latency || + abs(attrs->write_latency - default_dram_attrs.write_latency) * 10 > + default_dram_attrs.write_latency || + abs(attrs->read_bandwidth - default_dram_attrs.read_bandwidth) * 10 > + default_dram_attrs.read_bandwidth) { + pr_info("hmat: hmem attrs for DRAM nodes mismatch.\n"); + pr_info(" node %d: ", nid_dram); + dump_hmem_attrs(&default_dram_attrs); + pr_info(" node %d: ", nid); + dump_hmem_attrs(attrs); + pr_info(" disable hmat based abstract distance algorithm.\n"); + disable_hmat_adistance_algorithm(); + return -EIO; + } + } + + return 0; +} + +static int hmat_calculate_adistance(struct notifier_block *self, + unsigned long nid, void *data) +{ + static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); + struct memory_target *target; + struct node_hmem_attrs *attrs; + int *adist = data; + int pxm; + + if (hmat_adistance_disabled) + return NOTIFY_OK; + + pxm = node_to_pxm(nid); + target = find_mem_target(pxm); + if (!target) + return NOTIFY_OK; + + if (hmat_init_default_dram_attrs()) + return NOTIFY_OK; + + mutex_lock(&target_lock); + hmat_update_target_attrs(target, p_nodes, 1); + mutex_unlock(&target_lock); + + attrs = &target->hmem_attrs[1]; + + if (attrs->read_latency + attrs->write_latency == 0 || + attrs->read_bandwidth + attrs->write_bandwidth == 0) + return NOTIFY_OK; + + /* + * The abstract distance of a memory node is in direct + * proportion to its memory latency (read + write) and + * inversely proportional to its memory bandwidth (read + + * write). The abstract distance, memory latency, and memory + * bandwidth of the default DRAM nodes are used as the base. + */ + *adist = MEMTIER_ADISTANCE_DRAM * + (attrs->read_latency + attrs->write_latency) / + (default_dram_attrs.read_latency + + default_dram_attrs.write_latency) * + (default_dram_attrs.read_bandwidth + + default_dram_attrs.write_bandwidth) / + (attrs->read_bandwidth + attrs->write_bandwidth); + + return NOTIFY_STOP; +} + +static struct notifier_block hmat_adist_nb __meminitdata = { + .notifier_call = hmat_calculate_adistance, + .priority = 100, +}; + static __init void hmat_free_structures(void) { struct memory_target *target, *tnext; @@ -801,6 +932,7 @@ static __init int hmat_init(void) struct acpi_table_header *tbl; enum acpi_hmat_type i; acpi_status status; + int usage; if (srat_disabled() || hmat_disable) return 0; @@ -841,8 +973,11 @@ static __init int hmat_init(void) hmat_register_targets(); /* Keep the table and structures if the notifier may use them */ - if (!hotplug_memory_notifier(hmat_callback, HMAT_CALLBACK_PRI)) + usage = !hotplug_memory_notifier(hmat_callback, HMAT_CALLBACK_PRI); + usage += !register_mt_adistance_algorithm(&hmat_adist_nb); + if (usage) return 0; + out_put: hmat_free_structures(); acpi_put_table(tbl); diff --git a/include/linux/memory-tiers.h b/include/linux/memory-tiers.h index c6429e624244..9377239c8d34 100644 --- a/include/linux/memory-tiers.h +++ b/include/linux/memory-tiers.h @@ -33,6 +33,7 @@ struct memory_dev_type { #ifdef CONFIG_NUMA extern bool numa_demotion_enabled; +extern struct memory_dev_type *default_dram_type; struct memory_dev_type *alloc_memory_type(int adistance); void destroy_memory_type(struct memory_dev_type *memtype); void init_node_memory_type(int node, struct memory_dev_type *default_type); @@ -64,6 +65,7 @@ static inline bool node_is_toptier(int node) #else #define numa_demotion_enabled false +#define default_dram_type NULL /* * CONFIG_NUMA implementation returns non NULL error. */ diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c index 1e55fbe2ad51..9a734ef2edfb 100644 --- a/mm/memory-tiers.c +++ b/mm/memory-tiers.c @@ -37,7 +37,7 @@ struct node_memory_type_map { static DEFINE_MUTEX(memory_tier_lock); static LIST_HEAD(memory_tiers); static struct node_memory_type_map node_memory_types[MAX_NUMNODES]; -static struct memory_dev_type *default_dram_type; +struct memory_dev_type *default_dram_type; static struct bus_type memory_tier_subsys = { .name = "memory_tiering",