"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-brk.c" (15 Mar 2019, 4402 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-brk.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 /*
   28  *  stress_brk()
   29  *  stress brk and sbrk
   30  */
   31 static int stress_brk(const args_t *args)
   32 {
   33     pid_t pid;
   34     uint32_t ooms = 0, segvs = 0, nomems = 0;
   35     const size_t page_size = args->page_size;
   36 
   37 again:
   38     if (!g_keep_stressing_flag)
   39         return EXIT_SUCCESS;
   40     pid = fork();
   41     if (pid < 0) {
   42         if ((errno == EAGAIN) || (errno == ENOMEM))
   43             goto again;
   44         pr_err("%s: fork failed: errno=%d: (%s)\n",
   45             args->name, errno, strerror(errno));
   46     } else if (pid > 0) {
   47         int status, ret;
   48 
   49         (void)setpgid(pid, g_pgrp);
   50         /* Parent, wait for child */
   51         ret = waitpid(pid, &status, 0);
   52         if (ret < 0) {
   53             if (errno != EINTR)
   54                 pr_dbg("%s: waitpid(): errno=%d (%s)\n",
   55                     args->name, errno, strerror(errno));
   56             (void)kill(pid, SIGTERM);
   57             (void)kill(pid, SIGKILL);
   58             (void)waitpid(pid, &status, 0);
   59         } else if (WIFSIGNALED(status)) {
   60             pr_dbg("%s: child died: %s (instance %d)\n",
   61                 args->name, stress_strsignal(WTERMSIG(status)),
   62                 args->instance);
   63             /* If we got killed by OOM killer, re-start */
   64             if (WTERMSIG(status) == SIGKILL) {
   65                 if (g_opt_flags & OPT_FLAGS_OOMABLE) {
   66                     log_system_mem_info();
   67                     pr_dbg("%s: assuming killed by OOM "
   68                         "killer, bailing out "
   69                         "(instance %d)\n",
   70                         args->name, args->instance);
   71                     _exit(0);
   72                 } else {
   73                     log_system_mem_info();
   74                     pr_dbg("%s: assuming killed by OOM "
   75                         "killer, restarting again "
   76                         "(instance %d)\n",
   77                         args->name, args->instance);
   78                     ooms++;
   79                     goto again;
   80                 }
   81             }
   82             /* If we got killed by sigsegv, re-start */
   83             if (WTERMSIG(status) == SIGSEGV) {
   84                 pr_dbg("%s: killed by SIGSEGV, "
   85                     "restarting again "
   86                     "(instance %d)\n",
   87                     args->name, args->instance);
   88                 segvs++;
   89                 goto again;
   90             }
   91         }
   92     } else if (pid == 0) {
   93         uint8_t *start_ptr;
   94         bool touch = !(g_opt_flags & OPT_FLAGS_BRK_NOTOUCH);
   95         int ret, i = 0;
   96 
   97         (void)setpgid(0, g_pgrp);
   98         stress_parent_died_alarm();
   99 
  100         /* Make sure this is killable by OOM killer */
  101         set_oom_adjustment(args->name, true);
  102 
  103         /* Explicitly drop capabilites, makes it more OOM-able */
  104         ret = stress_drop_capabilities(args->name);
  105         (void)ret;
  106 
  107         start_ptr = shim_sbrk(0);
  108         if (start_ptr == (void *) -1) {
  109             pr_fail_err("sbrk(0)");
  110             _exit(EXIT_FAILURE);
  111         }
  112 
  113         do {
  114             uint8_t *ptr;
  115 
  116             i++;
  117             if (i > 8) {
  118                 i = 0;
  119                 ptr = shim_sbrk(0);
  120                 ptr -= page_size;
  121                 if (shim_brk(ptr) < 0)
  122                     ptr = (void *)-1;
  123             } else {
  124                 ptr = shim_sbrk((intptr_t)page_size);
  125             }
  126             if (ptr == (void *)-1) {
  127                 if ((errno == ENOMEM) || (errno == EAGAIN)) {
  128                     nomems++;
  129                     if (shim_brk(start_ptr) < 0) {
  130                         pr_err("%s: brk(%p) failed: errno=%d (%s)\n",
  131                             args->name, start_ptr, errno,
  132                             strerror(errno));
  133                         _exit(EXIT_FAILURE);
  134                     }
  135                 } else {
  136                     pr_err("%s: sbrk(%d) failed: errno=%d (%s)\n",
  137                         args->name, (int)page_size, errno,
  138                         strerror(errno));
  139                     _exit(EXIT_FAILURE);
  140                 }
  141             } else {
  142                 /* Touch page, force it to be resident */
  143                 if (touch)
  144                     *(ptr - 1) = 0;
  145             }
  146             inc_counter(args);
  147         } while (keep_stressing());
  148     }
  149     if (ooms + segvs + nomems > 0)
  150         pr_dbg("%s: OOM restarts: %" PRIu32
  151             ", SEGV restarts: %" PRIu32
  152             ", out of memory restarts: %" PRIu32 ".\n",
  153             args->name, ooms, segvs, nomems);
  154 
  155     return EXIT_SUCCESS;
  156 }
  157 
  158 stressor_info_t stress_brk_info = {
  159     .stressor = stress_brk,
  160     .class = CLASS_OS | CLASS_VM
  161 };