On 01/07/2011 02:42 AM, Caspar Zhang wrote:
> Hi Garrett, this is the *final* version, please review.

Hi, anybody have a chance to look at this patch? Thanks!

Caspar

> 
> On 01/07/2011 02:40 AM, [email protected] wrote:
>> 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.
>> v4: fix code format.
>>
>> Signed-off-by: Caspar Zhang <[email protected]>
>> ---
>>  testcases/kernel/mem/mtest01/mtest01.c |  409 
>> +++++++++++++++++---------------
>>  1 files changed, 215 insertions(+), 194 deletions(-)
>>
>> diff --git a/testcases/kernel/mem/mtest01/mtest01.c 
>> b/testcases/kernel/mem/mtest01/mtest01.c
>> index aee0d51..94b429a 100644
>> --- a/testcases/kernel/mem/mtest01/mtest01.c
>> +++ b/testcases/kernel/mem/mtest01/mtest01.c
>> @@ -44,223 +44,244 @@
>>  
>>  #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;
>> -
>>  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;
>> -  unsigned long long original_maxbytes,maxbytes=0;
>> -  unsigned long long pre_mem, post_mem;
>> -  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];
>> -  struct sigaction act;
>> -
>> -  act.sa_handler = handler;
>> -  act.sa_flags = 0;
>> -  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':
>> -        chunksize = atoi(optarg);
>> -        break;
>> -      case 'b':
>> -        maxbytes = atoll(optarg);
>> -        break;
>> -      case 'p':
>> -        maxpercent = atoi(optarg);
>> -    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);
>> -  if (maxpercent) {
>> +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;
>> -    percent=(float)maxpercent/100.00;
>> -
>> -    total_ram=sstats.totalram;
>> -    total_ram=total_ram+sstats.totalswap;
>> -
>> -    total_free=sstats.freeram;
>> -    total_free=total_free+sstats.freeswap;
>> -
>> -    /* 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);
>> -
>> -    /* 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);
>> +    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);
>> +    
>> +    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_resm(TFAIL, "ERROR: -b option cannot be used with 
>> -p option at the same time");
>> +                    exit(1);
>> +                }
>> +                maxbytes = atoll(optarg);
>> +                break;
>> +            case 'p':
>> +                if (maxbytes != 0) {
>> +                    tst_resm(TFAIL, "ERROR: -p option cannot be used with 
>> -b option at the same time");
>> +                    exit(1);
>> +                }
>> +                maxpercent = atoi(optarg);
>> +                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;
>> -
>> -    /* 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");
>> -      exit(1);
>> +    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_resm(TBROK|TERRNO, "malloc failed.");
>> +        exit(1);
>>      }
>> -    else
>> -      pre_mem = sstats.mem_unit*total_free;
>> +    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;
>>  
>> -    /* 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;
>> +        /* 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);
>> +    }
>> +    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 */
>> -#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++;
>> -    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);
>> -        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);
>> -  }
>> -  exit(0);
>> -}
>> \ No newline at end of file
>> +    free(pid_list);
>> +    exit(0);
>> +}
> 
> 


-- 
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ɑ:/ ;-)

------------------------------------------------------------------------------
Gaining the trust of online customers is vital for the success of any company
that requires sensitive data to be transmitted over the Web.   Learn how to 
best implement a security strategy that keeps consumers' information secure 
and instills the confidence they need to proceed with transactions.
http://p.sf.net/sfu/oracle-sfdevnl 
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to