summaryrefslogtreecommitdiffstats
path: root/util/oslib-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/oslib-posix.c')
-rw-r--r--util/oslib-posix.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 827a7aadba..59a891b6a8 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -42,6 +42,7 @@
#include "qemu/cutils.h"
#include "qemu/compiler.h"
#include "qemu/units.h"
+#include "qemu/thread-context.h"
#ifdef CONFIG_LINUX
#include <sys/syscall.h>
@@ -329,7 +330,7 @@ static void sigbus_handler(int signal)
return;
}
#endif /* CONFIG_LINUX */
- warn_report("os_mem_prealloc: unrelated SIGBUS detected and ignored");
+ warn_report("qemu_prealloc_mem: unrelated SIGBUS detected and ignored");
}
static void *do_touch_pages(void *arg)
@@ -399,13 +400,13 @@ static void *do_madv_populate_write_pages(void *arg)
}
static inline int get_memset_num_threads(size_t hpagesize, size_t numpages,
- int smp_cpus)
+ int max_threads)
{
long host_procs = sysconf(_SC_NPROCESSORS_ONLN);
int ret = 1;
if (host_procs > 0) {
- ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), smp_cpus);
+ ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), max_threads);
}
/* Especially with gigantic pages, don't create more threads than pages. */
@@ -418,11 +419,12 @@ static inline int get_memset_num_threads(size_t hpagesize, size_t numpages,
}
static int touch_all_pages(char *area, size_t hpagesize, size_t numpages,
- int smp_cpus, bool use_madv_populate_write)
+ int max_threads, ThreadContext *tc,
+ bool use_madv_populate_write)
{
static gsize initialized = 0;
MemsetContext context = {
- .num_threads = get_memset_num_threads(hpagesize, numpages, smp_cpus),
+ .num_threads = get_memset_num_threads(hpagesize, numpages, max_threads),
};
size_t numpages_per_thread, leftover;
void *(*touch_fn)(void *);
@@ -457,9 +459,16 @@ static int touch_all_pages(char *area, size_t hpagesize, size_t numpages,
context.threads[i].numpages = numpages_per_thread + (i < leftover);
context.threads[i].hpagesize = hpagesize;
context.threads[i].context = &context;
- qemu_thread_create(&context.threads[i].pgthread, "touch_pages",
- touch_fn, &context.threads[i],
- QEMU_THREAD_JOINABLE);
+ if (tc) {
+ thread_context_create_thread(tc, &context.threads[i].pgthread,
+ "touch_pages",
+ touch_fn, &context.threads[i],
+ QEMU_THREAD_JOINABLE);
+ } else {
+ qemu_thread_create(&context.threads[i].pgthread, "touch_pages",
+ touch_fn, &context.threads[i],
+ QEMU_THREAD_JOINABLE);
+ }
addr += context.threads[i].numpages * hpagesize;
}
@@ -494,13 +503,13 @@ static bool madv_populate_write_possible(char *area, size_t pagesize)
errno != EINVAL;
}
-void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
- Error **errp)
+void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
+ ThreadContext *tc, Error **errp)
{
static gsize initialized;
int ret;
size_t hpagesize = qemu_fd_getpagesize(fd);
- size_t numpages = DIV_ROUND_UP(memory, hpagesize);
+ size_t numpages = DIV_ROUND_UP(sz, hpagesize);
bool use_madv_populate_write;
struct sigaction act;
@@ -530,24 +539,24 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
if (ret) {
qemu_mutex_unlock(&sigbus_mutex);
error_setg_errno(errp, errno,
- "os_mem_prealloc: failed to install signal handler");
+ "qemu_prealloc_mem: failed to install signal handler");
return;
}
}
/* touch pages simultaneously */
- ret = touch_all_pages(area, hpagesize, numpages, smp_cpus,
+ ret = touch_all_pages(area, hpagesize, numpages, max_threads, tc,
use_madv_populate_write);
if (ret) {
error_setg_errno(errp, -ret,
- "os_mem_prealloc: preallocating memory failed");
+ "qemu_prealloc_mem: preallocating memory failed");
}
if (!use_madv_populate_write) {
ret = sigaction(SIGBUS, &sigbus_oldact, NULL);
if (ret) {
/* Terminate QEMU since it can't recover from error */
- perror("os_mem_prealloc: failed to reinstall signal handler");
+ perror("qemu_prealloc_mem: failed to reinstall signal handler");
exit(1);
}
qemu_mutex_unlock(&sigbus_mutex);