util/oslib-posix: Support concurrent os_mem_prealloc() invocation
Add a mutex to protect the SIGBUS case, as we cannot mess concurrently with the sigbus handler and we have to manage the global variable sigbus_memset_context. The MADV_POPULATE_WRITE path can run concurrently. Note that page_mutex and page_cond are shared between concurrent invocations, which shouldn't be a problem. This is a preparation for future virtio-mem prealloc code, which will call os_mem_prealloc() asynchronously from an iothread when handling guest requests. Reviewed-by: Pankaj Gupta <pankaj.gupta@ionos.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20211217134611.31172-7-david@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
ac86e5c37d
commit
a960d6642d
@ -95,6 +95,7 @@ typedef struct MemsetThread MemsetThread;
|
||||
|
||||
/* used by sigbus_handler() */
|
||||
static MemsetContext *sigbus_memset_context;
|
||||
static QemuMutex sigbus_mutex;
|
||||
|
||||
static QemuMutex page_mutex;
|
||||
static QemuCond page_cond;
|
||||
@ -625,6 +626,7 @@ static bool madv_populate_write_possible(char *area, size_t pagesize)
|
||||
void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
|
||||
Error **errp)
|
||||
{
|
||||
static gsize initialized;
|
||||
int ret;
|
||||
struct sigaction act, oldact;
|
||||
size_t hpagesize = qemu_fd_getpagesize(fd);
|
||||
@ -638,6 +640,12 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
|
||||
use_madv_populate_write = madv_populate_write_possible(area, hpagesize);
|
||||
|
||||
if (!use_madv_populate_write) {
|
||||
if (g_once_init_enter(&initialized)) {
|
||||
qemu_mutex_init(&sigbus_mutex);
|
||||
g_once_init_leave(&initialized, 1);
|
||||
}
|
||||
|
||||
qemu_mutex_lock(&sigbus_mutex);
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = &sigbus_handler;
|
||||
act.sa_flags = 0;
|
||||
@ -665,6 +673,7 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
|
||||
perror("os_mem_prealloc: failed to reinstall signal handler");
|
||||
exit(1);
|
||||
}
|
||||
qemu_mutex_unlock(&sigbus_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user