Azat Khuzhin a943172b73 Add runtime detection for MADV_DONTNEED zeroes pages (mostly for qemu)
qemu does not support this, yet [1], and you can get very tricky assert
if you will run program with jemalloc in use under qemu:

    <jemalloc>: ../contrib/jemalloc/src/extent.c:1195: Failed assertion: "p[i] == 0"

  [1]: https://patchwork.kernel.org/patch/10576637/

Here is a simple example that shows the problem [2]:

    // Gist to check possible issues with MADV_DONTNEED
    // For example it does not supported by qemu user
    // There is a patch for this [1], but it hasn't been applied.
    //   [1]: https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg05422.html

    #include <sys/mman.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <assert.h>
    #include <string.h>

    int main(int argc, char **argv)
    {
        void *addr = mmap(NULL, 1<<16, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
        if (addr == MAP_FAILED) {
            perror("mmap");
            return 1;
        }
        memset(addr, 'A', 1<<16);

        if (!madvise(addr, 1<<16, MADV_DONTNEED)) {
            puts("MADV_DONTNEED does not return error. Check memory.");
            for (int i = 0; i < 1<<16; ++i) {
                assert(((unsigned char *)addr)[i] == 0);
            }
        } else {
            perror("madvise");
        }

        if (munmap(addr, 1<<16)) {
            perror("munmap");
            return 1;
        }

        return 0;
    }

  ### unpatched qemu

      $ qemu-x86_64-static /tmp/test-MADV_DONTNEED
      MADV_DONTNEED does not return error. Check memory.
      test-MADV_DONTNEED: /tmp/test-MADV_DONTNEED.c:19: main: Assertion `((unsigned char *)addr)[i] == 0' failed.
      qemu: uncaught target signal 6 (Aborted) - core dumped
      Aborted (core dumped)

  ### patched qemu (by returning ENOSYS error)

      $ qemu-x86_64 /tmp/test-MADV_DONTNEED
      madvise: Success

  ### patch for qemu to return ENOSYS

      diff --git a/linux-user/syscall.c b/linux-user/syscall.c
      index 897d20c076..5540792e0e 100644
      --- a/linux-user/syscall.c
      +++ b/linux-user/syscall.c
      @@ -11775,7 +11775,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                  turns private file-backed mappings into anonymous mappings.
                  This will break MADV_DONTNEED.
                  This is a hint, so ignoring and returning success is ok.  */
      -        return 0;
      +        return ENOSYS;
       #endif
       #ifdef TARGET_NR_fcntl64
           case TARGET_NR_fcntl64:

  [2]: https://gist.github.com/azat/12ba2c825b710653ece34dba7f926ece

v2:
- review fixes
- add opt_dont_trust_madvise
v3:
- review fixes
- rename opt_dont_trust_madvise to opt_trust_madvise
2021-01-20 20:08:30 -08:00
..
2020-03-12 11:54:19 -07:00
2020-05-12 08:23:15 -07:00
2017-03-06 15:08:43 -08:00
2020-07-09 13:41:04 -07:00
2019-09-23 23:06:27 -07:00
2019-11-21 11:08:36 -08:00
2019-12-20 10:18:40 -08:00
2020-05-11 14:51:24 -07:00
2020-05-12 08:23:15 -07:00
2020-08-19 16:53:21 -07:00
2021-01-07 20:39:49 -08:00
2020-02-25 10:21:03 -08:00
2020-10-05 19:55:57 -07:00
2020-05-11 14:51:24 -07:00
2020-11-13 13:42:33 -08:00
2020-12-04 23:48:19 -08:00
2020-02-13 12:25:26 -08:00
2018-05-18 11:43:03 -07:00
2020-12-07 06:21:08 -08:00
2020-12-07 06:21:08 -08:00
2020-05-12 08:23:15 -07:00
2017-10-02 20:44:43 -07:00
2020-05-11 14:51:24 -07:00
2021-01-07 20:39:49 -08:00
2020-12-07 06:21:08 -08:00
2020-11-13 13:45:35 -08:00
2020-12-07 06:21:08 -08:00
2020-07-09 13:41:04 -07:00
2017-03-07 10:25:33 -08:00
2020-10-05 19:55:57 -07:00
2020-06-29 14:27:50 -07:00
2020-04-11 10:32:11 -07:00
2020-04-11 10:32:11 -07:00
2018-07-09 21:40:42 -07:00
2020-04-10 13:12:47 -07:00
2020-10-23 11:14:34 -07:00
2019-09-23 23:06:27 -07:00
2017-05-25 16:52:10 -07:00
2017-05-25 16:52:10 -07:00
2017-10-04 18:37:23 -07:00
2020-10-23 11:14:34 -07:00
2020-07-31 09:16:50 -07:00
2018-10-18 08:32:19 -07:00
2019-04-16 11:07:15 -07:00