Revision ef36fa14 exec.c

b/exec.c
904 904
    return fs.f_bsize;
905 905
}
906 906

  
907
static sigjmp_buf sigjump;
908

  
909
static void sigbus_handler(int signal)
910
{
911
    siglongjmp(sigjump, 1);
912
}
913

  
907 914
static void *file_ram_alloc(RAMBlock *block,
908 915
                            ram_addr_t memory,
909 916
                            const char *path)
......
913 920
    char *c;
914 921
    void *area;
915 922
    int fd;
916
#ifdef MAP_POPULATE
917
    int flags;
918
#endif
919 923
    unsigned long hpagesize;
920 924

  
921 925
    hpagesize = gethugepagesize(path);
......
963 967
    if (ftruncate(fd, memory))
964 968
        perror("ftruncate");
965 969

  
966
#ifdef MAP_POPULATE
967
    /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
968
     * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED
969
     * to sidestep this quirk.
970
     */
971
    flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
972
    area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
973
#else
974 970
    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
975
#endif
976 971
    if (area == MAP_FAILED) {
977 972
        perror("file_ram_alloc: can't mmap RAM pages");
978 973
        close(fd);
979 974
        return (NULL);
980 975
    }
976

  
977
    if (mem_prealloc) {
978
        int ret, i;
979
        struct sigaction act, oldact;
980
        sigset_t set, oldset;
981

  
982
        memset(&act, 0, sizeof(act));
983
        act.sa_handler = &sigbus_handler;
984
        act.sa_flags = 0;
985

  
986
        ret = sigaction(SIGBUS, &act, &oldact);
987
        if (ret) {
988
            perror("file_ram_alloc: failed to install signal handler");
989
            exit(1);
990
        }
991

  
992
        /* unblock SIGBUS */
993
        sigemptyset(&set);
994
        sigaddset(&set, SIGBUS);
995
        pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
996

  
997
        if (sigsetjmp(sigjump, 1)) {
998
            fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
999
            exit(1);
1000
        }
1001

  
1002
        /* MAP_POPULATE silently ignores failures */
1003
        for (i = 0; i < (memory/hpagesize)-1; i++) {
1004
            memset(area + (hpagesize*i), 0, 1);
1005
        }
1006

  
1007
        ret = sigaction(SIGBUS, &oldact, NULL);
1008
        if (ret) {
1009
            perror("file_ram_alloc: failed to reinstall signal handler");
1010
            exit(1);
1011
        }
1012

  
1013
        pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1014
    }
1015

  
981 1016
    block->fd = fd;
982 1017
    return area;
983 1018
}

Also available in: Unified diff