bpf: selftests: handle sparse CPU allocations
Subsystems (5)
PATCH 1/1 bpf: selftests: handle sparse CPU allocations
Previously, bpf_num_possible_cpus() had a bug when calculating a number of possible CPUs in the case of sparse CPU allocations, as it was considering only the first range or element of /sys/devices/system/cpu/possible.
E.g. in the case of "0,2-3" (CPU 1 is not available), the function returned 1 instead of 3.
This patch fixes the function by making it parse all CPU ranges and elements.
--- tools/testing/selftests/bpf/bpf_util.h | 29 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-)
tools/testing/selftests/bpf/bpf_util.h +19 -10
@@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void)unsigned int start, end, possible_cpus =0 ;char buff[128 ];FILE *fp; -int n; +int n, i, j =0 ; fp =fopen (fcpu,"r" );if (!fp) {
@@ -21,17 +21,26 @@ static inline unsigned int bpf_num_possible_cpus(void)exit (1 ); } -while (fgets (buff,sizeof (buff), fp)) { - n =sscanf (buff,"%u-%u" , &start, &end); -if (n ==0 ) { -printf ("Failed to retrieve # possible CPUs!\n" ); -exit (1 ); - }else if (n ==1 ) { - end = start; +if (!fgets (buff,sizeof (buff), fp)) { +printf ("Failed to read %s!\n" , fcpu); +exit (1 ); + } + +for (i =0 ; i <=strlen (buff); i++) { +if (buff[i] ==',' || buff[i] =='\0' ) { + buff[i] ='\0' ; + n =sscanf (&buff[j],"%u-%u" , &start, &end); +if (n <=0 ) { +printf ("Failed to retrieve # possible CPUs!\n" ); +exit (1 ); + }else if (n ==1 ) { + end = start; + } + possible_cpus += end - start +1 ; + j = i +1 ; } - possible_cpus = start ==0 ? end +1 :0 ; -break ; } +fclose (fp);return possible_cpus;
Signature · 1 line
2.20.1
[ My reply somehow rejected by netdev, this is to send it again. ]
Quoted 39 lines · Martynas Pumputis
Previously,
bpf_num_possible_cpus()had a bug when calculating a number of possible CPUs in the case of sparse CPU allocations, as it was considering only the first range or element of/sys/devices/system/cpu/possible.E.g. in the case of "0,2-3" (CPU 1 is not available), the function returned 1 instead of 3.
This patch fixes the function by making it parse all CPU ranges and elements.
Signed-off-by Martynas Pumputis <[email protected]>--- tools/testing/selftests/bpf/bpf_util.h | 29 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-)tools/testing/selftests/bpf/bpf_util.h +1
-6@@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void)unsigned int start, end, possible_cpus =0 ;char buff[128 ];FILE *fp; -int n; +int n, i, j =0 ; fp =fopen (fcpu,"r" );if (!fp) {@@ -21,17 +21,26 @@ static inline unsigned int bpf_num_possible_cpus(void)exit (1 ); } -while (fgets (buff,sizeof (buff), fp)) { - n =sscanf (buff,"%u-%u" , &start, &end); -if (n ==0 ) { -printf ("Failed to retrieve # possible CPUs!\n" ); -exit (1 );
tools/testing/selftests/bpf/bpf_util.h static inline unsigned int bpf_num_possible_cpus(void) · line 31
Quoted 10 lines
tools/testing/selftests/bpf/bpf_util.h +8
-2- }else if (n ==1 ) { - end = start; +if (!fgets (buff,sizeof (buff), fp)) { +printf ("Failed to read %s!\n" , fcpu); +exit (1 ); + } + +for (i =0 ; i <=strlen (buff); i++) { +if (buff[i] ==',' || buff[i] =='\0' ) { + buff[i] ='\0' ;
This does not sound right. For example, the cpu list "0,2-3", you will change "," to '\0" so buffer becomes "0\02-3". The next iteration you will get strlen(buff) = 1. The "2-3" will be skipped.
Quoted 20 lines
tools/testing/selftests/bpf/bpf_util.h +10
-3+ n =sscanf (&buff[j],"%u-%u" , &start, &end); +if (n <=0 ) { +printf ("Failed to retrieve # possible CPUs!\n" ); +exit (1 ); + }else if (n ==1 ) { + end = start; + } + possible_cpus += end - start +1 ; + j = i +1 ; } - possible_cpus = start ==0 ? end +1 :0 ; -break ; } +fclose (fp);return possible_cpus; --2.20.1
Oops, thanks for noticing the issue with strlen in the for loop. Changing to "int len = strlen(buff); for (i = 0; i < len; i++) <..>" should fix the issue. I'm going to re-submit the patch.
Also, I put some testing results: https://gist.github.com/brb/5369b5cfd08babb80cf2c4081dc19762
Quoted 78 lines · Y Song
[ My reply somehow rejected by netdev, this is to send it again. ]
Quoted 39 lines · Martynas Pumputis
Previously,
bpf_num_possible_cpus()had a bug when calculating a number of possible CPUs in the case of sparse CPU allocations, as it was considering only the first range or element of/sys/devices/system/cpu/possible.E.g. in the case of "0,2-3" (CPU 1 is not available), the function returned 1 instead of 3.
This patch fixes the function by making it parse all CPU ranges and elements.
Signed-off-by Martynas Pumputis <[email protected]>--- tools/testing/selftests/bpf/bpf_util.h | 29 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-)tools/testing/selftests/bpf/bpf_util.h +1
-6@@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void)unsigned int start, end, possible_cpus =0 ;char buff[128 ];FILE *fp; -int n; +int n, i, j =0 ; fp =fopen (fcpu,"r" );if (!fp) {@@ -21,17 +21,26 @@ static inline unsigned int bpf_num_possible_cpus(void)exit (1 ); } -while (fgets (buff,sizeof (buff), fp)) { - n =sscanf (buff,"%u-%u" , &start, &end); -if (n ==0 ) { -printf ("Failed to retrieve # possible CPUs!\n" ); -exit (1 );tools/testing/selftests/bpf/bpf_util.h static inline unsigned int bpf_num_possible_cpus(void) · line 31
Quoted 10 lines
tools/testing/selftests/bpf/bpf_util.h +8
-2- }else if (n ==1 ) { - end = start; +if (!fgets (buff,sizeof (buff), fp)) { +printf ("Failed to read %s!\n" , fcpu); +exit (1 ); + } + +for (i =0 ; i <=strlen (buff); i++) { +if (buff[i] ==',' || buff[i] =='\0' ) { + buff[i] ='\0' ;This does not sound right. For example, the cpu list "0,2-3", you will change "," to '\0" so buffer becomes "0\02-3". The next iteration you will get strlen(buff) = 1. The "2-3" will be skipped.
Quoted 20 lines
tools/testing/selftests/bpf/bpf_util.h +10
-3+ n =sscanf (&buff[j],"%u-%u" , &start, &end); +if (n <=0 ) { +printf ("Failed to retrieve # possible CPUs!\n" ); +exit (1 ); + }else if (n ==1 ) { + end = start; + } + possible_cpus += end - start +1 ; + j = i +1 ; } - possible_cpus = start ==0 ? end +1 :0 ; -break ; } +fclose (fp);return possible_cpus; --2.20.1