^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * driver/base/topology.c - Populate sysfs with cpu topology information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by: Zhang Yanmin, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2006, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/topology.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define define_id_show_func(name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static ssize_t name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define define_siblings_show_map(name, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static ssize_t name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define define_siblings_show_list(name, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static ssize_t name##_list_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define define_siblings_show_func(name, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) define_siblings_show_map(name, mask); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) define_siblings_show_list(name, mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) define_id_show_func(physical_package_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static DEVICE_ATTR_RO(physical_package_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) define_id_show_func(die_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static DEVICE_ATTR_RO(die_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) define_id_show_func(core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static DEVICE_ATTR_RO(core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) define_siblings_show_func(thread_siblings, sibling_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static DEVICE_ATTR_RO(thread_siblings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static DEVICE_ATTR_RO(thread_siblings_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) define_siblings_show_func(core_cpus, sibling_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static DEVICE_ATTR_RO(core_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static DEVICE_ATTR_RO(core_cpus_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) define_siblings_show_func(core_siblings, core_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static DEVICE_ATTR_RO(core_siblings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static DEVICE_ATTR_RO(core_siblings_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) define_siblings_show_func(die_cpus, die_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static DEVICE_ATTR_RO(die_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static DEVICE_ATTR_RO(die_cpus_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) define_siblings_show_func(package_cpus, core_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static DEVICE_ATTR_RO(package_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static DEVICE_ATTR_RO(package_cpus_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #ifdef CONFIG_SCHED_BOOK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) define_id_show_func(book_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static DEVICE_ATTR_RO(book_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) define_siblings_show_func(book_siblings, book_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static DEVICE_ATTR_RO(book_siblings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static DEVICE_ATTR_RO(book_siblings_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #ifdef CONFIG_SCHED_DRAWER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) define_id_show_func(drawer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static DEVICE_ATTR_RO(drawer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) define_siblings_show_func(drawer_siblings, drawer_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static DEVICE_ATTR_RO(drawer_siblings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static DEVICE_ATTR_RO(drawer_siblings_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static struct attribute *default_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) &dev_attr_physical_package_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) &dev_attr_die_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) &dev_attr_core_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) &dev_attr_thread_siblings.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) &dev_attr_thread_siblings_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) &dev_attr_core_cpus.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) &dev_attr_core_cpus_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) &dev_attr_core_siblings.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) &dev_attr_core_siblings_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) &dev_attr_die_cpus.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) &dev_attr_die_cpus_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) &dev_attr_package_cpus.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) &dev_attr_package_cpus_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #ifdef CONFIG_SCHED_BOOK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) &dev_attr_book_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) &dev_attr_book_siblings.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) &dev_attr_book_siblings_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_SCHED_DRAWER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) &dev_attr_drawer_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) &dev_attr_drawer_siblings.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) &dev_attr_drawer_siblings_list.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static const struct attribute_group topology_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .attrs = default_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .name = "topology"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Add/Remove cpu_topology interface for CPU device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int topology_add_dev(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct device *dev = get_cpu_device(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return sysfs_create_group(&dev->kobj, &topology_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int topology_remove_dev(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct device *dev = get_cpu_device(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) sysfs_remove_group(&dev->kobj, &topology_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int __init topology_sysfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return cpuhp_setup_state(CPUHP_TOPOLOGY_PREPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "base/topology:prepare", topology_add_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) topology_remove_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) device_initcall(topology_sysfs_init);