"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-mlockmany.c" (15 Mar 2019, 4882 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-mlockmany.c" see the Fossies "Dox" file reference documentation.

    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 #if defined(HAVE_MLOCK)
   28 
   29 #define MAX_MLOCK_PROCS     (1024)
   30 
   31 /*
   32  *  stress_mlockmany()
   33  *  stress by forking and exiting
   34  */
   35 static int stress_mlockmany(const args_t *args)
   36 {
   37     pid_t pids[MAX_MLOCK_PROCS];
   38     int errnos[MAX_MLOCK_PROCS];
   39     int ret;
   40 #if defined(RLIMIT_MEMLOCK)
   41     struct rlimit rlim;
   42 #endif
   43     size_t mlock_size, max_mlock_procs;
   44 
   45     set_oom_adjustment(args->name, true);
   46 
   47     /* Explicitly drop capabilites, makes it more OOM-able */
   48     ret = stress_drop_capabilities(args->name);
   49     (void)ret;
   50 
   51     max_mlock_procs = args->num_instances > 0 ? MAX_MLOCK_PROCS / args->num_instances : 1;
   52     if (max_mlock_procs < 1)
   53         max_mlock_procs = 1;
   54 
   55 #if defined(RLIMIT_MEMLOCK)
   56     ret = getrlimit(RLIMIT_MEMLOCK, &rlim);
   57     if (ret < 0) {
   58         mlock_size = 8 * MB;
   59     } else {
   60         mlock_size = rlim.rlim_cur;
   61     }
   62 #else
   63     mlock_size = args->page_size * 1024;
   64 #endif
   65 
   66     do {
   67         unsigned int i, n;
   68         size_t shmall, freemem, totalmem, freeswap, last_freeswap;
   69 
   70         (void)memset(pids, 0, sizeof(pids));
   71         (void)memset(errnos, 0, sizeof(errnos));
   72 
   73         stress_get_memlimits(&shmall, &freemem, &totalmem, &last_freeswap);
   74 
   75         for (n = 0; n < max_mlock_procs; n++) {
   76             pid_t pid;
   77 
   78             if (!keep_stressing())
   79                 break;
   80 
   81             stress_get_memlimits(&shmall, &freemem, &totalmem, &freeswap);
   82 
   83             /* We detected swap being used, bail out */
   84             if (last_freeswap > freeswap)
   85                 break;
   86 
   87             /* Keep track of expanding free swap space */
   88             if (freeswap > last_freeswap)
   89                 last_freeswap = freeswap;
   90 
   91             pid = fork();
   92             if (pid == 0) {
   93                 void *ptr = MAP_FAILED;
   94                 size_t mmap_size = mlock_size;
   95 
   96                 (void)setpgid(0, g_pgrp);
   97                 stress_parent_died_alarm();
   98                 set_oom_adjustment(args->name, true);
   99 
  100                 shim_mlockall(0);
  101                 stress_get_memlimits(&shmall, &freemem, &totalmem, &freeswap);
  102                 /* We detected swap being used, bail out */
  103                 if (last_freeswap > freeswap)
  104                     _exit(0);
  105 
  106                 while (mmap_size > args->page_size) {
  107                     if (!keep_stressing())
  108                         _exit(0);
  109                     ptr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
  110                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  111                     if (ptr != MAP_FAILED)
  112                         break;
  113                     mmap_size >>= 1;
  114                 }
  115                 if (ptr == MAP_FAILED)
  116                     _exit(0);
  117 
  118 
  119                 mincore_touch_pages(ptr, mmap_size);
  120 
  121                 mlock_size = mmap_size;
  122                 while (mlock_size > args->page_size) {
  123                     if (!keep_stressing())
  124                         _exit(0);
  125                     ret = shim_mlock(ptr, mlock_size);
  126                     if (ret == 0)
  127                         break;
  128                     mlock_size >>= 1;
  129                 }
  130 
  131                 for (;;) {
  132                     if (!keep_stressing())
  133                         goto unlock;
  134                     (void)shim_munlock(ptr, mlock_size);
  135                     if (!keep_stressing())
  136                         goto unmap;
  137                     (void)shim_mlock(ptr, mlock_size);
  138                     if (!keep_stressing())
  139                         goto unlock;
  140                     /* Try invalid sizes */
  141                     (void)shim_mlock(ptr, 0);
  142                     (void)shim_munlock(ptr, 0);
  143 
  144                     (void)shim_mlock(ptr, mlock_size << 1);
  145                     (void)shim_munlock(ptr, mlock_size << 1);
  146 
  147                     (void)shim_mlock(ptr, ~(size_t)0);
  148                     (void)shim_munlock(ptr, ~(size_t)0);
  149                     if (!keep_stressing())
  150                         goto unlock;
  151                     (void)shim_usleep_interruptible(10000);
  152                 }
  153 unlock:
  154                 (void)shim_munlock(ptr, mlock_size);
  155 unmap:
  156                 (void)munmap(ptr, mmap_size);
  157                 _exit(0);
  158             } else if (pid < 0) {
  159                 errnos[n] = errno;
  160             }
  161             if (pid > -1)
  162                 (void)setpgid(pids[n], g_pgrp);
  163             pids[n] = pid;
  164             if (!g_keep_stressing_flag)
  165                 break;
  166         }
  167         for (i = 0; i < n; i++) {
  168             if (pids[i] > 0) {
  169                 int status;
  170                 /* Parent, wait for child */
  171                 (void)kill(pids[i], SIGKILL);
  172                 (void)waitpid(pids[i], &status, 0);
  173                 inc_counter(args);
  174             }
  175         }
  176     } while (keep_stressing());
  177 
  178     return EXIT_SUCCESS;
  179 }
  180 
  181 stressor_info_t stress_mlockmany_info = {
  182     .stressor = stress_mlockmany,
  183     .class = CLASS_VM | CLASS_OS | CLASS_PATHOLOGICAL
  184 };
  185 
  186 #else
  187 
  188 stressor_info_t stress_mlockmany_info = {
  189     .stressor = stress_not_implemented,
  190     .class = CLASS_VM | CLASS_OS | CLASS_PATHOLOGICAL
  191 };
  192 
  193 #endif
  194