From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56CB3C433EF for ; Tue, 25 Jan 2022 07:25:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1387820AbiAYHZj (ORCPT ); Tue, 25 Jan 2022 02:25:39 -0500 Received: from esa1.hc1455-7.c3s2.iphmx.com ([207.54.90.47]:58051 "EHLO esa1.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443900AbiAYHVu (ORCPT ); Tue, 25 Jan 2022 02:21:50 -0500 X-Greylist: delayed 444 seconds by postgrey-1.27 at vger.kernel.org; Tue, 25 Jan 2022 02:21:42 EST IronPort-SDR: Tt5KRiiNzwRLEImD11muCHZO8uJGCcRjIgpU3Rwcryhj7nP7t6x0HRskhPamZinmuHd4Kjgg/u 8lu6ru5ztH3x/K+CV1Dtw9jFea2j59LvPJuvqT6AgWtXZJEizCE8ZaFOsSXrdIQ+pzFSUHKQoG CAMdFqum2rAu8PVLkULQLmLsxIQ0/GbhN1oEoOgjJ/lkU1xMpNN8mB/rwuegN5h3HVDVdVRnli 2zJnUdlA9A+FZj3w26BPW25+MeCwI4MZYDgQRGCFl7jS0hmGRFWqf0S7+5lSYU6T3LRuxvY0HM ff1Q+xnzfH3Ak4kM2r6ncq3m X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60525454" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60525454" Received: from unknown (HELO yto-r3.gw.nic.fujitsu.com) ([218.44.52.219]) by esa1.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:12 +0900 Received: from yto-m4.gw.nic.fujitsu.com (yto-nat-yto-m4.gw.nic.fujitsu.com [192.168.83.67]) by yto-r3.gw.nic.fujitsu.com (Postfix) with ESMTP id 4D1FAE3E10 for ; Tue, 25 Jan 2022 16:14:11 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by yto-m4.gw.nic.fujitsu.com (Postfix) with ESMTP id 6E565EA178 for ; Tue, 25 Jan 2022 16:14:10 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id 357744007ED6C; Tue, 25 Jan 2022 16:14:10 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 1/8] drivers: base: Add hardware prefetch control core driver Date: Tue, 25 Jan 2022 16:14:07 +0900 Message-Id: <20220125071414.811344-2-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This driver provides a register/unregister function to create the sysfs interface with an attribute file named "prefetch_control" in every CPU's cache/index[0,2] directory. If the architecture has control of the CPU's hardware prefetcher behavior, use this function to create sysfs. When registering, it is necessary to provide what type of hardware prefetcher is supported and how to read/write to the register. Following patches add support for ARM64 and x86. Signed-off-by: Kohei Tarumizu --- drivers/base/pfctl.c | 541 ++++++++++++++++++++++++++++++++++++++++++ include/linux/pfctl.h | 42 ++++ 2 files changed, 583 insertions(+) create mode 100644 drivers/base/pfctl.c create mode 100644 include/linux/pfctl.h diff --git a/drivers/base/pfctl.c b/drivers/base/pfctl.c new file mode 100644 index 000000000000..4bc3c2826d69 --- /dev/null +++ b/drivers/base/pfctl.c @@ -0,0 +1,541 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2022 FUJITSU LIMITED + * + * This driver provides tunable sysfs interface for Hardware Prefetch Cont= rol. + * See Documentation/ABI/testing/sysfs-devices-system-cpu for more informa= tion. + * + * This code provides architecture-independent functions such as create and + * remove attribute file. + * The implementation of reads and writes to the Hardware Prefetch Control + * register is architecture-dependent. Therefore, each architecture regist= er + * a callback to read and write the register via pfctl_register_driver(). + */ + +#include +#include +#include +#include +#include +#include + +#ifdef pr_fmt +#undef pr_fmt +#endif +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +enum { + OPT_HWPF_ENABLE, + OPT_IPPF_ENABLE, + OPT_ACLPF_ENABLE, + OPT_SDPF_ENABLE, + OPT_SDPF_DIST, + OPT_SDPF_DIST_AUTO, + OPT_SDPF_STRONG, + OPT_ERR, +}; + +static const char hwpf_enable_fmt[] =3D "hardware_prefetcher_enable=3D%s"; +static const char ippf_enable_fmt[] =3D "ip_prefetcher_enable=3D%s"; +static const char aclpf_enable_fmt[] =3D + "adjacent_cache_line_prefetcher_enable=3D%s"; +static const char sdpf_enable_fmt[] =3D "stream_detect_prefetcher_enable= =3D%s"; +static const char sdpf_dist_fmt[] =3D "stream_detect_prefetcher_dist=3D%d"; +static const char sdpf_dist_auto_fmt[] =3D "stream_detect_prefetcher_dist= =3D%s"; +static const char sdpf_strong_fmt[] =3D "stream_detect_prefetcher_strong= =3D%s"; + +static const match_table_t pfctl_opt_tokens =3D { + {OPT_HWPF_ENABLE, hwpf_enable_fmt}, + {OPT_IPPF_ENABLE, ippf_enable_fmt}, + {OPT_ACLPF_ENABLE, aclpf_enable_fmt}, + {OPT_SDPF_ENABLE, sdpf_enable_fmt}, + {OPT_SDPF_DIST, sdpf_dist_fmt}, + {OPT_SDPF_DIST_AUTO, sdpf_dist_auto_fmt}, + {OPT_SDPF_STRONG, sdpf_strong_fmt}, + {OPT_ERR, NULL}, +}; + +static DEFINE_PER_CPU(struct device *, cache_device_pcpu); +#define per_cpu_cache_device(cpu) (per_cpu(cache_device_pcpu, cpu)) + +struct pfctl_driver *pdriver; +enum cpuhp_state hp_online; + +static bool prefetcher_is_available(unsigned int level, enum cache_type ty= pe, + int prefetcher) +{ + if ((level =3D=3D 1) && (type =3D=3D CACHE_TYPE_DATA)) + if (pdriver->supported_l1d_prefetcher & prefetcher) + return true; + else + return false; + else if ((level =3D=3D 2) && + (type =3D=3D CACHE_TYPE_UNIFIED)) + if (pdriver->supported_l2_prefetcher & prefetcher) + return true; + else + return false; + else + return false; +} + +static int parse_prefetch_options(struct prefetcher_options *opts, + const char *buf, unsigned int level, + enum cache_type type) +{ + char *options, *sep_opt, *p; + substring_t args[MAX_OPT_ARGS]; + int opt_mask =3D 0; + int token; + int ret =3D 0; + + options =3D kstrdup(buf, GFP_KERNEL); + if (!options) + return -ENOMEM; + + sep_opt =3D strstrip(options); + while ((p =3D strsep(&sep_opt, " ")) !=3D NULL) { + unsigned int val; + + if (!*p) + continue; + + token =3D match_token(p, pfctl_opt_tokens, args); + opt_mask |=3D token; + + switch (token) { + case OPT_HWPF_ENABLE: + if (!prefetcher_is_available(level, type, HWPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "enable")) { + opts->hwpf_enable =3D PFCTL_ENABLE_VAL; + } else if (!strcmp(p, "disable")) { + opts->hwpf_enable =3D PFCTL_DISABLE_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + case OPT_IPPF_ENABLE: + if (!prefetcher_is_available(level, type, IPPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "enable")) { + opts->ippf_enable =3D PFCTL_ENABLE_VAL; + } else if (!strcmp(p, "disable")) { + opts->ippf_enable =3D PFCTL_DISABLE_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + case OPT_ACLPF_ENABLE: + if (!prefetcher_is_available(level, type, ACLPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "enable")) { + opts->aclpf_enable =3D PFCTL_ENABLE_VAL; + } else if (!strcmp(p, "disable")) { + opts->aclpf_enable =3D PFCTL_DISABLE_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + case OPT_SDPF_ENABLE: + if (!prefetcher_is_available(level, type, SDPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "enable")) { + opts->sdpf_enable =3D PFCTL_ENABLE_VAL; + } else if (!strcmp(p, "disable")) { + opts->sdpf_enable =3D PFCTL_DISABLE_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + case OPT_SDPF_DIST: + if (!prefetcher_is_available(level, type, SDPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + ret =3D match_uint(args, &val); + if (ret < 0) { + pr_err("Invalid value: '%s'\n", p); + goto out; + } + + opts->sdpf_dist =3D val; + break; + case OPT_SDPF_DIST_AUTO: + if (!prefetcher_is_available(level, type, SDPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "auto")) { + opts->sdpf_dist =3D PFCTL_DIST_AUTO_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + case OPT_SDPF_STRONG: + if (!prefetcher_is_available(level, type, SDPF)) { + pr_err("Unsupported parameter: '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + p =3D match_strdup(args); + if (!p) { + ret =3D -ENOMEM; + goto out; + } + + if (!strcmp(p, "strong")) { + opts->sdpf_strong =3D PFCTL_STRONG_VAL; + } else if (!strcmp(p, "weak")) { + opts->sdpf_strong =3D PFCTL_WEAK_VAL; + } else { + pr_err("Invalid value: '%s'\n", p); + ret =3D -EINVAL; + kfree(p); + goto out; + } + + kfree(p); + break; + default: + pr_err("Unknown parameter or missing value '%s'\n", p); + ret =3D -EINVAL; + goto out; + } + } + +out: + kfree(options); + return ret; +} + +static ssize_t prefetch_control_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned int cpu; + ssize_t len =3D 0; + struct prefetcher_options opts; + struct cacheinfo *this_leaf =3D dev_get_drvdata(dev); + + cpu =3D dev->parent->parent->id; + + ret =3D pdriver->read_pfreg(cpu, this_leaf->level, &opts); + if (ret < 0) + return ret; + + if (prefetcher_is_available(this_leaf->level, this_leaf->type, HWPF)) { + if (opts.hwpf_enable =3D=3D PFCTL_ENABLE_VAL) + len +=3D sysfs_emit_at(buf, len, hwpf_enable_fmt, + "enable"); + else + len +=3D sysfs_emit_at(buf, len, hwpf_enable_fmt, + "disable"); + len +=3D sysfs_emit_at(buf, len, "\n"); + } + + if (prefetcher_is_available(this_leaf->level, this_leaf->type, IPPF)) { + if (opts.ippf_enable =3D=3D PFCTL_ENABLE_VAL) + len +=3D sysfs_emit_at(buf, len, ippf_enable_fmt, + "enable"); + else + len +=3D sysfs_emit_at(buf, len, ippf_enable_fmt, + "disable"); + len +=3D sysfs_emit_at(buf, len, "\n"); + } + + if (prefetcher_is_available(this_leaf->level, this_leaf->type, ACLPF)) { + if (opts.aclpf_enable =3D=3D PFCTL_ENABLE_VAL) + len +=3D sysfs_emit_at(buf, len, aclpf_enable_fmt, + "enable"); + else + len +=3D sysfs_emit_at(buf, len, aclpf_enable_fmt, + "disable"); + len +=3D sysfs_emit_at(buf, len, "\n"); + } + + if (prefetcher_is_available(this_leaf->level, this_leaf->type, SDPF)) { + if (opts.sdpf_enable =3D=3D PFCTL_ENABLE_VAL) + len +=3D sysfs_emit_at(buf, len, sdpf_enable_fmt, + "enable"); + else + len +=3D sysfs_emit_at(buf, len, sdpf_enable_fmt, + "disable"); + len +=3D sysfs_emit_at(buf, len, "\n"); + + if (opts.sdpf_dist =3D=3D PFCTL_DIST_AUTO_VAL) + len +=3D sysfs_emit_at(buf, len, sdpf_dist_auto_fmt, + "auto"); + else + len +=3D sysfs_emit_at(buf, len, sdpf_dist_fmt, + opts.sdpf_dist); + len +=3D sysfs_emit_at(buf, len, "\n"); + + if (opts.sdpf_strong =3D=3D PFCTL_STRONG_VAL) + len +=3D sysfs_emit_at(buf, len, sdpf_strong_fmt, + "strong"); + else + len +=3D sysfs_emit_at(buf, len, sdpf_strong_fmt, + "weak"); + len +=3D sysfs_emit_at(buf, len, "\n"); + } + + return len; +} + +static ssize_t prefetch_control_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned int cpu; + struct cacheinfo *this_leaf =3D dev_get_drvdata(dev); + struct prefetcher_options opts =3D { + .hwpf_enable =3D PFCTL_PARAM_UNSET, + .ippf_enable =3D PFCTL_PARAM_UNSET, + .aclpf_enable =3D PFCTL_PARAM_UNSET, + .sdpf_enable =3D PFCTL_PARAM_UNSET, + .sdpf_dist =3D PFCTL_PARAM_UNSET, + .sdpf_strong =3D PFCTL_PARAM_UNSET, + }; + + cpu =3D dev->parent->parent->id; + + ret =3D parse_prefetch_options(&opts, buf, this_leaf->level, + this_leaf->type); + if (ret < 0) + return ret; + + ret =3D pdriver->write_pfreg(cpu, this_leaf->level, &opts); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR_ADMIN_RW(prefetch_control); + +static int find_cache_device(unsigned int cpu) +{ + struct device *cpu_dev =3D get_cpu_device(cpu); + struct device *cache_dev; + + cache_dev =3D device_find_child_by_name(cpu_dev, "cache"); + if (!cache_dev) + return -ENODEV; + per_cpu_cache_device(cpu) =3D cache_dev; + + return 0; +} + +static int _create_pfctl_attr(struct device *dev, void *data) +{ + int ret; + struct cacheinfo *leaf =3D dev_get_drvdata(dev); + + if (!prefetcher_is_available(leaf->level, leaf->type, ANYPF)) + return 0; + + ret =3D sysfs_create_file(&dev->kobj, &dev_attr_prefetch_control.attr); + if (ret < 0) { + pr_err("sysfs_create_file failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int create_pfctl_attr(unsigned int cpu) +{ + int ret; + struct device *cache_dev =3D per_cpu_cache_device(cpu); + + if (!cache_dev) + return -ENODEV; + + ret =3D device_for_each_child(cache_dev, NULL, _create_pfctl_attr); + if (ret < 0) + return ret; + + return 0; +} + +static int _remove_pfctl_attr(struct device *dev, void *data) +{ + struct cacheinfo *leaf =3D dev_get_drvdata(dev); + + if (!prefetcher_is_available(leaf->level, leaf->type, ANYPF)) + return 0; + + sysfs_remove_file(&dev->kobj, &dev_attr_prefetch_control.attr); + + return 0; +} + +static void remove_pfctl_attr(unsigned int cpu) +{ + struct device *cache_dev =3D per_cpu_cache_device(cpu); + + if (!cache_dev) + return; + + device_for_each_child(cache_dev, NULL, _remove_pfctl_attr); +} + +static int pfctl_online(unsigned int cpu) +{ + int ret; + + ret =3D find_cache_device(cpu); + if (ret < 0) + return ret; + + ret =3D create_pfctl_attr(cpu); + if (ret < 0) + return ret; + + return 0; +} + +static int pfctl_prepare_down(unsigned int cpu) +{ + remove_pfctl_attr(cpu); + + return 0; +} + +/** + * pfctl_register_driver - register a Hardware Prefetch Control driver + * @driver_data: struct pfctl_driver must contain the supported prefetcher= type + * and function pointer for reading and writing hardware pre= fetch + * register. If these are not defined this function return e= rror. + * + * Note: This function must be called after the cache device is initialized + * because it requires access to the cache device. + * (e.g. Call at the late_initcall) + * + * Context: Any context. + * Return: 0 on success, negative error code on failure. + */ +int pfctl_register_driver(struct pfctl_driver *driver_data) +{ + int ret; + + if (pdriver) + return -EEXIST; + + if ((driver_data->supported_l1d_prefetcher =3D=3D 0) && + (driver_data->supported_l2_prefetcher =3D=3D 0)) + return -EINVAL; + + if (!driver_data->read_pfreg || !driver_data->write_pfreg) + return -EINVAL; + + pdriver =3D driver_data; + + ret =3D cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/pfctl:online", + pfctl_online, pfctl_prepare_down); + if (ret < 0) { + pr_err("failed to register hotplug callbacks\n"); + pdriver =3D NULL; + return ret; + } + + hp_online =3D ret; + + return 0; +} +EXPORT_SYMBOL_GPL(pfctl_register_driver); + +/** + * pfctl_unregister_driver - unregister the Hardware Prefetch Control driv= er + * @driver_data: Used to verify that this function is called by the driver= that + * called pfctl_register_driver by determining if driver_dat= a is + * the same. + * + * Context: Any context. + * Return: nothing. + */ +void pfctl_unregister_driver(struct pfctl_driver *driver_data) +{ + if (!pdriver || (driver_data !=3D pdriver)) + return; + + cpuhp_remove_state(hp_online); + + pdriver =3D NULL; +} +EXPORT_SYMBOL_GPL(pfctl_unregister_driver); diff --git a/include/linux/pfctl.h b/include/linux/pfctl.h new file mode 100644 index 000000000000..7a05e2f4a4f7 --- /dev/null +++ b/include/linux/pfctl.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_PFCTL_H +#define _LINUX_PFCTL_H + +#define PFCTL_ENABLE_VAL 0 +#define PFCTL_DISABLE_VAL 1 +#define PFCTL_DIST_AUTO_VAL 0 +#define PFCTL_STRONG_VAL 0 +#define PFCTL_WEAK_VAL 1 +#define PFCTL_PARAM_UNSET -1 + +struct prefetcher_options { + int hwpf_enable; + int ippf_enable; + int aclpf_enable; + int sdpf_enable; + int sdpf_dist; + int sdpf_strong; +}; + +enum prefetcher { + HWPF =3D BIT(0), /* Hardware Prefetcher */ + IPPF =3D BIT(1), /* IP Prefetcher */ + ACLPF =3D BIT(2), /* Adjacent Cache Line Prefetcher */ + SDPF =3D BIT(3), /* Stream Detect Prefetcher */ + ANYPF =3D HWPF|IPPF|ACLPF|SDPF, +}; + +struct pfctl_driver { + unsigned int supported_l1d_prefetcher; + unsigned int supported_l2_prefetcher; + + int (*read_pfreg)(unsigned int cpu, unsigned int level, + struct prefetcher_options *opt); + int (*write_pfreg)(unsigned int cpu, unsigned int level, + struct prefetcher_options *opt); +}; + +int pfctl_register_driver(struct pfctl_driver *driver_data); +void pfctl_unregister_driver(struct pfctl_driver *driver_data); + +#endif --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8EFABC433F5 for ; Tue, 25 Jan 2022 07:26:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359860AbiAYH0J (ORCPT ); Tue, 25 Jan 2022 02:26:09 -0500 Received: from esa5.hc1455-7.c3s2.iphmx.com ([68.232.139.130]:24644 "EHLO esa5.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443999AbiAYHV5 (ORCPT ); Tue, 25 Jan 2022 02:21:57 -0500 X-Greylist: delayed 449 seconds by postgrey-1.27 at vger.kernel.org; Tue, 25 Jan 2022 02:21:57 EST IronPort-SDR: Hulmt9SCTCfNRZKC3fW6Qmcyfi13TwRwVOtSPTVRwkiluoOdONI58QxyTB5cLnt8DUlJ8cLecz VjfS7YqGZdZ7xs0AD7o/79b84RUpT+lz9UnUzknnSFznp9VI0/GC6tv+RhnnzRLy71dXZQXAXZ 26t+SzhsStBYVqYY103lZVNs35cmFfiEzmOnmSHCVbOixPAXv7K9WYi3iZXzaArA8SQrLRYx3G kertGmq3yjkrUbOhZ0kvWR56IY3Znp8p/rTi2GDtk2zbzoXxIy9XZWEbMamLQ8RAkXfzT7ftP1 6+v13Hi39pHOnIwTcbAgdW9r X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60079426" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60079426" Received: from unknown (HELO oym-r2.gw.nic.fujitsu.com) ([210.162.30.90]) by esa5.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:16 +0900 Received: from oym-m3.gw.nic.fujitsu.com (oym-nat-oym-m3.gw.nic.fujitsu.com [192.168.87.60]) by oym-r2.gw.nic.fujitsu.com (Postfix) with ESMTP id 9A680DB9F7 for ; Tue, 25 Jan 2022 16:14:15 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by oym-m3.gw.nic.fujitsu.com (Postfix) with ESMTP id D2A86D95EE for ; Tue, 25 Jan 2022 16:14:14 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id 87F6B4007ED6C; Tue, 25 Jan 2022 16:14:14 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 2/8] drivers: base: Add Kconfig/Makefile to build hardware prefetch control core driver Date: Tue, 25 Jan 2022 16:14:08 +0900 Message-Id: <20220125071414.811344-3-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds Kconfig/Makefile to build hardware prefetch control core driver. This also adds a MAINTAINERS entry. Signed-off-by: Kohei Tarumizu --- MAINTAINERS | 6 ++++++ drivers/base/Kconfig | 13 +++++++++++++ drivers/base/Makefile | 1 + 3 files changed, 20 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ea3e6c914384..b474051c41e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8444,6 +8444,12 @@ F: include/linux/hwmon*.h F: include/trace/events/hwmon*.h K: (devm_)?hwmon_device_(un)?register(|_with_groups|_with_info) =20 +HARDWARE PREFETCH CONTROL DRIVERS +M: Kohei Tarumizu +S: Maintained +F: drivers/base/pfctl.c +F: include/linux/pfctl.h + HARDWARE RANDOM NUMBER GENERATOR CORE M: Matt Mackall M: Herbert Xu diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 6f04b831a5c0..d146604b5b3a 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -230,4 +230,17 @@ config GENERIC_ARCH_NUMA Enable support for generic NUMA implementation. Currently, RISC-V and ARM64 use it. =20 +config ARCH_HAS_HWPF_CONTROL + bool + +config HWPF_CONTROL + bool "Hardware Prefetch Control driver" + depends on ARCH_HAS_HWPF_CONTROL && SYSFS + help + This driver allows user to control CPU's Hardware Prefetch behavior. + If the machine supports this behavior, it provides a sysfs interface. + + See Documentation/ABI/testing/sysfs-devices-system-cpu for more + information. + endmenu diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 02f7f1358e86..13f3a0ddf3d1 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_DEV_COREDUMP) +=3D devcoredump.o obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) +=3D platform-msi.o obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) +=3D arch_topology.o obj-$(CONFIG_GENERIC_ARCH_NUMA) +=3D arch_numa.o +obj-$(CONFIG_HWPF_CONTROL) +=3D pfctl.o =20 obj-y +=3D test/ =20 --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E22BC433F5 for ; Tue, 25 Jan 2022 07:26:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1445086AbiAYH0B (ORCPT ); Tue, 25 Jan 2022 02:26:01 -0500 Received: from esa1.hc1455-7.c3s2.iphmx.com ([207.54.90.47]:58061 "EHLO esa1.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443458AbiAYHV5 (ORCPT ); Tue, 25 Jan 2022 02:21:57 -0500 IronPort-SDR: ZM928DjHdUPW+d/4tYWCvExLyaJLLvIP+7FMuC9Ds4zd9uLq7fKI+VXqJeafAtVa5fTZuW2TIv 3FmWhMyjx9b6VV+7ulWFWAFMjLibhb4ZC6dwUOsG80H1k3A6+k9kWw3/pfxw5dkhRlB7h1sOoQ XqzfC3s9wqlKjkWjjZ9Wv+qdH/D5sUJPvdvt4Ax6l/qc14E8sTmlH6SOrUYbwaV42jVWhzl78x x2dXnaD9/Rds0YZe325O+Y8Acs9/ii+S5va/90iCkJH6GFLi3bOmXAKRSx9O0+2AWFR9sbq07J WW+KJg1JV+LN85vghjAVXI3b X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60525469" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60525469" Received: from unknown (HELO oym-r1.gw.nic.fujitsu.com) ([210.162.30.89]) by esa1.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:19 +0900 Received: from oym-m4.gw.nic.fujitsu.com (oym-nat-oym-m4.gw.nic.fujitsu.com [192.168.87.61]) by oym-r1.gw.nic.fujitsu.com (Postfix) with ESMTP id 05DDAE8FF8 for ; Tue, 25 Jan 2022 16:14:18 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by oym-m4.gw.nic.fujitsu.com (Postfix) with ESMTP id 31FD819826 for ; Tue, 25 Jan 2022 16:14:17 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id DB25C4007ED6C; Tue, 25 Jan 2022 16:14:16 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 3/8] arm64: Add hardware prefetch control support for ARM64 Date: Tue, 25 Jan 2022 16:14:09 +0900 Message-Id: <20220125071414.811344-4-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds module init/exit code, and creates sysfs attribute files for "prefetch_control". This driver works only if part number is FUJITSU_CPU_PART_A64FX at this point. The details of the registers to be read and written in this patch are described below. "https://github.com/fujitsu/A64FX/tree/master/doc/" A64FX_Specification_HPC_Extension_v1_EN.pdf Signed-off-by: Kohei Tarumizu --- arch/arm64/kernel/pfctl.c | 324 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 arch/arm64/kernel/pfctl.c diff --git a/arch/arm64/kernel/pfctl.c b/arch/arm64/kernel/pfctl.c new file mode 100644 index 000000000000..14f4b8248280 --- /dev/null +++ b/arch/arm64/kernel/pfctl.c @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2022 FUJITSU LIMITED + * + * ARM64 Hardware Prefetch Control support + */ + +#include +#include +#include +#include +#include +#include + +struct pfctl_driver arm64_pfctl_driver; + +/************************************** + * FUJITSU A64FX support + **************************************/ + +/* + * Constants for these add the "A64FX_SDPF" prefix to the name described in + * section "1.3.4.2. IMP_PF_STREAM_DETECT_CTRL_EL0" of "A64FX specificatio= n". + * (https://github.com/fujitsu/A64FX/tree/master/doc/A64FX_Specification_H= PC_Extension_v1_EN.pdf") + * See this document for register specification details. + */ +#define A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0 sys_reg(3, 3, 11, 4, 0) +#define A64FX_SDPF_V BIT_ULL(63) +#define A64FX_SDPF_L1PF_DIS BIT_ULL(59) +#define A64FX_SDPF_L2PF_DIS BIT_ULL(58) +#define A64FX_SDPF_L1W BIT_ULL(55) +#define A64FX_SDPF_L2W BIT_ULL(54) +#define A64FX_SDPF_L1_DIST GENMASK_ULL(27, 24) +#define A64FX_SDPF_L2_DIST GENMASK_ULL(19, 16) + +#define A64FX_SDPF_MIN_DIST_L1 256 +#define A64FX_SDPF_MIN_DIST_L2 1024 + +struct a64fx_read_info { + struct prefetcher_options *opts; + unsigned int level; + int ret; +}; + +struct a64fx_write_info { + struct prefetcher_options *opts; + unsigned int level; + int ret; +}; + +static int a64fx_get_sdpf_enable(u64 reg, unsigned int level) +{ + switch (level) { + case 1: + return FIELD_GET(A64FX_SDPF_L1PF_DIS, reg); + case 2: + return FIELD_GET(A64FX_SDPF_L2PF_DIS, reg); + default: + return -EINVAL; + } +} + +static int a64fx_modify_sdpf_enable(u64 *reg, unsigned int level, int val) +{ + switch (level) { + case 1: + *reg &=3D ~A64FX_SDPF_L1PF_DIS; + *reg |=3D FIELD_PREP(A64FX_SDPF_L1PF_DIS, val); + break; + case 2: + *reg &=3D ~A64FX_SDPF_L2PF_DIS; + *reg |=3D FIELD_PREP(A64FX_SDPF_L2PF_DIS, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int a64fx_get_sdpf_dist(u64 reg, unsigned int level) +{ + switch (level) { + case 1: + return FIELD_GET(A64FX_SDPF_L1_DIST, reg) * + A64FX_SDPF_MIN_DIST_L1; + case 2: + return FIELD_GET(A64FX_SDPF_L2_DIST, reg) * + A64FX_SDPF_MIN_DIST_L2; + default: + return -EINVAL; + } +} + +static int a64fx_modify_sdpf_dist(u64 *reg, unsigned int level, int val) +{ + switch (level) { + case 1: + val =3D roundup(val, A64FX_SDPF_MIN_DIST_L1) / + A64FX_SDPF_MIN_DIST_L1; + if (!FIELD_FIT(A64FX_SDPF_L1_DIST, val)) + return -EINVAL; + *reg &=3D ~A64FX_SDPF_L1_DIST; + *reg |=3D FIELD_PREP(A64FX_SDPF_L1_DIST, val); + break; + case 2: + val =3D roundup(val, A64FX_SDPF_MIN_DIST_L2) / + A64FX_SDPF_MIN_DIST_L2; + if (!FIELD_FIT(A64FX_SDPF_L2_DIST, val)) + return -EINVAL; + *reg &=3D ~A64FX_SDPF_L2_DIST; + *reg |=3D FIELD_PREP(A64FX_SDPF_L2_DIST, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int a64fx_get_sdpf_strong(u64 reg, unsigned int level) +{ + switch (level) { + case 1: + return FIELD_GET(A64FX_SDPF_L1W, reg); + case 2: + return FIELD_GET(A64FX_SDPF_L2W, reg); + default: + return -EINVAL; + } +} + +static int a64fx_modify_sdpf_strong(u64 *reg, unsigned int level, int val) +{ + switch (level) { + case 1: + *reg &=3D ~A64FX_SDPF_L1W; + *reg |=3D FIELD_PREP(A64FX_SDPF_L1W, val); + break; + case 2: + *reg &=3D ~A64FX_SDPF_L2W; + *reg |=3D FIELD_PREP(A64FX_SDPF_L2W, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static void a64fx_enable_sdpf_verify(u64 *reg) +{ + *reg &=3D ~A64FX_SDPF_V; + *reg |=3D FIELD_PREP(A64FX_SDPF_V, 1); +} + +static int a64fx_get_sdpf_params(struct prefetcher_options *opts, u64 reg, + unsigned int level) +{ + int ret; + + ret =3D a64fx_get_sdpf_enable(reg, level); + if (ret < 0) + return ret; + opts->sdpf_enable =3D ret; + + ret =3D a64fx_get_sdpf_dist(reg, level); + if (ret < 0) + return ret; + opts->sdpf_dist =3D ret; + + ret =3D a64fx_get_sdpf_strong(reg, level); + if (ret < 0) + return ret; + opts->sdpf_strong =3D ret; + + return 0; +} + +static int a64fx_modify_pfreg_val(u64 *reg, struct prefetcher_options *opt= s, + unsigned int level) +{ + int ret; + + if (opts->sdpf_enable !=3D PFCTL_PARAM_UNSET) { + ret =3D a64fx_modify_sdpf_enable(reg, level, opts->sdpf_enable); + if (ret < 0) + return ret; + } + + if (opts->sdpf_dist !=3D PFCTL_PARAM_UNSET) { + ret =3D a64fx_modify_sdpf_dist(reg, level, opts->sdpf_dist); + if (ret < 0) + return ret; + } + + if (opts->sdpf_strong !=3D PFCTL_PARAM_UNSET) { + ret =3D a64fx_modify_sdpf_strong(reg, level, opts->sdpf_strong); + if (ret < 0) + return ret; + } + + a64fx_enable_sdpf_verify(reg); + + return 0; +} + +static void _a64fx_read_pfreg(void *info) +{ + u64 reg; + struct a64fx_read_info *rinfo =3D info; + + reg =3D read_sysreg_s(A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0); + + rinfo->ret =3D a64fx_get_sdpf_params(rinfo->opts, reg, rinfo->level); +} + +static int a64fx_read_pfreg(unsigned int cpu, unsigned int level, + struct prefetcher_options *opt) +{ + struct a64fx_read_info info =3D { + .level =3D level, + .opts =3D opt, + }; + + smp_call_function_single(cpu, _a64fx_read_pfreg, &info, true); + return info.ret; +} + +static void _a64fx_write_pfreg(void *info) +{ + int ret; + u64 reg; + struct a64fx_write_info *winfo =3D info; + + reg =3D read_sysreg_s(A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0); + + ret =3D a64fx_modify_pfreg_val(®, winfo->opts, winfo->level); + if (ret < 0) { + winfo->ret =3D ret; + return; + } + + write_sysreg_s(reg, A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0); + + winfo->ret =3D 0; +} + +static int a64fx_write_pfreg(unsigned int cpu, unsigned int level, + struct prefetcher_options *opt) +{ + struct a64fx_write_info info =3D { + .level =3D level, + .opts =3D opt, + }; + + smp_call_function_single(cpu, _a64fx_write_pfreg, &info, true); + return info.ret; +} + +/***** end of FUJITSU A64FX support *****/ + +/* + * This driver returns a negative value if it does not support the Hardware + * Prefetch Control or if it is running on a VM guest. + */ +static int __init setup_pfctl_driver_params(void) +{ + unsigned long implementor =3D read_cpuid_implementor(); + unsigned long part_number =3D read_cpuid_part_number(); + + if (!is_kernel_in_hyp_mode()) + return -EINVAL; + + switch (implementor) { + case ARM_CPU_IMP_FUJITSU: + switch (part_number) { + case FUJITSU_CPU_PART_A64FX: + /* A64FX register requires EL2 access */ + if (!has_vhe()) + return -EINVAL; + + arm64_pfctl_driver.supported_l1d_prefetcher =3D SDPF; + arm64_pfctl_driver.supported_l2_prefetcher =3D SDPF; + arm64_pfctl_driver.read_pfreg =3D a64fx_read_pfreg; + arm64_pfctl_driver.write_pfreg =3D a64fx_write_pfreg; + break; + default: + return -ENODEV; + } + break; + default: + return -ENODEV; + } + + return 0; +} + +static int __init arm64_pfctl_init(void) +{ + int ret; + + ret =3D setup_pfctl_driver_params(); + if (ret < 0) + return ret; + + ret =3D pfctl_register_driver(&arm64_pfctl_driver); + if (ret < 0) + return ret; + + return 0; +} + +static void __exit arm64_pfctl_exit(void) +{ + pfctl_unregister_driver(&arm64_pfctl_driver); +} + +late_initcall(arm64_pfctl_init); +module_exit(arm64_pfctl_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("FUJITSU LIMITED"); +MODULE_DESCRIPTION("ARM64 Prefetch Control Driver"); --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB390C433EF for ; Tue, 25 Jan 2022 07:26:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378098AbiAYH0Q (ORCPT ); Tue, 25 Jan 2022 02:26:16 -0500 Received: from esa7.hc1455-7.c3s2.iphmx.com ([139.138.61.252]:16758 "EHLO esa7.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1444482AbiAYHV6 (ORCPT ); Tue, 25 Jan 2022 02:21:58 -0500 X-Greylist: delayed 432 seconds by postgrey-1.27 at vger.kernel.org; Tue, 25 Jan 2022 02:21:58 EST IronPort-SDR: DO5rrdXVRGdxqfxenqFIhBFYicT9pIjAggEXo2eXaGuXLO5twJoKYAy5umlxekrMFQ8KZNOfIx v955dTAkfR/Cl4/ypzdab2Cb5LH4L2Kq97+m0+w+CTYZAPJ6gazN5A5yzt/W189MOUQ+/Lnhli fQWAzx5tNjqFGci/dcrUmlbmqaGq0IQ43FvDEIH3Gsjczdl1m/3tHqPuB4RijojZWcnYbJvciW A9d/rLC6QJbazKwnzqMViYCNA9jdPrLNCiNe1d5BiQTTUwgRoFuPO5RRyQVMLqQHTgNrEpkGzS o5esxtIvgpMMpDjhThyS/RAQ X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="39268502" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="39268502" Received: from unknown (HELO yto-r1.gw.nic.fujitsu.com) ([218.44.52.217]) by esa7.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:34 +0900 Received: from yto-m2.gw.nic.fujitsu.com (yto-nat-yto-m2.gw.nic.fujitsu.com [192.168.83.65]) by yto-r1.gw.nic.fujitsu.com (Postfix) with ESMTP id 4A47DE5B29 for ; Tue, 25 Jan 2022 16:14:33 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by yto-m2.gw.nic.fujitsu.com (Postfix) with ESMTP id 7E6EBE654E for ; Tue, 25 Jan 2022 16:14:32 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id CC491400C1BBD; Tue, 25 Jan 2022 16:14:31 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 4/8] arm64: Add Kconfig/Makefile to build hardware prefetch control driver Date: Tue, 25 Jan 2022 16:14:10 +0900 Message-Id: <20220125071414.811344-5-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds Kconfig/Makefile to build hardware prefetch control driver for arm64 support. This also adds a MAINTAINERS entry. Signed-off-by: Kohei Tarumizu --- MAINTAINERS | 1 + arch/arm64/Kconfig | 8 ++++++++ arch/arm64/kernel/Makefile | 1 + 3 files changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b474051c41e7..0eaee76438e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8447,6 +8447,7 @@ K: (devm_)?hwmon_device_(un)?register(|_with_groups|_= with_info) HARDWARE PREFETCH CONTROL DRIVERS M: Kohei Tarumizu S: Maintained +F: arch/arm64/kernel/pfctl.c F: drivers/base/pfctl.c F: include/linux/pfctl.h =20 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 6978140edfa4..c2256dbb0243 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -36,6 +36,7 @@ config ARM64 select ARCH_HAS_SET_DIRECT_MAP select ARCH_HAS_SET_MEMORY select ARCH_STACKWALK + select ARCH_HAS_HWPF_CONTROL select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYNC_DMA_FOR_DEVICE @@ -1941,6 +1942,13 @@ config STACKPROTECTOR_PER_TASK def_bool y depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG =20 +config ARM64_HWPF_CONTROL + tristate "ARM64 Hardware Prefetch Control support" + depends on HWPF_CONTROL + default m + help + This adds Hardware Prefetch Control driver support for ARM64. + endmenu =20 menu "Boot options" diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 88b3e2a21408..d5eb1dc6bfa6 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_ARM64_PTR_AUTH) +=3D pointer_auth.o obj-$(CONFIG_ARM64_MTE) +=3D mte.o obj-y +=3D vdso-wrap.o obj-$(CONFIG_COMPAT_VDSO) +=3D vdso32-wrap.o +obj-$(CONFIG_ARM64_HWPF_CONTROL) +=3D pfctl.o =20 obj-y +=3D probes/ head-y :=3D head.o --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26A20C4332F for ; Tue, 25 Jan 2022 07:28:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1445407AbiAYH2P (ORCPT ); Tue, 25 Jan 2022 02:28:15 -0500 Received: from esa3.hc1455-7.c3s2.iphmx.com ([207.54.90.49]:10542 "EHLO esa3.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1444480AbiAYHV6 (ORCPT ); Tue, 25 Jan 2022 02:21:58 -0500 IronPort-SDR: VJQgLN9sZ5VBBcQtL2uqZJOmbSMxvubZ2tASwCu9tlBRFJXzrRLVqo4XJ1XdrpQ+awf7Yshdrw WDFvpPuRcc0kdd2KWw6urxveun2Sc71K4OYt9Q2fy1HPNCjlqxTqYdEH4/38C3PwasH5MQuAW0 LC85huxjN7AK7FUnyYXdHQwIaVxIQwBj/unf1l2H6Ta5j0lzFhZ40yX4DygdFe7B6hq2BAtAm1 3hNxG3s37HjbpF159Pja3JnBI+8pr6r+booVbjrokLZQQ+5F2qLagDkOuw+gswDufAwiD5mxJE i9Nu2y0rQPtsyBmoLGQ6VzBq X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60495849" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60495849" Received: from unknown (HELO oym-r1.gw.nic.fujitsu.com) ([210.162.30.89]) by esa3.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:37 +0900 Received: from oym-m3.gw.nic.fujitsu.com (oym-nat-oym-m3.gw.nic.fujitsu.com [192.168.87.60]) by oym-r1.gw.nic.fujitsu.com (Postfix) with ESMTP id E15E8E8FF8 for ; Tue, 25 Jan 2022 16:14:35 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by oym-m3.gw.nic.fujitsu.com (Postfix) with ESMTP id 1B36BD95EE for ; Tue, 25 Jan 2022 16:14:35 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id C5D25400C1BBD; Tue, 25 Jan 2022 16:14:34 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 5/8] arm64: Create cache sysfs directory without ACPI PPTT for hardware prefetch control Date: Tue, 25 Jan 2022 16:14:11 +0900 Message-Id: <20220125071414.811344-6-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch will create a cache sysfs directory without ACPI PPTT if the CONFIG_HWPF_CONTROL is true. Hardware prefetch control driver need cache sysfs directory and cache level/type information. In ARM processor, these information can be obtained from the register even without PPTT. Therefore, we set the cpu_map_populated to true to create cache sysfs directory if the machine doesn't have PPTT. Signed-off-by: Kohei Tarumizu --- arch/arm64/kernel/cacheinfo.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c index 587543c6c51c..039ec32d0b3d 100644 --- a/arch/arm64/kernel/cacheinfo.c +++ b/arch/arm64/kernel/cacheinfo.c @@ -43,6 +43,21 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, this_leaf->type =3D type; } =20 +#if defined(CONFIG_HWPF_CONTROL) +static bool acpi_has_pptt(void) +{ + struct acpi_table_header *table; + acpi_status status; + + status =3D acpi_get_table(ACPI_SIG_PPTT, 0, &table); + if (ACPI_FAILURE(status)) + return false; + + acpi_put_table(table); + return true; +} +#endif + int init_cache_level(unsigned int cpu) { unsigned int ctype, level, leaves, fw_level; @@ -95,5 +110,19 @@ int populate_cache_leaves(unsigned int cpu) ci_leaf_init(this_leaf++, type, level); } } + +#if defined(CONFIG_HWPF_CONTROL) + /* + * Hardware prefetch functions need cache sysfs directory and cache + * level/type information. In ARM processor, these information can be + * obtained from registers even without PPTT. Therefore, we set the + * cpu_map_populated to true to create cache sysfs directory, if the + * machine doesn't have PPTT. + **/ + if (!acpi_disabled) + if (!acpi_has_pptt()) + this_cpu_ci->cpu_map_populated =3D true; +#endif + return 0; } --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75BA6C433FE for ; Tue, 25 Jan 2022 07:28:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1445444AbiAYH2b (ORCPT ); Tue, 25 Jan 2022 02:28:31 -0500 Received: from esa1.hc1455-7.c3s2.iphmx.com ([207.54.90.47]:58197 "EHLO esa1.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1444472AbiAYHV6 (ORCPT ); Tue, 25 Jan 2022 02:21:58 -0500 IronPort-SDR: 2wYmYFIqB50Kl3K75d8Gh1y3pMpLSA0zBgkLFr1raQFCxz+TQHJIvgeHy8YjFR/hTLJL9XSnid xYSl6u35I41u1lQPIqoE0gYbWzZep13VJFEtUoM3odqKcP4B/0U37XVRMwbw9gCMvpTTVkn9xu kjPxPioW0fG053UCXHByvt5nksGPMo4wvKlUhk665B21oZTDUQ40gmgodh7ETtrRAuT9+sM37n WnRKku2oBkZa94rWBsJcW0psHzUHe77abmikcAhAORV6oTj0Ishjz4EFI4jD/EvKf/IY1OU1ek SdzxKDlL2f4KYcOvxd3tW3B6 X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60525509" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60525509" Received: from unknown (HELO yto-r4.gw.nic.fujitsu.com) ([218.44.52.220]) by esa1.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:39 +0900 Received: from yto-m1.gw.nic.fujitsu.com (yto-nat-yto-m1.gw.nic.fujitsu.com [192.168.83.64]) by yto-r4.gw.nic.fujitsu.com (Postfix) with ESMTP id 230CACD6C1 for ; Tue, 25 Jan 2022 16:14:38 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by yto-m1.gw.nic.fujitsu.com (Postfix) with ESMTP id 6B118D0424 for ; Tue, 25 Jan 2022 16:14:37 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id 2BE74400C1BBC; Tue, 25 Jan 2022 16:14:37 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 6/8] x86: Add hardware prefetch control support for x86 Date: Tue, 25 Jan 2022 16:14:12 +0900 Message-Id: <20220125071414.811344-7-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds module init/exit code, and creates sysfs attribute file "prefetch_control" for x86. This driver works only if the model is INTEL_FAM6_BROADWELL_X at this point. If you would like to support a new model with the same register specifications as INTEL_FAM6_BROADWELL_X, it is possible to add the model settings to array of broadwell_cpu_ids[]. The details of the registers to be read and written in this patch are described below: "https://www.intel.com/content/www/us/en/developer/articles/technical/intel= -sdm.html" Volume 4 Signed-off-by: Kohei Tarumizu --- arch/x86/kernel/cpu/pfctl.c | 292 ++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 arch/x86/kernel/cpu/pfctl.c diff --git a/arch/x86/kernel/cpu/pfctl.c b/arch/x86/kernel/cpu/pfctl.c new file mode 100644 index 000000000000..02628f6d2c05 --- /dev/null +++ b/arch/x86/kernel/cpu/pfctl.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2022 FUJITSU LIMITED + * + * x86 Hardware Prefetch Control support + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct pfctl_driver x86_pfctl_driver; + +/************************************** + * Intle BROADWELL support + **************************************/ + +/* + * The register specification for each bits of Intel BROADWELL is as + * follow: + * + * [0] L2 Hardware Prefetcher Disable (R/W) + * [1] L2 Adjacent Cache Line Prefetcher Disable (R/W) + * [2] DCU Hardware Prefetcher Disable (R/W) + * [3] DCU IP Prefetcher Disable (R/W) + * [63:4] Reserved + * + * See "Intel 64 and IA-32 Architectures Software Developer's Manual" + * (https://www.intel.com/content/www/us/en/developer/articles/technical/i= ntel-sdm.html) + * for register specification details. + */ +#define BROADWELL_L2_HWPF_FIELD BIT_ULL(0) +#define BROADWELL_L2_ACLPF_FIELD BIT_ULL(1) +#define BROADWELL_DCU_HWPF_FIELD BIT_ULL(2) +#define BROADWELL_DCU_IPPF_FIELD BIT_ULL(3) + +static int broadwell_get_hwpf_enable(u64 reg, unsigned int level) +{ + switch (level) { + case 1: + return FIELD_GET(BROADWELL_DCU_HWPF_FIELD, reg); + case 2: + return FIELD_GET(BROADWELL_L2_HWPF_FIELD, reg); + default: + return -EINVAL; + } +} + +static int broadwell_modify_hwpf_enable(u64 *reg, unsigned int level, + unsigned int val) +{ + switch (level) { + case 1: + *reg &=3D ~BROADWELL_DCU_HWPF_FIELD; + *reg |=3D FIELD_PREP(BROADWELL_DCU_HWPF_FIELD, val); + break; + case 2: + *reg &=3D ~BROADWELL_L2_HWPF_FIELD; + *reg |=3D FIELD_PREP(BROADWELL_L2_HWPF_FIELD, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int broadwell_get_ippf_enable(u64 reg, unsigned int level) +{ + switch (level) { + case 1: + return FIELD_GET(BROADWELL_DCU_IPPF_FIELD, reg); + default: + return -EINVAL; + } +} + +static int broadwell_modify_ippf_enable(u64 *reg, unsigned int level, + unsigned int val) +{ + switch (level) { + case 1: + *reg &=3D ~BROADWELL_DCU_IPPF_FIELD; + *reg |=3D FIELD_PREP(BROADWELL_DCU_IPPF_FIELD, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int broadwell_get_aclpf_enable(u64 reg, unsigned int level) +{ + switch (level) { + case 2: + return FIELD_GET(BROADWELL_L2_ACLPF_FIELD, reg); + default: + return -EINVAL; + } +} + +static int broadwell_modify_aclpf_enable(u64 *reg, unsigned int level, + unsigned int val) +{ + switch (level) { + case 2: + *reg &=3D ~BROADWELL_L2_ACLPF_FIELD; + *reg |=3D FIELD_PREP(BROADWELL_L2_ACLPF_FIELD, val); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int _broadwell_get_pfctl_params(struct prefetcher_options *opts, u6= 4 reg, + unsigned int level, int supported_prefetcher) +{ + int ret; + + if (supported_prefetcher & HWPF) { + ret =3D broadwell_get_hwpf_enable(reg, level); + if (ret < 0) + return ret; + opts->hwpf_enable =3D ret; + } + + if (supported_prefetcher & IPPF) { + ret =3D broadwell_get_ippf_enable(reg, level); + if (ret < 0) + return ret; + opts->ippf_enable =3D ret; + } + + if (supported_prefetcher & ACLPF) { + ret =3D broadwell_get_aclpf_enable(reg, level); + if (ret < 0) + return ret; + opts->aclpf_enable =3D ret; + } + + return 0; +} + +static int broadwell_get_pfctl_params(struct prefetcher_options *opts, u64= reg, + unsigned int level) +{ + int ret, supported_prefetcher; + + if (level =3D=3D 1) + supported_prefetcher =3D + x86_pfctl_driver.supported_l1d_prefetcher; + else if (level =3D=3D 2) + supported_prefetcher =3D + x86_pfctl_driver.supported_l2_prefetcher; + else + return -EINVAL; + + ret =3D _broadwell_get_pfctl_params(opts, reg, level, supported_prefetche= r); + if (ret < 0) + return ret; + + return 0; +} + +static int broadwell_modify_pfreg(u64 *reg, struct prefetcher_options *opt= s, + unsigned int level) +{ + int ret; + + if (opts->hwpf_enable !=3D PFCTL_PARAM_UNSET) { + ret =3D broadwell_modify_hwpf_enable(reg, level, + opts->hwpf_enable); + if (ret < 0) + return ret; + } + + if (opts->ippf_enable !=3D PFCTL_PARAM_UNSET) { + ret =3D broadwell_modify_ippf_enable(reg, level, + opts->ippf_enable); + if (ret < 0) + return ret; + } + + if (opts->aclpf_enable !=3D PFCTL_PARAM_UNSET) { + ret =3D broadwell_modify_aclpf_enable(reg, level, + opts->aclpf_enable); + if (ret < 0) + return ret; + } + + return 0; +} + +static int broadwell_read_pfreg(unsigned int cpu, unsigned int level, + struct prefetcher_options *opts) +{ + int ret; + u64 reg; + + ret =3D rdmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, ®); + if (ret) + return ret; + + ret =3D broadwell_get_pfctl_params(opts, reg, level); + if (ret) + return ret; + + return 0; +} + +static int broadwell_write_pfreg(unsigned int cpu, unsigned int level, + struct prefetcher_options *opts) +{ + int ret; + u64 reg; + + ret =3D rdmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, ®); + if (ret) + return ret; + + ret =3D broadwell_modify_pfreg(®, opts, level); + if (ret < 0) + return ret; + + ret =3D wrmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, reg); + if (ret) + return ret; + + return 0; +} + +/* + * In addition to BROADWELL_X, NEHALEM and others have same register + * specifications as those represented by BROADWELL_XXX_FIELD. + * If you want to add support for these processor, add the new target model + * here. + */ +static const struct x86_cpu_id broadwell_cpu_ids[] =3D { + X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, NULL), + {} +}; + +/***** end of Intel BROADWELL support *****/ + +static int __init setup_pfctl_driver_params(void) +{ + if (x86_match_cpu(broadwell_cpu_ids)) { + x86_pfctl_driver.supported_l1d_prefetcher =3D HWPF|IPPF; + x86_pfctl_driver.supported_l2_prefetcher =3D HWPF|ACLPF; + x86_pfctl_driver.read_pfreg =3D broadwell_read_pfreg; + x86_pfctl_driver.write_pfreg =3D broadwell_write_pfreg; + } else { + return -ENODEV; + } + + return 0; +} + +static int __init x86_pfctl_init(void) +{ + int ret; + + ret =3D setup_pfctl_driver_params(); + if (ret < 0) + return ret; + + ret =3D pfctl_register_driver(&x86_pfctl_driver); + if (ret < 0) + return ret; + + return 0; +} + +static void __exit x86_pfctl_exit(void) +{ + pfctl_unregister_driver(&x86_pfctl_driver); +} + +late_initcall(x86_pfctl_init); +module_exit(x86_pfctl_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("FUJITSU LIMITED"); +MODULE_DESCRIPTION("x86 Hardware Prefetch Control Driver"); --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED83EC433F5 for ; Tue, 25 Jan 2022 07:27:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1445182AbiAYH1J (ORCPT ); Tue, 25 Jan 2022 02:27:09 -0500 Received: from esa5.hc1455-7.c3s2.iphmx.com ([68.232.139.130]:34712 "EHLO esa5.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443736AbiAYHWB (ORCPT ); Tue, 25 Jan 2022 02:22:01 -0500 IronPort-SDR: JYoD63yj9LFTzLLIlQ/KoD8A4atNtC1uDHFNlLdGitAgX/N+j2ojoKUwZS5+DzY90W7DhCL23j GSKaJDnJriZXGdhHz5nkvSuVcAvRBgx3XXNMUI6YQbY3L/lvsEAPn42OSVsWDn8583uHoyeXlz AYSp5Mju3dBtbKWqGGke35uLL/L3aMcMVrsrEkK9YfubEuK66MdMQTF0ju2oxjunCUn63InTvL ShIfJwga6ofpBh8gJThEiE93sXnzDsZh6V460kkGm2XmUMV6l9GNph1zZOASfOF8CX69uX/mpZ 626QMF+Yixx4ACZkjISP3iIf X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="60079469" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="60079469" Received: from unknown (HELO oym-r4.gw.nic.fujitsu.com) ([210.162.30.92]) by esa5.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:41 +0900 Received: from oym-m1.gw.nic.fujitsu.com (oym-nat-oym-m1.gw.nic.fujitsu.com [192.168.87.58]) by oym-r4.gw.nic.fujitsu.com (Postfix) with ESMTP id 35D47E07E1 for ; Tue, 25 Jan 2022 16:14:40 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by oym-m1.gw.nic.fujitsu.com (Postfix) with ESMTP id 7007DD994E for ; Tue, 25 Jan 2022 16:14:39 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id 266E8400C1BBE; Tue, 25 Jan 2022 16:14:39 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 7/8] x86: Add Kconfig/Makefile to build hardware prefetch control driver Date: Tue, 25 Jan 2022 16:14:13 +0900 Message-Id: <20220125071414.811344-8-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds Kconfig/Makefile to build hardware prefetch control driver for x86 support. This also adds a MAINTAINERS entry. Signed-off-by: Kohei Tarumizu --- MAINTAINERS | 1 + arch/x86/Kconfig | 7 +++++++ arch/x86/kernel/cpu/Makefile | 2 ++ 3 files changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0eaee76438e9..ea049bddc4e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8448,6 +8448,7 @@ HARDWARE PREFETCH CONTROL DRIVERS M: Kohei Tarumizu S: Maintained F: arch/arm64/kernel/pfctl.c +F: arch/x86/kernel/pfctl.c F: drivers/base/pfctl.c F: include/linux/pfctl.h =20 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ebe8fc76949a..069aee252ba3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -26,6 +26,7 @@ config X86_64 depends on 64BIT # Options that are inherently 64-bit kernel only: select ARCH_HAS_GIGANTIC_PAGE + select ARCH_HAS_HWPF_CONTROL select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 select ARCH_USE_CMPXCHG_LOCKREF select HAVE_ARCH_SOFT_DIRTY @@ -1377,6 +1378,12 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. =20 +config X86_HWPF_CONTROL + tristate "x86 Hardware Prefetch Control support" + depends on HWPF_CONTROL + help + This adds Hardware Prefetch Control driver support for X86. + choice prompt "High Memory Support" default HIGHMEM4G diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 9661e3e802be..aec62a6b37d2 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -56,6 +56,8 @@ obj-$(CONFIG_X86_LOCAL_APIC) +=3D perfctr-watchdog.o obj-$(CONFIG_HYPERVISOR_GUEST) +=3D vmware.o hypervisor.o mshyperv.o obj-$(CONFIG_ACRN_GUEST) +=3D acrn.o =20 +obj-$(CONFIG_X86_HWPF_CONTROL) +=3D pfctl.o + ifdef CONFIG_X86_FEATURE_NAMES quiet_cmd_mkcapflags =3D MKCAP $@ cmd_mkcapflags =3D $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $= @ $^ --=20 2.27.0 From nobody Tue Jun 30 04:38:22 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 277FFC433EF for ; Tue, 25 Jan 2022 07:27:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443078AbiAYH0o (ORCPT ); Tue, 25 Jan 2022 02:26:44 -0500 Received: from esa11.hc1455-7.c3s2.iphmx.com ([207.54.90.137]:19240 "EHLO esa11.hc1455-7.c3s2.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443751AbiAYHWB (ORCPT ); Tue, 25 Jan 2022 02:22:01 -0500 IronPort-SDR: Mh03SH5ExviKiI/Fr6lksYIWcTGsdTkHkc1yUpzP3W6ION5HJcpbtVZ2cz2saxRuaVv8AggJVB hB7qriSt1dwzGS2SS6/hdrmDQn6mJzC1eJBlJtr4WJJzBvv9xRUG7Fv6yLJ1vey44h547he5If Kp9K5/7xfk9iq6SxLGmF/HU4wVwaZP6HQ5buq2tHqZ2hNBpYQZtY/cVyMVhg7E+REeyu01JdBd f11FzNrrHBeSe+qzW6dM0BpB8oMDLNVJClUp68bWr8S/8Qcdwb1KkzhIWHry3UtTdZ15e8M6pg F5tWtZGap0vzno3/IGHrlu5z X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="40059904" X-IronPort-AV: E=Sophos;i="5.88,314,1635174000"; d="scan'208";a="40059904" Received: from unknown (HELO yto-r4.gw.nic.fujitsu.com) ([218.44.52.220]) by esa11.hc1455-7.c3s2.iphmx.com with ESMTP; 25 Jan 2022 16:14:42 +0900 Received: from yto-m2.gw.nic.fujitsu.com (yto-nat-yto-m2.gw.nic.fujitsu.com [192.168.83.65]) by yto-r4.gw.nic.fujitsu.com (Postfix) with ESMTP id E711ECD6C1 for ; Tue, 25 Jan 2022 16:14:41 +0900 (JST) Received: from yto-om4.fujitsu.com (yto-om4.o.css.fujitsu.com [10.128.89.165]) by yto-m2.gw.nic.fujitsu.com (Postfix) with ESMTP id 274F2E6544 for ; Tue, 25 Jan 2022 16:14:41 +0900 (JST) Received: from localhost.localdomain (n3235113.np.ts.nmh.cs.fujitsu.co.jp [10.123.235.113]) by yto-om4.fujitsu.com (Postfix) with ESMTP id E2062400C1BBE; Tue, 25 Jan 2022 16:14:40 +0900 (JST) From: Kohei Tarumizu To: catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: tarumizu.kohei@fujitsu.com Subject: [PATCH 8/8] docs: ABI: Add sysfs documentation interface of hardware prefetch control driver Date: Tue, 25 Jan 2022 16:14:14 +0900 Message-Id: <20220125071414.811344-9-tarumizu.kohei@fujitsu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This describes the sysfs interface implemented on the hardware prefetch control driver. Signed-off-by: Kohei Tarumizu --- .../ABI/testing/sysfs-devices-system-cpu | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documenta= tion/ABI/testing/sysfs-devices-system-cpu index 61f5676a7429..66b4023b2ed1 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -681,3 +681,96 @@ Description: (RO) the list of CPUs that are isolated and don't participate in load balancing. These CPUs are set by boot parameter "isolcpus=3D". + +What: /sys/devices/system/cpu/cpu*/cache/index[0,2]/prefetch_control +Date: January 2022 +Contact: Linux kernel mailing list +Description: Parameters for CPU's hardware prefetch control + + This sysfs interface provides Hardware Prefetch control + attribute file by using implementation defined registers. + This file exists in every CPU's cache/index[0,2] directory. + Each attribute file corresponds to the cache level of the + parent index directory. + + prefetch_control: (RW) This file allows user to control + several options described below. Which options are available + depends on the CPU. + + * hardware_prefetcher_enable: + The enablement status of prefetcher, "enable" or "disable". + + * ip_prefetcher_enable: + The enablement status of prefetcher, "enable" or "disable". + + * adjacent_cache_line_prefetcher_enable: + The enablement status of prefetcher, "enable" or "disable". + + * stream_detect_prefetcher_enable: + The enablement status of prefetcher, "enable" or "disable". + + * stream_detect_prefetcher_strong: + The strongness status of prefetcher, "strong" or "weak". + + * stream_detect_prefetcher_dist: + The current prefetcher distance value in bytes or the "auto". + This value is a multiples of a specific value, depending on + the CPU. + + Write either a value in byte or the string "auto" to this + parameter. If you write a value less than multiples of a + specific value, it is rounded up. + + - Supported processors + + This sysfs interface is available on several processors, x86 + and ARM64. Currently, the following processors are supported: + + - x86 processor + - INTEL_FAM6_BROADWELL_X + + - ARM64 processor + - FUJITSU_CPU_PART_A64FX + + - Attribute mapping + + Some Intel processors have MSR 0x1a4. This register has several + specifications depending on the model. This interface provides + a one-to-one option to control all the tunable parameters the + CPU provides of the following. + + - "* Hardware Prefetcher Disable (R/W)" + corresponds to the attribute "hardware_prefetcher_enable" + + - "* Adjacent Cache Line Prefetcher Disable (R/W)" + corresponds to the attribute "adjacent_cache_line_prefetcher_enable" + + - "* IP Prefetcher Disable (R/W)" + corresponds to the attribute "ip_prefetcher_enable" + + The processor A64FX has register IMP_PF_STREAM_DETECT_CTRL_EL0 + for Hardware Prefetch Control. This attribute maps each + specification to the following. + + - "L*PF_DIS": enablement of hardware prefetcher + corresponds to the attribute "stream_detect_prefetcher_enable" + + - "L*W": strongness of hardware prefetcher + corresponds to the attribute "stream_detect_prefetcher_strong" + + - "L*_DIST": distance of hardware prefetcher + corresponds to the attribute "stream_detect_prefetcher_dist" + + - Example:: + + # cat /sys/devices/system/cpu/cpu0/cache/index0/prefetch_control + + > hardware_prefetcher_enable=3Denable + > ip_prefetcher_enable=3Denable + + # echo "hardware_prefetcher_enable=3Ddisable" > /sys/devices/system/= cpu/cpu0/cache/index0/prefetch_control + + # cat /sys/devices/system/cpu/cpu0/cache/index2/prefetch_control + + > hardware_prefetcher_enable=3Ddisable + > ip_prefetcher_enable=3Denable --=20 2.27.0