LCOV - code coverage report
Current view: top level - drivers/base - topology.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 19 42.1 %
Date: 2023-07-19 18:55:55 Functions: 3 15 20.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * driver/base/topology.c - Populate sysfs with cpu topology information
       4             :  *
       5             :  * Written by: Zhang Yanmin, Intel Corporation
       6             :  *
       7             :  * Copyright (C) 2006, Intel Corp.
       8             :  *
       9             :  * All rights reserved.
      10             :  */
      11             : #include <linux/mm.h>
      12             : #include <linux/cpu.h>
      13             : #include <linux/module.h>
      14             : #include <linux/hardirq.h>
      15             : #include <linux/topology.h>
      16             : 
      17             : #define define_id_show_func(name, fmt)                                  \
      18             : static ssize_t name##_show(struct device *dev,                          \
      19             :                            struct device_attribute *attr, char *buf)    \
      20             : {                                                                       \
      21             :         return sysfs_emit(buf, fmt "\n", topology_##name(dev->id));        \
      22             : }
      23             : 
      24             : #define define_siblings_read_func(name, mask)                                   \
      25             : static ssize_t name##_read(struct file *file, struct kobject *kobj,             \
      26             :                            struct bin_attribute *attr, char *buf,               \
      27             :                            loff_t off, size_t count)                            \
      28             : {                                                                               \
      29             :         struct device *dev = kobj_to_dev(kobj);                                 \
      30             :                                                                                 \
      31             :         return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id),    \
      32             :                                            off, count);                         \
      33             : }                                                                               \
      34             :                                                                                 \
      35             : static ssize_t name##_list_read(struct file *file, struct kobject *kobj,        \
      36             :                                 struct bin_attribute *attr, char *buf,          \
      37             :                                 loff_t off, size_t count)                       \
      38             : {                                                                               \
      39             :         struct device *dev = kobj_to_dev(kobj);                                 \
      40             :                                                                                 \
      41             :         return cpumap_print_list_to_buf(buf, topology_##mask(dev->id),               \
      42             :                                         off, count);                            \
      43             : }
      44             : 
      45           0 : define_id_show_func(physical_package_id, "%d");
      46             : static DEVICE_ATTR_RO(physical_package_id);
      47             : 
      48             : #ifdef TOPOLOGY_DIE_SYSFS
      49             : define_id_show_func(die_id, "%d");
      50             : static DEVICE_ATTR_RO(die_id);
      51             : #endif
      52             : 
      53             : #ifdef TOPOLOGY_CLUSTER_SYSFS
      54             : define_id_show_func(cluster_id, "%d");
      55             : static DEVICE_ATTR_RO(cluster_id);
      56             : #endif
      57             : 
      58           0 : define_id_show_func(core_id, "%d");
      59             : static DEVICE_ATTR_RO(core_id);
      60             : 
      61           0 : define_id_show_func(ppin, "0x%llx");
      62             : static DEVICE_ATTR_ADMIN_RO(ppin);
      63             : 
      64           0 : define_siblings_read_func(thread_siblings, sibling_cpumask);
      65             : static BIN_ATTR_RO(thread_siblings, CPUMAP_FILE_MAX_BYTES);
      66             : static BIN_ATTR_RO(thread_siblings_list, CPULIST_FILE_MAX_BYTES);
      67             : 
      68           0 : define_siblings_read_func(core_cpus, sibling_cpumask);
      69             : static BIN_ATTR_RO(core_cpus, CPUMAP_FILE_MAX_BYTES);
      70             : static BIN_ATTR_RO(core_cpus_list, CPULIST_FILE_MAX_BYTES);
      71             : 
      72           0 : define_siblings_read_func(core_siblings, core_cpumask);
      73             : static BIN_ATTR_RO(core_siblings, CPUMAP_FILE_MAX_BYTES);
      74             : static BIN_ATTR_RO(core_siblings_list, CPULIST_FILE_MAX_BYTES);
      75             : 
      76             : #ifdef TOPOLOGY_CLUSTER_SYSFS
      77             : define_siblings_read_func(cluster_cpus, cluster_cpumask);
      78             : static BIN_ATTR_RO(cluster_cpus, CPUMAP_FILE_MAX_BYTES);
      79             : static BIN_ATTR_RO(cluster_cpus_list, CPULIST_FILE_MAX_BYTES);
      80             : #endif
      81             : 
      82             : #ifdef TOPOLOGY_DIE_SYSFS
      83             : define_siblings_read_func(die_cpus, die_cpumask);
      84             : static BIN_ATTR_RO(die_cpus, CPUMAP_FILE_MAX_BYTES);
      85             : static BIN_ATTR_RO(die_cpus_list, CPULIST_FILE_MAX_BYTES);
      86             : #endif
      87             : 
      88           0 : define_siblings_read_func(package_cpus, core_cpumask);
      89             : static BIN_ATTR_RO(package_cpus, CPUMAP_FILE_MAX_BYTES);
      90             : static BIN_ATTR_RO(package_cpus_list, CPULIST_FILE_MAX_BYTES);
      91             : 
      92             : #ifdef TOPOLOGY_BOOK_SYSFS
      93             : define_id_show_func(book_id, "%d");
      94             : static DEVICE_ATTR_RO(book_id);
      95             : define_siblings_read_func(book_siblings, book_cpumask);
      96             : static BIN_ATTR_RO(book_siblings, CPUMAP_FILE_MAX_BYTES);
      97             : static BIN_ATTR_RO(book_siblings_list, CPULIST_FILE_MAX_BYTES);
      98             : #endif
      99             : 
     100             : #ifdef TOPOLOGY_DRAWER_SYSFS
     101             : define_id_show_func(drawer_id, "%d");
     102             : static DEVICE_ATTR_RO(drawer_id);
     103             : define_siblings_read_func(drawer_siblings, drawer_cpumask);
     104             : static BIN_ATTR_RO(drawer_siblings, CPUMAP_FILE_MAX_BYTES);
     105             : static BIN_ATTR_RO(drawer_siblings_list, CPULIST_FILE_MAX_BYTES);
     106             : #endif
     107             : 
     108             : static struct bin_attribute *bin_attrs[] = {
     109             :         &bin_attr_core_cpus,
     110             :         &bin_attr_core_cpus_list,
     111             :         &bin_attr_thread_siblings,
     112             :         &bin_attr_thread_siblings_list,
     113             :         &bin_attr_core_siblings,
     114             :         &bin_attr_core_siblings_list,
     115             : #ifdef TOPOLOGY_CLUSTER_SYSFS
     116             :         &bin_attr_cluster_cpus,
     117             :         &bin_attr_cluster_cpus_list,
     118             : #endif
     119             : #ifdef TOPOLOGY_DIE_SYSFS
     120             :         &bin_attr_die_cpus,
     121             :         &bin_attr_die_cpus_list,
     122             : #endif
     123             :         &bin_attr_package_cpus,
     124             :         &bin_attr_package_cpus_list,
     125             : #ifdef TOPOLOGY_BOOK_SYSFS
     126             :         &bin_attr_book_siblings,
     127             :         &bin_attr_book_siblings_list,
     128             : #endif
     129             : #ifdef TOPOLOGY_DRAWER_SYSFS
     130             :         &bin_attr_drawer_siblings,
     131             :         &bin_attr_drawer_siblings_list,
     132             : #endif
     133             :         NULL
     134             : };
     135             : 
     136             : static struct attribute *default_attrs[] = {
     137             :         &dev_attr_physical_package_id.attr,
     138             : #ifdef TOPOLOGY_DIE_SYSFS
     139             :         &dev_attr_die_id.attr,
     140             : #endif
     141             : #ifdef TOPOLOGY_CLUSTER_SYSFS
     142             :         &dev_attr_cluster_id.attr,
     143             : #endif
     144             :         &dev_attr_core_id.attr,
     145             : #ifdef TOPOLOGY_BOOK_SYSFS
     146             :         &dev_attr_book_id.attr,
     147             : #endif
     148             : #ifdef TOPOLOGY_DRAWER_SYSFS
     149             :         &dev_attr_drawer_id.attr,
     150             : #endif
     151             :         &dev_attr_ppin.attr,
     152             :         NULL
     153             : };
     154             : 
     155           3 : static umode_t topology_is_visible(struct kobject *kobj,
     156             :                                    struct attribute *attr, int unused)
     157             : {
     158           3 :         if (attr == &dev_attr_ppin.attr && !topology_ppin(kobj_to_dev(kobj)->id))
     159             :                 return 0;
     160             : 
     161           2 :         return attr->mode;
     162             : }
     163             : 
     164             : static const struct attribute_group topology_attr_group = {
     165             :         .attrs = default_attrs,
     166             :         .bin_attrs = bin_attrs,
     167             :         .is_visible = topology_is_visible,
     168             :         .name = "topology"
     169             : };
     170             : 
     171             : /* Add/Remove cpu_topology interface for CPU device */
     172           1 : static int topology_add_dev(unsigned int cpu)
     173             : {
     174           1 :         struct device *dev = get_cpu_device(cpu);
     175             : 
     176           1 :         return sysfs_create_group(&dev->kobj, &topology_attr_group);
     177             : }
     178             : 
     179           0 : static int topology_remove_dev(unsigned int cpu)
     180             : {
     181           0 :         struct device *dev = get_cpu_device(cpu);
     182             : 
     183           0 :         sysfs_remove_group(&dev->kobj, &topology_attr_group);
     184           0 :         return 0;
     185             : }
     186             : 
     187           1 : static int __init topology_sysfs_init(void)
     188             : {
     189           1 :         return cpuhp_setup_state(CPUHP_TOPOLOGY_PREPARE,
     190             :                                  "base/topology:prepare", topology_add_dev,
     191             :                                  topology_remove_dev);
     192             : }
     193             : 
     194             : device_initcall(topology_sysfs_init);

Generated by: LCOV version 1.14