Re: [PATCH v2 2/2] platform/x86/intel-uncore-freq: Expose instance ID in the sysfs
From: srinivas pandruvada
Date: Tue Apr 07 2026 - 14:06:31 EST
On Thu, 2026-04-02 at 19:59 +0000, Maciej Wieczor-Retman wrote:
> From: Maciej Wieczor-Retman <maciej.wieczor-retman@xxxxxxxxx>
>
> Insufficient data is exported to allow direct access to TPMI
> registers
> through MMIO. On non-partitioned systems domain_id can be used both
> for
> mapping CPUs to their compute die IDs and for mapping die indices to
> their MMIO memory blocks mapped
> into userspace.
not mapped. But presented to user space via TPMI debugfs.
> However on partitioned
> systems it can't be used for mapping MMIO blocks anymore.
Again not mapping.
> This is due to
> how TPMI partitioning influences domain_id calculation. The previous
> association is lost on partitioned systems in order to keep using
> domain_id for mapping CPUs to compute dies.
>
> Expose the instance ID in sysfs that's unique in the scope of one
> TPMI
> partition (and hence one TPMI device). It's a physical index into
> mapped
> MMIO blocks and can be used by userspace to figure out how to
> directly
> access TPMI registers.
>
> Signed-off-by: Maciej Wieczor-Retman
> <maciej.wieczor-retman@xxxxxxxxx>
> ---
> Changelog v2:
> - Redo the patch message.
> - Redo the function comment that assigns instance_id.
> - Modify the documentation.
>
> .../pm/intel_uncore_frequency_scaling.rst | 7 +++++++
> .../uncore-frequency/uncore-frequency-common.c | 10 ++++++++++
> .../uncore-frequency/uncore-frequency-common.h | 6 +++++-
> .../uncore-frequency/uncore-frequency-tpmi.c | 15
> ++++++++++++++-
> 4 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/admin-
> guide/pm/intel_uncore_frequency_scaling.rst b/Documentation/admin-
> guide/pm/intel_uncore_frequency_scaling.rst
> index d367ba4d744a..b43ad4d5e333 100644
> --- a/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst
> +++ b/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst
> @@ -88,8 +88,15 @@ and "fabric_cluster_id" in the directory.
>
> Attributes in each directory:
>
> +``instance_id``
> + This attribute is used to get die indices in userspace
> mapped MMIO
> + blocks. Indices are local to a single TPMI partition. Needed
> for direct
> + TPMI register access.
> +
> ``domain_id``
> This attribute is used to get the power domain id of this
> instance.
> + Indices are unique in all TPMI partitions on a given CPU
> package. Can be
> + used to map compute dies to corresponding CPUs.
>
> ``die_id``
> This attribute is used to get the Linux die id of this
> instance.
> 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 25ab511ed8d2..7141544ee94b 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> common.c
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> common.c
> @@ -29,6 +29,13 @@ static ssize_t show_domain_id(struct kobject
> *kobj, struct kobj_attribute *attr,
> return sysfs_emit(buf, "%u\n", data->domain_id);
> }
>
> +static ssize_t show_instance_id(struct kobject *kobj, struct
> kobj_attribute *attr, char *buf)
> +{
> + struct uncore_data *data = container_of(attr, struct
> uncore_data, instance_id_kobj_attr);
> +
> + return sprintf(buf, "%u\n", data->instance_id);
> +}
> +
> static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct
> kobj_attribute *attr, char *buf)
> {
> struct uncore_data *data = container_of(attr, struct
> uncore_data, fabric_cluster_id_kobj_attr);
> @@ -200,6 +207,9 @@ static int create_attr_group(struct uncore_data
> *data, char *name)
> if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) {
> init_attribute_root_ro(domain_id);
> data->uncore_attrs[index++] = &data-
> >domain_id_kobj_attr.attr;
> + init_attribute_root_ro(instance_id);
> + data->uncore_attrs[index++] = &data-
> >instance_id_kobj_attr.attr;
> +
> init_attribute_root_ro(fabric_cluster_id);
> data->uncore_attrs[index++] = &data-
> >fabric_cluster_id_kobj_attr.attr;
> init_attribute_root_ro(package_id);
> 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 0d5fd91ee0aa..e319448dc1a4 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> common.h
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> common.h
> @@ -36,6 +36,7 @@
> * @domain_id: Power domain id for this instance
> * @cluster_id: cluster id in a domain
> * @seqnum_id: Unique sequential id to append to directory
> name
> + * @instance_id: Die indices or feature instances for a
> single TPMI device
> * @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
> @@ -56,6 +57,7 @@
> * @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute
> elc_floor_freq_khz
> * @agent_types_kobj_attr: Storage for kobject attribute agent_type
> * @die_id_kobj_attr: Attribute storage for die_id information
> + * @instance_id_kobj_attr: Attribute storage for instance_id value
> * @uncore_attrs: Attribute storage for group creation
> *
> * This structure is used to encapsulate all data related to uncore
> sysfs
> @@ -72,6 +74,7 @@ struct uncore_data {
> int domain_id;
> int cluster_id;
> int seqnum_id;
> + int instance_id;
> char name[32];
> u16 agent_type_mask;
>
> @@ -90,7 +93,8 @@ struct uncore_data {
> struct kobj_attribute elc_floor_freq_khz_kobj_attr;
> struct kobj_attribute agent_types_kobj_attr;
> struct kobj_attribute die_id_kobj_attr;
> - struct attribute *uncore_attrs[15];
> + struct kobj_attribute instance_id_kobj_attr;
> + struct attribute *uncore_attrs[16];
> };
>
> #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 1237d9570886..1676a2049aad 100644
> --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> tpmi.c
> +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-
> tpmi.c
> @@ -385,7 +385,19 @@ static u8 io_die_index_next;
> /* Lock to protect io_die_start, io_die_index_next */
> static DEFINE_MUTEX(domain_lock);
>
> -static void set_domain_id(int id, int num_resources,
> +static void set_instance_id(int id, struct tpmi_uncore_cluster_info
> *cluster_info)
> +{
> + /*
> + * On non-partitioned systems domain_id can be used for
> mapping both
> + * CPUs to compute die IDs and physical die indexes to MMIO
> mapped
> + * memory. However on partitioned systems domain_id loses
> the second
> + * association. Therefore instance_id should be used for
> that instead,
> + * while domain_id should still be used to match CPUs to
> compute dies.
> + */
> + cluster_info->uncore_data.instance_id = id;
> +}
Do you need a function for single line assignment? Why not just assign
in the uncore_probe().
> +
> +static void set_domain_id(int id, int num_resources,
> struct oobmsm_plat_info *plat_info,
> struct tpmi_uncore_cluster_info
> *cluster_info)
> {
> @@ -686,6 +698,7 @@ static int uncore_probe(struct auxiliary_device
> *auxdev, const struct auxiliary_
> set_cdie_id(i, cluster_info, plat_info);
>
> set_domain_id(i, num_resources, plat_info,
> cluster_info);
> + set_instance_id(i, cluster_info);
>
> cluster_info->uncore_root = tpmi_uncore;
>