|
@@ -63,11 +63,20 @@ static void cpu_free(cpu_t *cpu)
|
|
|
The second CPU with the same IDs is a thread of Hyper Threading.
|
|
|
We don't want to use HT for IRQ balancing. */
|
|
|
static cpu_t * cpu_list_search_ht(lub_list_t *cpus,
|
|
|
- unsigned int package_id,
|
|
|
- unsigned int core_id)
|
|
|
+ unsigned int package_id, unsigned int core_id,
|
|
|
+ cpumask_t thread_siblings)
|
|
|
{
|
|
|
lub_list_node_t *iter;
|
|
|
|
|
|
+ /* Check if current CPU has thread siblings */
|
|
|
+ /* The CPUs without thread siblings has no hyper
|
|
|
+ threading. For example some AMD processors has
|
|
|
+ two CPUs with the same package and core ids but
|
|
|
+ has no thread siblings. Don't consider such CPUs as
|
|
|
+ a hyper threading. */
|
|
|
+ if (cpus_weight(thread_siblings) < 2)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
for (iter = lub_list_iterator_init(cpus); iter;
|
|
|
iter = lub_list_iterator_next(iter)) {
|
|
|
cpu_t *cpu;
|
|
@@ -149,6 +158,9 @@ int scan_cpus(lub_list_t *cpus, int ht)
|
|
|
unsigned int package_id;
|
|
|
unsigned int core_id;
|
|
|
cpu_t *new;
|
|
|
+ char *str = NULL;
|
|
|
+ size_t sz;
|
|
|
+ cpumask_t thread_siblings;
|
|
|
|
|
|
for (id = 0; id < NR_CPUS; id++) {
|
|
|
sprintf(path, "%s/cpu%d", SYSFS_CPU_PATH, id);
|
|
@@ -177,8 +189,19 @@ int scan_cpus(lub_list_t *cpus, int ht)
|
|
|
}
|
|
|
fclose(fd);
|
|
|
|
|
|
+ /* Get thread siblings */
|
|
|
+ cpus_clear(thread_siblings);
|
|
|
+ cpu_set(id, thread_siblings);
|
|
|
+ sprintf(path, "%s/cpu%d/topology/thread_siblings",
|
|
|
+ SYSFS_CPU_PATH, id);
|
|
|
+ if ((fd = fopen(path, "r"))) {
|
|
|
+ if (getline(&str, &sz, fd) >= 0)
|
|
|
+ cpumask_parse_user(str, strlen(str), thread_siblings);
|
|
|
+ fclose(fd);
|
|
|
+ }
|
|
|
+
|
|
|
/* Don't use second thread of Hyper Threading */
|
|
|
- if (!ht && cpu_list_search_ht(cpus, package_id, core_id))
|
|
|
+ if (!ht && cpu_list_search_ht(cpus, package_id, core_id, thread_siblings))
|
|
|
continue;
|
|
|
|
|
|
new = cpu_new(id);
|
|
@@ -186,6 +209,7 @@ int scan_cpus(lub_list_t *cpus, int ht)
|
|
|
new->core_id = core_id;
|
|
|
cpu_list_add(cpus, new);
|
|
|
}
|
|
|
+ free(str);
|
|
|
|
|
|
return 0;
|
|
|
}
|