lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ