Skip to content

Commit b98fa87

Browse files
spandruvadaij-intel
authored andcommitted
platform/x86/intel-uncore-freq: Add attributes to show agent types
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ilpo Järvinen <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent 751bcc0 commit b98fa87

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ static ssize_t show_package_id(struct kobject *kobj, struct kobj_attribute *attr
4343
return sprintf(buf, "%u\n", data->package_id);
4444
}
4545

46+
#define MAX_UNCORE_AGENT_TYPES 4
47+
48+
/* The order follows AGENT_TYPE_* defines */
49+
static const char *agent_name[MAX_UNCORE_AGENT_TYPES] = {"core", "cache", "memory", "io"};
50+
51+
static ssize_t show_agent_types(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
52+
{
53+
struct uncore_data *data = container_of(attr, struct uncore_data, agent_types_kobj_attr);
54+
unsigned long agent_mask = data->agent_type_mask;
55+
int agent, length = 0;
56+
57+
for_each_set_bit(agent, &agent_mask, MAX_UNCORE_AGENT_TYPES) {
58+
if (length)
59+
length += sysfs_emit_at(buf, length, " ");
60+
61+
length += sysfs_emit_at(buf, length, agent_name[agent]);
62+
}
63+
64+
length += sysfs_emit_at(buf, length, "\n");
65+
66+
return length;
67+
}
68+
4669
static ssize_t show_attr(struct uncore_data *data, char *buf, enum uncore_index index)
4770
{
4871
unsigned int value;
@@ -179,6 +202,10 @@ static int create_attr_group(struct uncore_data *data, char *name)
179202
data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr;
180203
init_attribute_root_ro(package_id);
181204
data->uncore_attrs[index++] = &data->package_id_kobj_attr.attr;
205+
if (data->agent_type_mask) {
206+
init_attribute_ro(agent_types);
207+
data->uncore_attrs[index++] = &data->agent_types_kobj_attr.attr;
208+
}
182209
}
183210

184211
data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr;

drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111

1212
#include <linux/device.h>
1313

14+
/*
15+
* Define uncore agents, which are under uncore frequency control.
16+
* Defined in the same order as specified in the TPMI UFS Specifications.
17+
* It is possible that there are common uncore frequency control to more than
18+
* one hardware agents. So, these defines are used as a bit mask.
19+
*/
20+
21+
#define AGENT_TYPE_CORE 0x01
22+
#define AGENT_TYPE_CACHE 0x02
23+
#define AGENT_TYPE_MEMORY 0x04
24+
#define AGENT_TYPE_IO 0x08
25+
1426
/**
1527
* struct uncore_data - Encapsulate all uncore data
1628
* @stored_uncore_data: Last user changed MSR 620 value, which will be restored
@@ -25,6 +37,7 @@
2537
* @cluster_id: cluster id in a domain
2638
* @instance_id: Unique instance id to append to directory name
2739
* @name: Sysfs entry name for this instance
40+
* @agent_type_mask: Bit mask of all hardware agents for this domain
2841
* @uncore_attr_group: Attribute group storage
2942
* @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz
3043
* @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz
@@ -41,6 +54,7 @@
4154
* @elc_high_threshold_enable_kobj_attr:
4255
Storage for kobject attribute elc_high_threshold_enable
4356
* @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute elc_floor_freq_khz
57+
* @agent_types_kobj_attr: Storage for kobject attribute agent_type
4458
* @uncore_attrs: Attribute storage for group creation
4559
*
4660
* This structure is used to encapsulate all data related to uncore sysfs
@@ -58,6 +72,7 @@ struct uncore_data {
5872
int cluster_id;
5973
int instance_id;
6074
char name[32];
75+
u16 agent_type_mask;
6176

6277
struct attribute_group uncore_attr_group;
6378
struct kobj_attribute max_freq_khz_kobj_attr;
@@ -72,7 +87,8 @@ struct uncore_data {
7287
struct kobj_attribute elc_high_threshold_percent_kobj_attr;
7388
struct kobj_attribute elc_high_threshold_enable_kobj_attr;
7489
struct kobj_attribute elc_floor_freq_khz_kobj_attr;
75-
struct attribute *uncore_attrs[13];
90+
struct kobj_attribute agent_types_kobj_attr;
91+
struct attribute *uncore_attrs[14];
7692
};
7793

7894
#define UNCORE_DOMAIN_ID_INVALID -1

drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,25 @@ static int uncore_read_freq(struct uncore_data *data, unsigned int *freq)
347347
return 0;
348348
}
349349

350+
/*
351+
* Agent types as per the TPMI UFS Specification for UFS_STATUS
352+
* Agent Type - Core Bit: 23
353+
* Agent Type - Cache Bit: 24
354+
* Agent Type - Memory Bit: 25
355+
* Agent Type - IO Bit: 26
356+
*/
357+
358+
#define UNCORE_AGENT_TYPES GENMASK_ULL(26, 23)
359+
360+
/* Helper function to read agent type over MMIO and set the agent type mask */
361+
static void uncore_set_agent_type(struct tpmi_uncore_cluster_info *cluster_info)
362+
{
363+
u64 status;
364+
365+
status = readq((u8 __iomem *)cluster_info->cluster_base + UNCORE_STATUS_INDEX);
366+
cluster_info->uncore_data.agent_type_mask = FIELD_GET(UNCORE_AGENT_TYPES, status);
367+
}
368+
350369
/* Callback for sysfs read for TPMI uncore values. Called under mutex locks. */
351370
static int uncore_read(struct uncore_data *data, unsigned int *value, enum uncore_index index)
352371
{
@@ -552,6 +571,8 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_
552571

553572
cluster_info->cluster_base = pd_info->uncore_base + mask;
554573

574+
uncore_set_agent_type(cluster_info);
575+
555576
cluster_info->uncore_data.package_id = pkg;
556577
/* There are no dies like Cascade Lake */
557578
cluster_info->uncore_data.die_id = 0;

0 commit comments

Comments
 (0)