Re: [PATCH v3 2/2] platform/x86/intel-uncore-freq: Expose instance ID in the sysfs

srinivas pandruvada
2026-04-22T16:17:20Z

On Wed, 2026-04-08 at 16:27 +0000, Maciej Wieczor-Retman wrote:
> From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
>
> 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 presented to userspace via TPMI debugfs.
> However on partitioned systems the debugfs association doesn't work
> anymore. 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@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

> ---
> Changelog v3:
> - Change sprintf -> sysfs_emit in show_instance_id().
> - Change part of patch message 'MMIO memory blocks mapped' -> 'MMIO
>   memory blocks presented to userspace...'
> - Change assigning function to static inline.
>
> 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..3b554418a7a3 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 sysfs_emit(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..32d03bee09a0 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 inline 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;
> +}
> +
> +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;
>