make pid_list dynamically sized with memory
PATCH v3 1/1 make pid_list dynamically sized with memory
From: Caspar Zhang <[email protected]>
We get segfaults during testing mtest01 on a 5TB memory machine, the problem was traced to the array pid_list[] went to overflow and corrupted memory. This fix makes pid_list dynamically sized with correct memory size to avoid overflow.
v2: not split into different bits when allocating pid_list.
v3: 1) fix optargs: -b and -p should not be used at the same time.
2) pre_mem maybe not initialized before using if -p option not used. fix it by moving it outside ``if(maxpercent)'' block.
--- testcases/kernel/mem/mtest01/mtest01.c | 64 +++++++++++++++++++------------- 1 files changed, 38 insertions(+), 26 deletions(-)
testcases/kernel/mem/mtest01/mtest01.c +38 -26
@@ -44,6 +44,10 @@#include "test.h" +#define FIVE_HUNDRED_KB (unsigned long long)(500*1024*1024) +#define ONE_MEGABYTE (unsigned long long)(1024*1024*1024) +#define THREE_MEGABYTES (unsigned long long)(3*ONE_MEGABYTE) +char *TCID ="mtest01" ;int TST_TOTAL =1 ;
@@ -58,14 +62,15 @@ int main(int argc, char* argv[]) {char * mem;float percent;unsigned int maxpercent=0 , dowrite=0 , verbose=0 , j, c; -unsigned long bytecount, alloc_bytes; +unsigned long bytecount, alloc_bytes, max_pids;unsigned long long original_maxbytes,maxbytes=0 ;unsigned long long pre_mem, post_mem; +unsigned long long total_ram, total_free,D ,C ;extern char * optarg;int chunksize =1024 *1024 ;/* one meg at a time by default */ struct sysinfo sstats;int i,pid_cntr; -pid_t pid,pid_list[1000 ]; +pid_t pid,*pid_list;struct sigaction act; act.sa_handler = handler;
@@ -73,9 +78,6 @@ int main(int argc, char* argv[]) {sigemptyset (&act.sa_mask);sigaction (SIGRTMIN , &act,0 ); -for (i=0 ;i<1000 ;i++) - pid_list[i]=(pid_t )0 ; -while ((c=getopt (argc, argv,"c:b:p:wvh" )) !=EOF ) {switch ((char )c) {case 'c' :
@@ -83,9 +85,17 @@ int main(int argc, char* argv[]) {break ;case 'b' : maxbytes =atoll (optarg); +if (maxpercent !=0 ) { +tst_resm (TFAIL ,"ERROR: -b option cannot be used with -p option at the same time" ); +exit (1 ); + }break ;case 'p' : maxpercent =atoi (optarg); +if (maxbytes !=0 ) { +tst_resm (TFAIL ,"ERROR: -p option cannot be used with -b option at the same time" ); +exit (1 ); + }if (maxpercent <=0 ) {tst_resm (TFAIL ,"ERROR: -p option requires number greater than 0" );exit (1 );}
@@ -113,34 +123,37 @@ int main(int argc, char* argv[]) { }sysinfo (&sstats); -if (maxpercent) { -unsigned long long total_ram, total_free,D ,C ; - percent=(float )maxpercent/100.00 ; + total_ram = sstats.totalram + sstats.totalswap; + total_free = sstats.freeram + sstats.freeswap; +/* Total Free Pre-Test RAM */ + pre_mem = sstats.mem_unit*total_free; - total_ram=sstats.totalram; - total_ram=total_ram+sstats.totalswap; + max_pids = total_ram /FIVE_HUNDRED_KB +1 ; - total_free=sstats.freeram; - total_free=total_free+sstats.freeswap; +if ((pid_list =malloc (max_pids *sizeof (pid_t))) ==NULL ) + { +tst_resm (TBROK |TERRNO ,"malloc" ); +exit (1 ); + } +memset (pid_list,0 , max_pids *sizeof (pid_t)); -/* Total memory used needed to reach maxpercent */ -D = percent*(sstats.mem_unit*total_ram); -tst_resm (TINFO ,"Total memory used needed to reach maxpercent = %llu kbytes" ,D /1024 ); +/* Currently used memory */ +C = sstats.mem_unit*(total_ram-total_free); +tst_resm (TINFO ,"Total memory already used on system = %llu kbytes" ,C /1024 ); -/* Total memory already used */ -C = sstats.mem_unit*(total_ram-total_free); -tst_resm (TINFO ,"Total memory already used on system = %llu kbytes" ,C /1024 ); +if (maxpercent) { + percent=(float )maxpercent/100.00 ; -/* Total Free Pre-Test RAM */ - pre_mem = sstats.mem_unit*total_free; +/* Desired memory needed to reach maxpercent */ +D = percent*(sstats.mem_unit*total_ram); +tst_resm (TINFO ,"Total memory used needed to reach maxpercent = %llu kbytes" ,D /1024 );/* Are we already using more than maxpercent? */ if (C >D ) {tst_resm (TFAIL ,"More memory than the maximum amount you specified is already being used" ); +free (pid_list);exit (1 ); } -else - pre_mem = sstats.mem_unit*total_free;/* set maxbytes to the extra amount we want to allocate */ maxbytes =D -C ;
@@ -155,9 +168,6 @@ int main(int argc, char* argv[]) { pid_list[i]=pid;#if defined (_s390_)/* s390's 31bit addressing requires smaller chunks */ -#define FIVE_HUNDRED_KB (500*1024*1024) -#define ONE_MEGABYTE (1024*1024*1024) -#define THREE_MEGABYTES (3*ONE_MEGABYTE)while (pid !=0 && maxbytes >FIVE_HUNDRED_KB ) { i++;
@@ -212,6 +222,7 @@ int main(int argc, char* argv[]) {while (1 ) {if ((mem = (char *)malloc (chunksize)) ==NULL ) {tst_resm (TINFO ,"stopped at %lu bytes" , bytecount); +free (pid_list);exit (1 ); }if (dowrite)
@@ -262,5 +273,6 @@ int main(int argc, char* argv[]) {else tst_resm (TPASS ,"%llu kbytes allocated only." , original_maxbytes/1024 ); } +free (pid_list);exit (0 ); -} +}
Signature · 13 lines
1.7.3.4 ------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
Quoted 11 lines · On 01/05/2011 12:21 AM, [email protected] wrote:
We get segfaults during testing mtest01 on a 5TB memory machine, the problem was traced to the array pid_list[] went to overflow and corrupted memory. This fix makes
pid_listdynamically sized with correct memory size to avoid overflow.v2: not split into different bits when allocating
pid_list.
v3: 1) fix optargs: -b and -p should not be used at the same time.
2)pre_memmaybe not initialized before using if -p option not used. fix it by moving it outside ``if(maxpercent)'' block.Signed-off-by Caspar Zhang <[email protected]>
Hi Garrett, please review v3, the up-to-date version.
Thanks,
Caspar
Signature · 18 lines
Quality Assurance Associate (Kernel) in Red Hat Software (Beijing) Co., R&D Branch TEL: +86-10-62608150 WEB: http://www.redhat.com/ -- C-A-S-P-A-R, Caspar /kæspɑ:/ ;-) ------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
PATCH 1/1 fix mtest01 code format [was: Re: [PATCH v3] make pid_list dynamically sized with memory]
Here is another patch, which just fixes the code format in mtest01.c. This patch should be applied after previous patch applied.
Thanks,
Caspar
From 9ba8783301dad1bef3aa3a929d4441c964802514 Mon Sep 17 00:00:00 2001
From: Caspar Zhang <[email protected]>
Date: Wed, 5 Jan 2011 21:09:25 +0800
Subject: [PATCH 2/2] fix mtest01 code format
--- testcases/kernel/mem/mtest01/mtest01.c | 400 ++++++++++++++++---------------- 1 files changed, 199 insertions(+), 201 deletions(-)
testcases/kernel/mem/mtest01/mtest01.c +199 -201
@@ -50,229 +50,227 @@char *TCID ="mtest01" ;int TST_TOTAL =1 ; -int pid_count =0 ;void handler (int signo) { - pid_count++; + pid_count++; } -int main (int argc,char * argv[]) { -char * mem; -float percent; -unsigned int maxpercent=0 , dowrite=0 , verbose=0 , j, c; -unsigned long bytecount, alloc_bytes, max_pids; -unsigned long long original_maxbytes,maxbytes=0 ; -unsigned long long pre_mem, post_mem; -unsigned long long total_ram, total_free,D ,C ; -extern char * optarg; -int chunksize =1024 *1024 ;/* one meg at a time by default */ -struct sysinfo sstats; -int i,pid_cntr; -pid_t pid,*pid_list; -struct sigaction act; - - act.sa_handler = handler; - act.sa_flags =0 ; -sigemptyset (&act.sa_mask); -sigaction (SIGRTMIN , &act,0 ); +int main (int argc,char * argv[]) +{ +char * mem; +float percent; +unsigned int maxpercent =0 , dowrite =0 , verbose=0 , j, c; +unsigned long bytecount, alloc_bytes, max_pids; +unsigned long long original_maxbytes, maxbytes =0 ; +unsigned long long pre_mem, post_mem; +unsigned long long total_ram, total_free,D ,C ; +extern char * optarg; +int chunksize =1024 *1024 ;/* one meg at a time by default */ +struct sysinfo sstats; +int i, pid_cntr; +pid_t pid, *pid_list; +struct sigaction act; -while ((c=getopt (argc, argv,"c:b:p:wvh" )) !=EOF ) { -switch ((char )c) { -case 'c' : - chunksize =atoi (optarg); -break ; -case 'b' : - maxbytes =atoll (optarg); -if (maxpercent !=0 ) { -tst_resm (TFAIL ,"ERROR: -b option cannot be used with -p option at the same time" ); -exit (1 ); - } -break ; -case 'p' : - maxpercent =atoi (optarg); -if (maxbytes !=0 ) { -tst_resm (TFAIL ,"ERROR: -p option cannot be used with -b option at the same time" ); -exit (1 ); + act.sa_handler = handler; + act.sa_flags =0 ; +sigemptyset (&act.sa_mask); +sigaction (SIGRTMIN , &act,0 ); + +while ((c =getopt (argc, argv,"c:b:p:wvh" )) !=EOF ) + { +switch ((char )c) + { +case 'c' : + chunksize =atoi (optarg); +break ; +case 'b' : +if (maxpercent !=0 ) +tst_brkm (TFAIL ,NULL ,"ERROR: -b option cannot be used with -p option at the same time" ); + maxbytes =atoll (optarg); +break ; +case 'p' : +if (maxbytes !=0 ) +tst_brkm (TFAIL ,NULL ,"ERROR: -p option cannot be used with -b option at the same time" ); + maxpercent =atoi (optarg); +if (maxpercent <=0 ) +tst_brkm (TFAIL ,NULL ,"ERROR: -p option requires number greater than 0" ); +if (maxpercent >99 ) +tst_brkm (TFAIL ,NULL ,"ERROR: -p option cannot be greater than 99" ); +break ; +case 'w' : + dowrite =1 ; +break ; +case 'v' : + verbose =1 ; +break ; +case 'h' : +default : +printf ("Usage: %s [-c <bytes>] [-b <bytes>|-p <percent>] [-v]\n" , argv[0 ]); +printf ("\t-c <num>\tsize of chunk in bytes to malloc on each pass\n" ); +printf ("\t-b <bytes>\tmaximum number of bytes to allocate before stopping\n" ); +printf ("\t-p <bytes>\tpercent of total memory used at which the program stops\n" ); +printf ("\t-w\t\twrite to the memory after allocating\n" ); +printf ("\t-v\t\tverbose\n" ); +printf ("\t-h\t\tdisplay usage\n" ); +exit (-1 ); } -if (maxpercent <=0 ) { -tst_resm (TFAIL ,"ERROR: -p option requires number greater than 0" ); -exit (1 );} -if (maxpercent >99 ) { -tst_resm (TFAIL ,"ERROR: -p option cannot be greater than 99" ); -exit (1 );} -break ; -case 'w' : - dowrite =1 ; -break ; -case 'v' : - verbose =1 ; -break ; -case 'h' : -default : -printf ("Usage: %s [-c <bytes>] [-b <bytes>|-p <percent>] [-v]\n" , argv[0 ]); -printf ("\t-c <num>\tsize of chunk in bytes to malloc on each pass\n" ); -printf ("\t-b <bytes>\tmaximum number of bytes to allocate before stopping\n" ); -printf ("\t-p <bytes>\tpercent of total memory used at which the program stops\n" ); -printf ("\t-w\t\twrite to the memory after allocating\n" ); -printf ("\t-v\t\tverbose\n" ); -printf ("\t-h\t\tdisplay usage\n" ); -exit (-1 ); } - } - -sysinfo (&sstats); - total_ram = sstats.totalram + sstats.totalswap; - total_free = sstats.freeram + sstats.freeswap; -/* Total Free Pre-Test RAM */ - pre_mem = sstats.mem_unit*total_free; - - max_pids = total_ram /FIVE_HUNDRED_KB +1 ; - -if ((pid_list =malloc (max_pids *sizeof (pid_t))) ==NULL ) - { -tst_resm (TBROK |TERRNO ,"malloc" ); -exit (1 ); - } -memset (pid_list,0 , max_pids *sizeof (pid_t)); - -/* Currently used memory */ -C = sstats.mem_unit*(total_ram-total_free); -tst_resm (TINFO ,"Total memory already used on system = %llu kbytes" ,C /1024 ); - -if (maxpercent) { - percent=(float )maxpercent/100.00 ; - -/* Desired memory needed to reach maxpercent */ -D = percent*(sstats.mem_unit*total_ram); -tst_resm (TINFO ,"Total memory used needed to reach maxpercent = %llu kbytes" ,D /1024 ); + +sysinfo (&sstats); + total_ram = sstats.totalram + sstats.totalswap; + total_free = sstats.freeram + sstats.freeswap; +/* Total Free Pre-Test RAM */ + pre_mem = sstats.mem_unit * total_free; + max_pids = total_ram / (unsigned long )FIVE_HUNDRED_KB +1 ; + +if ((pid_list =malloc (max_pids *sizeof (pid_t))) ==NULL ) +tst_brkm (TBROK |TERRNO ,NULL ,"malloc" ); +memset (pid_list,0 , max_pids *sizeof (pid_t)); + +/* Currently used memory */ +C = sstats.mem_unit * (total_ram - total_free); +tst_resm (TINFO ,"Total memory already used on system = %llu kbytes" ,C /1024 ); + +if (maxpercent) + { + percent = (float )maxpercent /100.00 ; -/* Are we already using more than maxpercent? */ -if (C >D ) { -tst_resm (TFAIL ,"More memory than the maximum amount you specified is already being used" ); -free (pid_list); -exit (1 ); +/* Desired memory needed to reach maxpercent */ +D = percent * (sstats.mem_unit * total_ram); +tst_resm (TINFO ,"Total memory used needed to reach maxpercent = %llu kbytes" ,D /1024 ); + +/* Are we already using more than maxpercent? */ +if (C >D ) + { +tst_resm (TFAIL ,"More memory than the maximum amount you specified is already being used" ); +free (pid_list); +exit (1 ); + } + +/* set maxbytes to the extra amount we want to allocate */ + maxbytes =D -C ; +tst_resm (TINFO ,"Filling up %d%% of ram which is %llu kbytes" , maxpercent, maxbytes/1024 ); } - -/* set maxbytes to the extra amount we want to allocate */ - maxbytes =D -C ; -tst_resm (TINFO ,"Filling up %d%% of ram which is %llu kbytes" , maxpercent, maxbytes/1024 ); - } - original_maxbytes=maxbytes; - i=0 ; - pid_cntr=0 ; - pid=fork (); -if (pid !=0 ) - pid_cntr++; - pid_list[i]=pid; + original_maxbytes = maxbytes; + i =0 ; + pid_cntr =0 ; + pid =fork (); +if (pid !=0 ) + pid_cntr++; + pid_list[i] = pid;#if defined (_s390_)/* s390's 31bit addressing requires smaller chunks */ -while (pid !=0 && maxbytes >FIVE_HUNDRED_KB ) - { - i++; - maxbytes -=FIVE_HUNDRED_KB ; - pid =fork (); -if (pid !=0 ) { - pid_cntr++; - pid_list[i] = pid; +while (pid !=0 && maxbytes >FIVE_HUNDRED_KB ) + { + i++; + maxbytes -=FIVE_HUNDRED_KB ; + pid =fork (); +if (pid !=0 ) + { + pid_cntr++; + pid_list[i] = pid; + } } - } -if (maxbytes >FIVE_HUNDRED_KB ) - alloc_bytes FIVE_HUNDRED_KB; - else - alloc_bytes = (unsigned long ) maxbytes; - +if (maxbytes >FIVE_HUNDRED_KB ) + alloc_bytes =FIVE_HUNDRED_KB ; +else + alloc_bytes = (unsigned long ) maxbytes; +#elif __WORDSIZE==32 -while (pid !=0 && maxbytes >ONE_MEGABYTE ) - { - i++; - maxbytes -=ONE_MEGABYTE ; - pid =fork (); -if (pid !=0 ) { - pid_cntr++; - pid_list[i]=pid; +while (pid !=0 && maxbytes >ONE_MEGABYTE ) + { + i++; + maxbytes -=ONE_MEGABYTE ; + pid =fork (); +if (pid !=0 ) + { + pid_cntr++; + pid_list[i]=pid; + } } - } -if (maxbytes >ONE_MEGABYTE ) - alloc_bytes =ONE_MEGABYTE ; -else - alloc_bytes = (unsigned long )maxbytes; - +if (maxbytes >ONE_MEGABYTE ) + alloc_bytes =ONE_MEGABYTE ; +else + alloc_bytes = (unsigned long )maxbytes; +#elif __WORDSIZE==64 -while (pid!=0 && maxbytes >THREE_MEGABYTES ) - { - i++; - maxbytes -=THREE_MEGABYTES ; - pid=fork (); -if (pid !=0 ) { - pid_cntr++; - pid_list[i] = pid; - } - } -if (maxbytes >THREE_MEGABYTES ) - alloc_bytes =THREE_MEGABYTES ; -else - alloc_bytes = maxbytes; -#endif - -if (pid ==0 )/** CHILD **/ - { - bytecount=chunksize; -while (1 ) { -if ((mem = (char *)malloc (chunksize)) ==NULL ) { -tst_resm (TINFO ,"stopped at %lu bytes" , bytecount); -free (pid_list); -exit (1 ); - } -if (dowrite) -for (j=0 ; j<chunksize; j++) - *(mem+j)='a' ; -if (verbose) -tst_resm (TINFO ,"allocated %lu bytes chunksize is %d" , bytecount, chunksize); - bytecount+=chunksize; -if (alloc_bytes && (bytecount >= alloc_bytes)) -break ; +while (pid!=0 && maxbytes >THREE_MEGABYTES ) + { + i++; + maxbytes -=THREE_MEGABYTES ; + pid =fork (); +if (pid !=0 ) + { + pid_cntr++; + pid_list[i] = pid; + } } -if (dowrite) -tst_resm (TINFO ,"... %lu bytes allocated and used." , bytecount); +if (maxbytes >THREE_MEGABYTES ) + alloc_bytes =THREE_MEGABYTES ;else -tst_resm (TINFO ,"... %lu bytes allocated only." , bytecount); -kill (getppid (),SIGRTMIN ); -while (1 ) -sleep (1 ); - } -else /** PARENT **/ - { - - i=0 ; -sysinfo (&sstats); + alloc_bytes = maxbytes; +#endif -if (dowrite) +if (pid ==0 )/** CHILD **/ { -/* Total Free Post-Test RAM */ - post_mem = (unsigned long long )sstats.mem_unit*sstats.freeram; - post_mem = post_mem+((unsigned long long )sstats.mem_unit*sstats.freeswap); - -while ((((unsigned long long )pre_mem - post_mem) < (unsigned long long )original_maxbytes) && - (pid_count < pid_cntr) ) - { -sleep (1 ); -sysinfo (&sstats); - post_mem = (unsigned long long )sstats.mem_unit*sstats.freeram; - post_mem = post_mem+((unsigned long long )sstats.mem_unit*sstats.freeswap); - } + bytecount = chunksize; +while (1 ) + { +if ((mem =malloc (chunksize)) ==NULL ) + { +tst_resm (TBROK |TERRNO ,"stopped at %lu bytes" , bytecount); +free (pid_list); +exit (1 ); + } +if (dowrite) +for (j =0 ; j < chunksize; j++) + *(mem+j) ='a' ; +if (verbose) +tst_resm (TINFO ,"allocated %lu bytes chunksize is %d" , bytecount, chunksize); + bytecount += chunksize; +if (alloc_bytes && bytecount >= alloc_bytes) +break ; + } +if (dowrite) +tst_resm (TINFO ,"... %lu bytes allocated and used." , bytecount); +else +tst_resm (TINFO ,"... %lu bytes allocated only." , bytecount); +kill (getppid (),SIGRTMIN ); +while (1 ) +sleep (1 ); } -while (pid_list[i]!=0 ) +else /** PARENT **/ { -kill (pid_list[i],SIGKILL ); - i++; + i =0 ; +sysinfo (&sstats); + +if (dowrite) + { +/* Total Free Post-Test RAM */ + post_mem = (unsigned long long )sstats.mem_unit * sstats.freeram; + post_mem = post_mem + (unsigned long long )sstats.mem_unit * sstats.freeswap; + +while ((((unsigned long long )pre_mem - post_mem) < (unsigned long long )original_maxbytes) && + (pid_count < pid_cntr)) + { +sleep (1 ); +sysinfo (&sstats); + post_mem = (unsigned long long )sstats.mem_unit * sstats.freeram; + post_mem = post_mem + (unsigned long long )sstats.mem_unit * sstats.freeswap; + } + } +while (pid_list[i] !=0 ) + { +kill (pid_list[i],SIGKILL ); + i++; + } +if (dowrite) +tst_resm (TPASS ,"%llu kbytes allocated and used." , original_maxbytes/1024 ); +else +tst_resm (TPASS ,"%llu kbytes allocated only." , original_maxbytes/1024 ); } -if (dowrite) -tst_resm (TPASS ,"%llu kbytes allocated and used." , original_maxbytes/1024 ); -else -tst_resm (TPASS ,"%llu kbytes allocated only." , original_maxbytes/1024 ); - } -free (pid_list); -exit (0 ); +free (pid_list); +exit (0 ); }
Signature · 1 line
1.7.3.4
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list