On 2024-12-03 at 15:26:41 -0800, Reinette Chatre wrote:
>Hi Maciej,
>
>On 12/2/24 3:08 AM, Maciej Wieczor-Retman wrote:
>
>> diff --git a/tools/testing/selftests/resctrl/resctrlfs.c 
>> b/tools/testing/selftests/resctrl/resctrlfs.c
>> index d38d6dd90be4..50561993d37c 100644
>> --- a/tools/testing/selftests/resctrl/resctrlfs.c
>> +++ b/tools/testing/selftests/resctrl/resctrlfs.c
>> @@ -13,6 +13,8 @@
>>  
>>  #include "resctrl.h"
>>  
>> +int snc_unreliable;
>> +
>>  static int find_resctrl_mount(char *buffer)
>>  {
>>      FILE *mounts;
>> @@ -156,6 +158,90 @@ int get_domain_id(const char *resource, int cpu_no, int 
>> *domain_id)
>>      return 0;
>>  }
>>  
>> +/*
>> + * Count number of CPUs in a /sys bitmap
>> + */
>> +static unsigned int count_sys_bitmap_bits(char *name)
>> +{
>> +    FILE *fp = fopen(name, "r");
>> +    int count = 0, c;
>> +
>> +    if (!fp)
>> +            return 0;
>> +
>> +    while ((c = fgetc(fp)) != EOF) {
>> +            if (!isxdigit(c))
>> +                    continue;
>> +            switch (c) {
>> +            case 'f':
>> +                    count++;
>> +            case '7': case 'b': case 'd': case 'e':
>> +                    count++;
>> +            case '3': case '5': case '6': case '9': case 'a': case 'c':
>> +                    count++;
>> +            case '1': case '2': case '4': case '8':
>> +                    count++;
>> +            }
>> +    }
>> +    fclose(fp);
>> +
>
>running this through a syntax checker triggers a couple of complaints due to 
>the
>missing break statements. I think this can be made more robust by making use of
>"fallthrough" and "break". It looks like this can be obtained by including
>linux/compiler.h ... but from what I can tell care should be taken to set
>the include directory _after_ includink lib.mk so that top_srcdir is set
>correctly.

Sure, I'll look into it

>
>> +    return count;
>> +}
>> +
>> +static bool cpus_offline_empty(void)
>> +{
>> +    char offline_cpus_str[64];
>> +    FILE *fp;
>> +
>> +    fp = fopen("/sys/devices/system/cpu/offline", "r");
>
>Please check fp before use.

Will do

>
>> +    if (fscanf(fp, "%s", offline_cpus_str) < 0) {
>
>This needs something equivalent to 
>46058430fc5d ("selftests/resctrl: Protect against array overflow when reading 
>strings")

Thanks, I'll add that protection here.

>
>> +            if (!errno) {
>> +                    fclose(fp);
>> +                    return 1;
>> +            }
>> +            ksft_perror("Could not read /sys/devices/system/cpu/offline");
>> +    }
>> +
>> +    fclose(fp);
>> +
>> +    return 0;
>> +}
>> +
>> +/*
>> + * Detect SNC by comparing #CPUs in node0 with #CPUs sharing LLC with CPU0.
>> + * If any CPUs are offline declare the detection as unreliable and skip the
>> + * tests.
>
>nit: "and skip the tests" can be dropped since the function need not make
>assumption about how callers will use it.

Right, sorry, will remove it.

>
>> + */
>> +int snc_nodes_per_l3_cache(void)
>> +{
>> +    int node_cpus, cache_cpus;
>> +    static int snc_mode;
>> +
>> +    if (!snc_mode) {
>> +            snc_mode = 1;
>> +            if (!cpus_offline_empty()) {
>> +                    ksft_print_msg("Runtime SNC detection unreliable due to 
>> offline CPUs.\n");
>> +                    ksft_print_msg("Setting SNC mode to disabled.\n");
>> +                    snc_unreliable = 1;
>> +                    return snc_mode;
>> +            }
>> +            node_cpus = 
>> count_sys_bitmap_bits("/sys/devices/system/node/node0/cpumap");
>> +            cache_cpus = 
>> count_sys_bitmap_bits("/sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_map");
>> +
>> +            if (!node_cpus || !cache_cpus) {
>> +                    ksft_print_msg("Could not determine Sub-NUMA Cluster 
>> mode.\n");
>> +                    snc_unreliable = 1;
>> +                    return snc_mode;
>> +            }
>> +            snc_mode = cache_cpus / node_cpus;
>> +
>> +            if (snc_mode > 1)
>> +                    ksft_print_msg("SNC-%d mode discovered.\n", snc_mode);
>> +    }
>> +
>> +    return snc_mode;
>> +}
>> +
>>  /*
>>   * get_cache_size - Get cache size for a specified CPU
>>   * @cpu_no: CPU number
>> @@ -211,6 +297,17 @@ int get_cache_size(int cpu_no, const char *cache_type, 
>> unsigned long *cache_size
>>                      break;
>>      }
>>  
>> +    /*
>> +     * The amount of cache represented by each bit in the masks
>> +     * in the schemata file is reduced by a factor equal to SNC
>> +     * nodes per L3 cache.
>> +     * E.g. on a SNC-2 system with a 100MB L3 cache a test that
>> +     * allocates memory from its local SNC node (default behavior
>> +     * without using libnuma) will only see 50 MB llc_occupancy
>> +     * with a fully populated L3 mask in the schemata file.
>> +     */
>> +    if (cache_num == 3)
>> +            *cache_size /= snc_nodes_per_l3_cache();
>>      return 0;
>>  }
>>  
>
>Reinette
>

-- 
Kind regards
Maciej Wieczór-Retman

Reply via email to