Browse Source

Dont confuse with HT

Serj Kalichev 10 years ago
parent
commit
174128c954
1 changed files with 27 additions and 3 deletions
  1. 27 3
      cpu_parse.c

+ 27 - 3
cpu_parse.c

@@ -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;
 }