[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <d80e1c91-64c4-8942-921a-91c78b6cbf05@linux.intel.com>
Date: Wed, 7 May 2025 16:02:22 +0300 (EEST)
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Srinivas Pandruvada <srinivas.pandruvada@...ux.intel.com>
cc: Hans de Goede <hdegoede@...hat.com>, platform-driver-x86@...r.kernel.org,
LKML <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v2 1/5] platform/x86/intel-uncore-freq: Add attributes
to show agent types
On Mon, 28 Apr 2025, Srinivas Pandruvada wrote:
> Currently, users need detailed hardware information to understand the
> scope of controls within each uncore domain. Uncore frequency controls
> manage subsystems such as core, cache, memory, and I/O. The UFS TPMI
> provides this information, which can be used to present the scope more
> clearly.
>
> Each uncore domain consists of one or more agent types, with each agent
> type controlling one or more uncore hardware subsystems. For example, a
> single agent might control both the core and cache.
>
> Introduce a new attribute called "agent_types." This attribute displays
> a list of agents, separated by space character.
>
> The string representations for agent types are as follows:
> For core agent: core
> For cache agent: cache
> For memory agent: memory
> For I/O agent: io
>
> These agent types are read during probe time for each cluster and stored
> as part of the struct uncore_data.
>
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@...ux.intel.com>
> ---
> v2:
> No change
>
> .../uncore-frequency-common.c | 24 ++++++++++++++++
> .../uncore-frequency-common.h | 17 ++++++++++-
> .../uncore-frequency/uncore-frequency-tpmi.c | 28 +++++++++++++++++++
> 3 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
> index 4e2c6a2d7e6e..cfa3039a0e39 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
> @@ -43,6 +43,28 @@ static ssize_t show_package_id(struct kobject *kobj, struct kobj_attribute *attr
> return sprintf(buf, "%u\n", data->package_id);
> }
>
> +static ssize_t show_agent_types(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> + struct uncore_data *data = container_of(attr, struct uncore_data, agent_types_kobj_attr);
> + int length = 0;
> +
> + if (data->agent_type_mask & AGENT_TYPE_CORE)
> + length += sysfs_emit_at(buf, length, "core ");
> +
> + if (data->agent_type_mask & AGENT_TYPE_CACHE)
> + length += sysfs_emit_at(buf, length, "cache ");
> +
> + if (data->agent_type_mask & AGENT_TYPE_MEMORY)
> + length += sysfs_emit_at(buf, length, "memory ");
> +
> + if (data->agent_type_mask & AGENT_TYPE_IO)
> + length += sysfs_emit_at(buf, length, "io ");
Is this set going to get expanded soon? It would feel more future proof to
do this mapping using a loop and array. You also chose the quick and dirty
approach wrt. trailing spaces as getting rid of the extra space is a bit
tedious when open coding the mapping like that ;-).
--
i.
> +
> + length += sysfs_emit_at(buf, length, "\n");
> +
> + return length;
> +}
> +
> static ssize_t show_attr(struct uncore_data *data, char *buf, enum uncore_index index)
> {
> unsigned int value;
> @@ -179,6 +201,8 @@ static int create_attr_group(struct uncore_data *data, char *name)
> data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr;
> init_attribute_root_ro(package_id);
> data->uncore_attrs[index++] = &data->package_id_kobj_attr.attr;
> + init_attribute_ro(agent_types);
> + data->uncore_attrs[index++] = &data->agent_types_kobj_attr.attr;
> }
>
> data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr;
> diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
> index 26c854cd5d97..197ca2ad327f 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
> @@ -11,6 +11,17 @@
>
> #include <linux/device.h>
>
> +/*
> + * Define uncore agents, which are under uncore frequency control.
> + * It is possible that there are common uncore frequency control to more than
> + * one agents. So these defines are used as a bit mask.
> + */
> +#define AGENT_TYPE_NONE 0
> +#define AGENT_TYPE_CORE 0x01
> +#define AGENT_TYPE_CACHE 0x02
> +#define AGENT_TYPE_MEMORY 0x04
> +#define AGENT_TYPE_IO 0x08
> +
> /**
> * struct uncore_data - Encapsulate all uncore data
> * @stored_uncore_data: Last user changed MSR 620 value, which will be restored
> @@ -25,6 +36,7 @@
> * @cluster_id: cluster id in a domain
> * @instance_id: Unique instance id to append to directory name
> * @name: Sysfs entry name for this instance
> + * @agent_type_mask: Bit mask of all hardware agents for this domain
> * @uncore_attr_group: Attribute group storage
> * @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz
> * @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz
> @@ -41,6 +53,7 @@
> * @elc_high_threshold_enable_kobj_attr:
> Storage for kobject attribute elc_high_threshold_enable
> * @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute elc_floor_freq_khz
> + * @agent_types_kobj_attr: Storage for kobject attribute agent_type
> * @uncore_attrs: Attribute storage for group creation
> *
> * This structure is used to encapsulate all data related to uncore sysfs
> @@ -58,6 +71,7 @@ struct uncore_data {
> int cluster_id;
> int instance_id;
> char name[32];
> + u16 agent_type_mask;
>
> struct attribute_group uncore_attr_group;
> struct kobj_attribute max_freq_khz_kobj_attr;
> @@ -72,7 +86,8 @@ struct uncore_data {
> struct kobj_attribute elc_high_threshold_percent_kobj_attr;
> struct kobj_attribute elc_high_threshold_enable_kobj_attr;
> struct kobj_attribute elc_floor_freq_khz_kobj_attr;
> - struct attribute *uncore_attrs[13];
> + struct kobj_attribute agent_types_kobj_attr;
> + struct attribute *uncore_attrs[14];
> };
>
> #define UNCORE_DOMAIN_ID_INVALID -1
> diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
> index 4aa6c227ec82..70415d80773c 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
> @@ -74,6 +74,12 @@ struct tpmi_uncore_struct {
> /* Bit definitions for STATUS register */
> #define UNCORE_CURRENT_RATIO_MASK GENMASK_ULL(6, 0)
>
> +/* Uncore agent type bits */
> +#define UNCORE_CORE_PRESENT BIT(23)
> +#define UNCORE_CACHE_PRESENT BIT(24)
> +#define UNCORE_MEMORY_PRESENT BIT(25)
> +#define UNCORE_IO_PRESENT BIT(26)
> +
> /* Bit definitions for CONTROL register */
> #define UNCORE_MAX_RATIO_MASK GENMASK_ULL(14, 8)
> #define UNCORE_MIN_RATIO_MASK GENMASK_ULL(21, 15)
> @@ -347,6 +353,26 @@ static int uncore_read_freq(struct uncore_data *data, unsigned int *freq)
> return 0;
> }
>
> +/* Helper function to read agent type over MMIO and set the agent type */
> +static void uncore_set_agent_type(struct tpmi_uncore_cluster_info *cluster_info)
> +{
> + u64 status;
> +
> + status = readq((u8 __iomem *)cluster_info->cluster_base + UNCORE_STATUS_INDEX);
> +
> + if (status & UNCORE_CORE_PRESENT)
> + cluster_info->uncore_data.agent_type_mask |= AGENT_TYPE_CORE;
> +
> + if (status & UNCORE_CACHE_PRESENT)
> + cluster_info->uncore_data.agent_type_mask |= AGENT_TYPE_CACHE;
> +
> + if (status & UNCORE_MEMORY_PRESENT)
> + cluster_info->uncore_data.agent_type_mask |= AGENT_TYPE_MEMORY;
> +
> + if (status & UNCORE_IO_PRESENT)
> + cluster_info->uncore_data.agent_type_mask |= AGENT_TYPE_IO;
> +}
> +
> /* Callback for sysfs read for TPMI uncore values. Called under mutex locks. */
> static int uncore_read(struct uncore_data *data, unsigned int *value, enum uncore_index index)
> {
> @@ -552,6 +578,8 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_
>
> cluster_info->cluster_base = pd_info->uncore_base + mask;
>
> + uncore_set_agent_type(cluster_info);
> +
> cluster_info->uncore_data.package_id = pkg;
> /* There are no dies like Cascade Lake */
> cluster_info->uncore_data.die_id = 0;
>
Powered by blists - more mailing lists