Skip to content
Snippets Groups Projects
Commit a960d664 authored by David Hildenbrand's avatar David Hildenbrand Committed by Michael S. Tsirkin
Browse files

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: default avatarPankaj Gupta <pankaj.gupta@ionos.com>
Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
Reviewed-by: default avatarMichal Privoznik <mprivozn@redhat.com>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20211217134611.31172-7-david@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent ac86e5c3
No related branches found
No related tags found
No related merge requests found
......@@ -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);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment