topology.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful, but
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  19. * NON INFRINGEMENT. See the GNU General Public License for more
  20. * details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. *
  26. */
  27. #include <linux/mm.h>
  28. #include <linux/cpu.h>
  29. #include <linux/module.h>
  30. #include <linux/hardirq.h>
  31. #include <linux/topology.h>
  32. #define define_id_show_func(name) \
  33. static ssize_t name##_show(struct device *dev, \
  34. struct device_attribute *attr, char *buf) \
  35. { \
  36. return sprintf(buf, "%d\n", topology_##name(dev->id)); \
  37. }
  38. #define define_siblings_show_map(name, mask) \
  39. static ssize_t name##_show(struct device *dev, \
  40. struct device_attribute *attr, char *buf) \
  41. { \
  42. return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\
  43. }
  44. #define define_siblings_show_list(name, mask) \
  45. static ssize_t name##_list_show(struct device *dev, \
  46. struct device_attribute *attr, \
  47. char *buf) \
  48. { \
  49. return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\
  50. }
  51. #define define_siblings_show_func(name, mask) \
  52. define_siblings_show_map(name, mask); \
  53. define_siblings_show_list(name, mask)
  54. define_id_show_func(physical_package_id);
  55. static DEVICE_ATTR_RO(physical_package_id);
  56. define_id_show_func(core_id);
  57. static DEVICE_ATTR_RO(core_id);
  58. define_siblings_show_func(thread_siblings, sibling_cpumask);
  59. static DEVICE_ATTR_RO(thread_siblings);
  60. static DEVICE_ATTR_RO(thread_siblings_list);
  61. define_siblings_show_func(core_siblings, core_cpumask);
  62. static DEVICE_ATTR_RO(core_siblings);
  63. static DEVICE_ATTR_RO(core_siblings_list);
  64. #ifdef CONFIG_SCHED_BOOK
  65. define_id_show_func(book_id);
  66. static DEVICE_ATTR_RO(book_id);
  67. define_siblings_show_func(book_siblings, book_cpumask);
  68. static DEVICE_ATTR_RO(book_siblings);
  69. static DEVICE_ATTR_RO(book_siblings_list);
  70. #endif
  71. #ifdef CONFIG_SCHED_DRAWER
  72. define_id_show_func(drawer_id);
  73. static DEVICE_ATTR_RO(drawer_id);
  74. define_siblings_show_func(drawer_siblings, drawer_cpumask);
  75. static DEVICE_ATTR_RO(drawer_siblings);
  76. static DEVICE_ATTR_RO(drawer_siblings_list);
  77. #endif
  78. static struct attribute *default_attrs[] = {
  79. &dev_attr_physical_package_id.attr,
  80. &dev_attr_core_id.attr,
  81. &dev_attr_thread_siblings.attr,
  82. &dev_attr_thread_siblings_list.attr,
  83. &dev_attr_core_siblings.attr,
  84. &dev_attr_core_siblings_list.attr,
  85. #ifdef CONFIG_SCHED_BOOK
  86. &dev_attr_book_id.attr,
  87. &dev_attr_book_siblings.attr,
  88. &dev_attr_book_siblings_list.attr,
  89. #endif
  90. #ifdef CONFIG_SCHED_DRAWER
  91. &dev_attr_drawer_id.attr,
  92. &dev_attr_drawer_siblings.attr,
  93. &dev_attr_drawer_siblings_list.attr,
  94. #endif
  95. NULL
  96. };
  97. static const struct attribute_group topology_attr_group = {
  98. .attrs = default_attrs,
  99. .name = "topology"
  100. };
  101. /* Add/Remove cpu_topology interface for CPU device */
  102. static int topology_add_dev(unsigned int cpu)
  103. {
  104. struct device *dev = get_cpu_device(cpu);
  105. return sysfs_create_group(&dev->kobj, &topology_attr_group);
  106. }
  107. static int topology_remove_dev(unsigned int cpu)
  108. {
  109. struct device *dev = get_cpu_device(cpu);
  110. sysfs_remove_group(&dev->kobj, &topology_attr_group);
  111. return 0;
  112. }
  113. static int topology_sysfs_init(void)
  114. {
  115. return cpuhp_setup_state(CPUHP_TOPOLOGY_PREPARE,
  116. "base/topology:prepare", topology_add_dev,
  117. topology_remove_dev);
  118. }
  119. device_initcall(topology_sysfs_init);