"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-fault.c" (15 Mar 2019, 4191 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-fault.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 static sigjmp_buf jmp_env;
   28 static volatile bool do_jmp = true;
   29 
   30 /*
   31  *  stress_segvhandler()
   32  *  SEGV handler
   33  */
   34 static void MLOCKED_TEXT stress_segvhandler(int signum)
   35 {
   36     (void)signum;
   37 
   38     if (do_jmp)
   39         siglongjmp(jmp_env, 1);     /* Ugly, bounce back */
   40 }
   41 
   42 /*
   43  *  stress_fault()
   44  *  stress min and max page faulting
   45  */
   46 static int stress_fault(const args_t *args)
   47 {
   48 #if !defined(__HAIKU__)
   49     struct rusage usage;
   50 #endif
   51     char filename[PATH_MAX];
   52     int ret;
   53     NOCLOBBER int i;
   54 
   55     ret = stress_temp_dir_mk_args(args);
   56     if (ret < 0)
   57         return exit_status(-ret);
   58 
   59     (void)stress_temp_filename_args(args,
   60         filename, sizeof(filename), mwc32());
   61     i = 0;
   62 
   63     if (stress_sighandler(args->name, SIGSEGV, stress_segvhandler, NULL) < 0)
   64         return EXIT_FAILURE;
   65     if (stress_sighandler(args->name, SIGBUS, stress_segvhandler, NULL) < 0)
   66         return EXIT_FAILURE;
   67 
   68     do {
   69         char *ptr;
   70         int fd;
   71 
   72         ret = sigsetjmp(jmp_env, 1);
   73         if (ret) {
   74             do_jmp = false;
   75             pr_err("%s: unexpected segmentation fault\n",
   76                 args->name);
   77             break;
   78         }
   79 
   80         fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
   81         if (fd < 0) {
   82             if ((errno == ENOSPC) || (errno == ENOMEM))
   83                 continue;   /* Try again */
   84             pr_fail_err("open");
   85             break;
   86         }
   87 #if defined(HAVE_POSIX_FALLOCATE)
   88         if (posix_fallocate(fd, 0, 1) < 0) {
   89             if (errno == ENOSPC) {
   90                 (void)close(fd);
   91                 continue;   /* Try again */
   92             }
   93             (void)close(fd);
   94             pr_fail_err("posix_fallocate");
   95             break;
   96         }
   97 #else
   98         {
   99             char buffer[1];
  100 
  101 redo:
  102             if (g_keep_stressing_flag &&
  103                 (write(fd, buffer, sizeof(buffer)) < 0)) {
  104                 if ((errno == EAGAIN) || (errno == EINTR))
  105                     goto redo;
  106                 if (errno == ENOSPC) {
  107                     (void)close(fd);
  108                     continue;
  109                 }
  110                 (void)close(fd);
  111                 pr_fail_err("write");
  112                 break;
  113             }
  114         }
  115 #endif
  116         ret = sigsetjmp(jmp_env, 1);
  117         if (ret) {
  118             if (!keep_stressing())
  119                 do_jmp = false;
  120             if (fd != -1)
  121                 (void)close(fd);
  122             goto next;
  123         }
  124 
  125         /*
  126          * Removing file here causes major fault when we touch
  127          * ptr later
  128          */
  129         if (i & 1)
  130             (void)unlink(filename);
  131 
  132         ptr = mmap(NULL, 1, PROT_READ | PROT_WRITE,
  133             MAP_SHARED, fd, 0);
  134         (void)close(fd);
  135         fd = -1;
  136         (void)fd;
  137 
  138         if (ptr == MAP_FAILED) {
  139             if ((errno == EAGAIN) ||
  140                 (errno == ENOMEM) ||
  141                 (errno == ENFILE))
  142                 goto next;
  143             pr_err("%s: mmap failed: errno=%d (%s)\n",
  144                 args->name, errno, strerror(errno));
  145             break;
  146 
  147         }
  148         *ptr = 0;   /* Cause the page fault */
  149 
  150         if (munmap(ptr, 1) < 0) {
  151             pr_err("%s: munmap failed: errno=%d (%s)\n",
  152                 args->name, errno, strerror(errno));
  153             break;
  154         }
  155 
  156 next:
  157         /* Remove file on-non major fault case */
  158         if (!(i & 1))
  159             (void)unlink(filename);
  160 
  161         i++;
  162         inc_counter(args);
  163     } while (keep_stressing());
  164     /* Clean up, most times this is redundant */
  165     (void)unlink(filename);
  166     (void)stress_temp_dir_rm_args(args);
  167 
  168 #if !defined(__HAIKU__)
  169     if (!getrusage(RUSAGE_SELF, &usage)) {
  170         pr_dbg("%s: page faults: minor: %lu, major: %lu\n",
  171             args->name, usage.ru_minflt, usage.ru_majflt);
  172     }
  173 #endif
  174 
  175     return EXIT_SUCCESS;
  176 }
  177 
  178 stressor_info_t stress_fault_info = {
  179     .stressor = stress_fault,
  180     .class = CLASS_INTERRUPT | CLASS_SCHEDULER | CLASS_OS
  181 };