[PATCH 3/3] ntdll: Implement relationship filtering for create_logical_proc_info on linux.
Anastasios Simeonidis
symeonidis at csd.auth.gr
Mon Nov 25 11:42:53 CST 2019
Also calculate all_cpus_mask on first pass.
Signed-off-by: Anastasios Simeonidis <symeonidis at csd.auth.gr>
---
dlls/ntdll/nt.c | 254 ++++++++++++++++++++++++------------------------
1 file changed, 128 insertions(+), 126 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 8c652a0615..52616b37be 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1686,9 +1686,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
char op, name[MAX_PATH];
ULONG_PTR all_cpus_mask = 0;
- if (relation != RelationAll)
- FIXME("Relationship filtering not implemented: 0x%x\n", relation);
-
/* On systems with a large number of CPU cores (32 or 64 depending on 32-bit or 64-bit),
* we have issues parsing processor information:
* - ULONG_PTR masks as used in data structures can't hold all cores. Requires splitting
@@ -1725,18 +1722,21 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
continue;
}
- sprintf(name, core_info, i, "physical_package_id");
- f = fopen(name, "r");
- if(f)
- {
- fscanf(f, "%u", &r);
- fclose(f);
- }
- else r = 0;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, r, (ULONG_PTR)1 << i))
+ if(relation == RelationAll || relation == RelationProcessorPackage)
{
- fclose(fcpu_list);
- return STATUS_NO_MEMORY;
+ sprintf(name, core_info, i, "physical_package_id");
+ f = fopen(name, "r");
+ if(f)
+ {
+ fscanf(f, "%u", &r);
+ fclose(f);
+ }
+ else r = 0;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, r, (ULONG_PTR)1 << i))
+ {
+ fclose(fcpu_list);
+ return STATUS_NO_MEMORY;
+ }
}
/* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates
@@ -1749,143 +1749,145 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
* on kernel cpu core numbering as opposed to a hardware core ID like provided through
* 'core_id', so are suitable as a unique ID.
*/
- sprintf(name, core_info, i, "thread_siblings_list");
- f = fopen(name, "r");
- if(f)
+ if(relation == RelationAll || relation == RelationProcessorCore ||
+ relation == RelationNumaNode || relation == RelationGroup)
{
- fscanf(f, "%d%c", &phys_core, &op);
- fclose(f);
- }
- else phys_core = i;
+ /* Mask of logical threads sharing same physical core in kernel core numbering. */
+ sprintf(name, core_info, i, "thread_siblings");
+ if(!sysfs_parse_bitmap(name, &thread_mask))
+ thread_mask = 1<<i;
- /* Mask of logical threads sharing same physical core in kernel core numbering. */
- sprintf(name, core_info, i, "thread_siblings");
- if(!sysfs_parse_bitmap(name, &thread_mask))
- thread_mask = 1<<i;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask))
- {
- fclose(fcpu_list);
- return STATUS_NO_MEMORY;
- }
+ /* Needed later for NumaNode and Group. */
+ all_cpus_mask |= thread_mask;
- for(j=0; j<4; j++)
- {
- CACHE_DESCRIPTOR cache;
- ULONG_PTR mask = 0;
-
- sprintf(name, cache_info, i, j, "shared_cpu_map");
- if(!sysfs_parse_bitmap(name, &mask)) continue;
-
- sprintf(name, cache_info, i, j, "level");
- f = fopen(name, "r");
- if(!f) continue;
- fscanf(f, "%u", &r);
- fclose(f);
- cache.Level = r;
-
- sprintf(name, cache_info, i, j, "ways_of_associativity");
- f = fopen(name, "r");
- if(!f) continue;
- fscanf(f, "%u", &r);
- fclose(f);
- cache.Associativity = r;
-
- sprintf(name, cache_info, i, j, "coherency_line_size");
- f = fopen(name, "r");
- if(!f) continue;
- fscanf(f, "%u", &r);
- fclose(f);
- cache.LineSize = r;
+ if(relation == RelationAll || relation == RelationProcessorCore)
+ {
+ sprintf(name, core_info, i, "thread_siblings_list");
+ f = fopen(name, "r");
+ if(f)
+ {
+ fscanf(f, "%d%c", &phys_core, &op);
+ fclose(f);
+ }
+ else phys_core = i;
- sprintf(name, cache_info, i, j, "size");
- f = fopen(name, "r");
- if(!f) continue;
- fscanf(f, "%u%c", &r, &op);
- fclose(f);
- if(op != 'K')
- WARN("unknown cache size %u%c\n", r, op);
- cache.Size = (op=='K' ? r*1024 : r);
-
- sprintf(name, cache_info, i, j, "type");
- f = fopen(name, "r");
- if(!f) continue;
- fscanf(f, "%s", name);
- fclose(f);
- if(!memcmp(name, "Data", 5))
- cache.Type = CacheData;
- else if(!memcmp(name, "Instruction", 11))
- cache.Type = CacheInstruction;
- else
- cache.Type = CacheUnified;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask))
+ {
+ fclose(fcpu_list);
+ return STATUS_NO_MEMORY;
+ }
+ }
+ }
- if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache))
+ if (relation == RelationAll || relation == RelationCache)
+ {
+ for(j=0; j<4; j++)
{
- fclose(fcpu_list);
- return STATUS_NO_MEMORY;
+ CACHE_DESCRIPTOR cache;
+ ULONG_PTR mask = 0;
+
+ sprintf(name, cache_info, i, j, "shared_cpu_map");
+ if(!sysfs_parse_bitmap(name, &mask)) continue;
+
+ sprintf(name, cache_info, i, j, "level");
+ f = fopen(name, "r");
+ if(!f) continue;
+ fscanf(f, "%u", &r);
+ fclose(f);
+ cache.Level = r;
+
+ sprintf(name, cache_info, i, j, "ways_of_associativity");
+ f = fopen(name, "r");
+ if(!f) continue;
+ fscanf(f, "%u", &r);
+ fclose(f);
+ cache.Associativity = r;
+
+ sprintf(name, cache_info, i, j, "coherency_line_size");
+ f = fopen(name, "r");
+ if(!f) continue;
+ fscanf(f, "%u", &r);
+ fclose(f);
+ cache.LineSize = r;
+
+ sprintf(name, cache_info, i, j, "size");
+ f = fopen(name, "r");
+ if(!f) continue;
+ fscanf(f, "%u%c", &r, &op);
+ fclose(f);
+ if(op != 'K')
+ WARN("unknown cache size %u%c\n", r, op);
+ cache.Size = (op=='K' ? r*1024 : r);
+
+ sprintf(name, cache_info, i, j, "type");
+ f = fopen(name, "r");
+ if(!f) continue;
+ fscanf(f, "%s", name);
+ fclose(f);
+ if(!memcmp(name, "Data", 5))
+ cache.Type = CacheData;
+ else if(!memcmp(name, "Instruction", 11))
+ cache.Type = CacheInstruction;
+ else
+ cache.Type = CacheUnified;
+
+ if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache))
+ {
+ fclose(fcpu_list);
+ return STATUS_NO_MEMORY;
+ }
}
}
}
}
fclose(fcpu_list);
- if(data){
- for(i=0; i<len; i++){
- if((*data)[i].Relationship == RelationProcessorCore){
- all_cpus_mask |= (*data)[i].ProcessorMask;
- }
- }
- }else{
- for(i = 0; i < len; ){
- SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i);
- if(infoex->Relationship == RelationProcessorCore){
- all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask;
- }
- i += infoex->Size;
- }
- }
num_cpus = count_bits(all_cpus_mask);
- fnuma_list = fopen("/sys/devices/system/node/online", "r");
- if(!fnuma_list)
+ if(relation == RelationAll || relation == RelationNumaNode)
{
- if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0))
- return STATUS_NO_MEMORY;
- }
- else
- {
- while(!feof(fnuma_list))
+ fnuma_list = fopen("/sys/devices/system/node/online", "r");
+ if(!fnuma_list)
{
- if(!fscanf(fnuma_list, "%u%c ", &beg, &op))
- break;
- if(op == '-') fscanf(fnuma_list, "%u%c ", &end, &op);
- else end = beg;
-
- for(i=beg; i<=end; i++)
+ if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0))
+ return STATUS_NO_MEMORY;
+ }
+ else
+ {
+ while(!feof(fnuma_list))
{
- ULONG_PTR mask = 0;
+ if(!fscanf(fnuma_list, "%u%c ", &beg, &op))
+ break;
+ if(op == '-') fscanf(fnuma_list, "%u%c ", &end, &op);
+ else end = beg;
- sprintf(name, numa_info, i);
- f = fopen(name, "r");
- if(!f) continue;
- while(!feof(f))
+ for(i=beg; i<=end; i++)
{
- if(!fscanf(f, "%x%c ", &r, &op))
- break;
- mask = (sizeof(ULONG_PTR)>sizeof(int) ? mask<<(8*sizeof(DWORD)) : 0) + r;
- }
- fclose(f);
+ ULONG_PTR mask = 0;
- if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, mask, i))
- {
- fclose(fnuma_list);
- return STATUS_NO_MEMORY;
+ sprintf(name, numa_info, i);
+ f = fopen(name, "r");
+ if(!f) continue;
+ while(!feof(f))
+ {
+ if(!fscanf(f, "%x%c ", &r, &op))
+ break;
+ mask = (sizeof(ULONG_PTR)>sizeof(int) ? mask<<(8*sizeof(DWORD)) : 0) + r;
+ }
+ fclose(f);
+
+ if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, mask, i))
+ {
+ fclose(fnuma_list);
+ return STATUS_NO_MEMORY;
+ }
}
}
+ fclose(fnuma_list);
}
- fclose(fnuma_list);
}
- if(dataex)
+ if(dataex && (relation == RelationAll || relation == RelationGroup))
logical_proc_info_add_group(dataex, &len, max_len, num_cpus, all_cpus_mask);
if(data)
--
2.24.0
More information about the wine-devel
mailing list