[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