qemu: mempath: prefault pages manually (v4)
v4: s/fail/failed/ (Peter Maydell) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
		
							parent
							
								
									fb541ca59c
								
							
						
					
					
						commit
						ef36fa1492
					
				
							
								
								
									
										59
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								exec.c
									
									
									
									
									
								
							@ -904,6 +904,13 @@ static long gethugepagesize(const char *path)
 | 
				
			|||||||
    return fs.f_bsize;
 | 
					    return fs.f_bsize;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static sigjmp_buf sigjump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sigbus_handler(int signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    siglongjmp(sigjump, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *file_ram_alloc(RAMBlock *block,
 | 
					static void *file_ram_alloc(RAMBlock *block,
 | 
				
			||||||
                            ram_addr_t memory,
 | 
					                            ram_addr_t memory,
 | 
				
			||||||
                            const char *path)
 | 
					                            const char *path)
 | 
				
			||||||
@ -913,9 +920,6 @@ static void *file_ram_alloc(RAMBlock *block,
 | 
				
			|||||||
    char *c;
 | 
					    char *c;
 | 
				
			||||||
    void *area;
 | 
					    void *area;
 | 
				
			||||||
    int fd;
 | 
					    int fd;
 | 
				
			||||||
#ifdef MAP_POPULATE
 | 
					 | 
				
			||||||
    int flags;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    unsigned long hpagesize;
 | 
					    unsigned long hpagesize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    hpagesize = gethugepagesize(path);
 | 
					    hpagesize = gethugepagesize(path);
 | 
				
			||||||
@ -963,21 +967,52 @@ static void *file_ram_alloc(RAMBlock *block,
 | 
				
			|||||||
    if (ftruncate(fd, memory))
 | 
					    if (ftruncate(fd, memory))
 | 
				
			||||||
        perror("ftruncate");
 | 
					        perror("ftruncate");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef MAP_POPULATE
 | 
					 | 
				
			||||||
    /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
 | 
					 | 
				
			||||||
     * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED
 | 
					 | 
				
			||||||
     * to sidestep this quirk.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
 | 
					 | 
				
			||||||
    area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 | 
					    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if (area == MAP_FAILED) {
 | 
					    if (area == MAP_FAILED) {
 | 
				
			||||||
        perror("file_ram_alloc: can't mmap RAM pages");
 | 
					        perror("file_ram_alloc: can't mmap RAM pages");
 | 
				
			||||||
        close(fd);
 | 
					        close(fd);
 | 
				
			||||||
        return (NULL);
 | 
					        return (NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mem_prealloc) {
 | 
				
			||||||
 | 
					        int ret, i;
 | 
				
			||||||
 | 
					        struct sigaction act, oldact;
 | 
				
			||||||
 | 
					        sigset_t set, oldset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        memset(&act, 0, sizeof(act));
 | 
				
			||||||
 | 
					        act.sa_handler = &sigbus_handler;
 | 
				
			||||||
 | 
					        act.sa_flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ret = sigaction(SIGBUS, &act, &oldact);
 | 
				
			||||||
 | 
					        if (ret) {
 | 
				
			||||||
 | 
					            perror("file_ram_alloc: failed to install signal handler");
 | 
				
			||||||
 | 
					            exit(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* unblock SIGBUS */
 | 
				
			||||||
 | 
					        sigemptyset(&set);
 | 
				
			||||||
 | 
					        sigaddset(&set, SIGBUS);
 | 
				
			||||||
 | 
					        pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (sigsetjmp(sigjump, 1)) {
 | 
				
			||||||
 | 
					            fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
 | 
				
			||||||
 | 
					            exit(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* MAP_POPULATE silently ignores failures */
 | 
				
			||||||
 | 
					        for (i = 0; i < (memory/hpagesize)-1; i++) {
 | 
				
			||||||
 | 
					            memset(area + (hpagesize*i), 0, 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ret = sigaction(SIGBUS, &oldact, NULL);
 | 
				
			||||||
 | 
					        if (ret) {
 | 
				
			||||||
 | 
					            perror("file_ram_alloc: failed to reinstall signal handler");
 | 
				
			||||||
 | 
					            exit(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    block->fd = fd;
 | 
					    block->fd = fd;
 | 
				
			||||||
    return area;
 | 
					    return area;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -228,7 +228,6 @@ STEXI
 | 
				
			|||||||
Allocate guest RAM from a temporarily created file in @var{path}.
 | 
					Allocate guest RAM from a temporarily created file in @var{path}.
 | 
				
			||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef MAP_POPULATE
 | 
					 | 
				
			||||||
DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
 | 
					DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
 | 
				
			||||||
    "-mem-prealloc   preallocate guest memory (use with -mem-path)\n",
 | 
					    "-mem-prealloc   preallocate guest memory (use with -mem-path)\n",
 | 
				
			||||||
    QEMU_ARCH_ALL)
 | 
					    QEMU_ARCH_ALL)
 | 
				
			||||||
@ -237,7 +236,6 @@ STEXI
 | 
				
			|||||||
@findex -mem-prealloc
 | 
					@findex -mem-prealloc
 | 
				
			||||||
Preallocate memory when using -mem-path.
 | 
					Preallocate memory when using -mem-path.
 | 
				
			||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF("k", HAS_ARG, QEMU_OPTION_k,
 | 
					DEF("k", HAS_ARG, QEMU_OPTION_k,
 | 
				
			||||||
    "-k language     use keyboard layout (for example 'fr' for French)\n",
 | 
					    "-k language     use keyboard layout (for example 'fr' for French)\n",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								vl.c
									
									
									
									
									
								
							@ -188,9 +188,7 @@ static int display_remote;
 | 
				
			|||||||
const char* keyboard_layout = NULL;
 | 
					const char* keyboard_layout = NULL;
 | 
				
			||||||
ram_addr_t ram_size;
 | 
					ram_addr_t ram_size;
 | 
				
			||||||
const char *mem_path = NULL;
 | 
					const char *mem_path = NULL;
 | 
				
			||||||
#ifdef MAP_POPULATE
 | 
					 | 
				
			||||||
int mem_prealloc = 0; /* force preallocation of physical target memory */
 | 
					int mem_prealloc = 0; /* force preallocation of physical target memory */
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
int nb_nics;
 | 
					int nb_nics;
 | 
				
			||||||
NICInfo nd_table[MAX_NICS];
 | 
					NICInfo nd_table[MAX_NICS];
 | 
				
			||||||
int autostart;
 | 
					int autostart;
 | 
				
			||||||
@ -3206,11 +3204,9 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
            case QEMU_OPTION_mempath:
 | 
					            case QEMU_OPTION_mempath:
 | 
				
			||||||
                mem_path = optarg;
 | 
					                mem_path = optarg;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
#ifdef MAP_POPULATE
 | 
					 | 
				
			||||||
            case QEMU_OPTION_mem_prealloc:
 | 
					            case QEMU_OPTION_mem_prealloc:
 | 
				
			||||||
                mem_prealloc = 1;
 | 
					                mem_prealloc = 1;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            case QEMU_OPTION_d:
 | 
					            case QEMU_OPTION_d:
 | 
				
			||||||
                log_mask = optarg;
 | 
					                log_mask = optarg;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user