From nobody Sun May 19 17:58:01 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626261916157639.1944674433857; Wed, 14 Jul 2021 04:25:16 -0700 (PDT) Received: from localhost ([::1]:60482 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m3d0t-0003EK-0d for importer@patchew.org; Wed, 14 Jul 2021 07:25:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59314) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3czB-0000hV-QC for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:50399) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3cz9-0007rf-VM for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:29 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-462-wuJQd4B3Py6yQ0cBFNRkaA-1; Wed, 14 Jul 2021 07:23:23 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C4485100CCC2; Wed, 14 Jul 2021 11:23:22 +0000 (UTC) Received: from t480s.redhat.com (ovpn-114-63.ams2.redhat.com [10.36.114.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id D8F03100F49F; Wed, 14 Jul 2021 11:23:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626261807; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v9MM6B2QJGKsy+4sX43eJugclE59Bro/XzlqqeBD3bU=; b=U4WkFDGaoPxEHGsYi3HL0fGS0aw7S2gaD4UlHFobfy9yuutNgZkqkGQrCr2mjdlADukq0g Pl3SBVYTIrXks3r8Bz7hTddyaSk/XVRM0AzsaP9OrZIdIyihBxckPQewuFF8pt3mQmDfgH Iuun/gqnMvyG+Om8S5QcufHsyOT+UzY= X-MC-Unique: wuJQd4B3Py6yQ0cBFNRkaA-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v1 1/3] util/oslib-posix: Support MADV_POPULATE_WRITE for os_mem_prealloc() Date: Wed, 14 Jul 2021 13:23:04 +0200 Message-Id: <20210714112306.67793-2-david@redhat.com> In-Reply-To: <20210714112306.67793-1-david@redhat.com> References: <20210714112306.67793-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.699, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pankaj Gupta , Eduardo Habkost , "Michael S. Tsirkin" , David Hildenbrand , "Dr . David Alan Gilbert" , Igor Mammedov , Paolo Bonzini , Marek Kedzierski Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626261918484100003 Content-Type: text/plain; charset="utf-8" Let's sense support and use it for preallocation. MADV_POPULATE_WRITE does not require a SIGBUS handler, doesn't actually touch page content, and avoids context switches; it is, therefore, faster and easier to handle than our current approach. This resolves the TODO in do_touch_pages(). Signed-off-by: David Hildenbrand Reviewed-by: Pankaj Gupta --- include/qemu/osdep.h | 7 ++++ util/oslib-posix.c | 84 +++++++++++++++++++++++++++++++++----------- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 60718fc342..d1660d67fa 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -471,6 +471,11 @@ static inline void qemu_cleanup_generic_vfree(void *p) #else #define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED #endif +#ifdef MADV_POPULATE_WRITE +#define QEMU_MADV_POPULATE_WRITE MADV_POPULATE_WRITE +#else +#define QEMU_MADV_POPULATE_WRITE QEMU_MADV_INVALID +#endif =20 #elif defined(CONFIG_POSIX_MADVISE) =20 @@ -484,6 +489,7 @@ static inline void qemu_cleanup_generic_vfree(void *p) #define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID #define QEMU_MADV_NOHUGEPAGE QEMU_MADV_INVALID #define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED +#define QEMU_MADV_POPULATE_WRITE QEMU_MADV_INVALID =20 #else /* no-op */ =20 @@ -497,6 +503,7 @@ static inline void qemu_cleanup_generic_vfree(void *p) #define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID #define QEMU_MADV_NOHUGEPAGE QEMU_MADV_INVALID #define QEMU_MADV_REMOVE QEMU_MADV_INVALID +#define QEMU_MADV_POPULATE_WRITE QEMU_MADV_INVALID =20 #endif =20 diff --git a/util/oslib-posix.c b/util/oslib-posix.c index e8bdb02e1d..679796ac1f 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -484,10 +484,6 @@ static void *do_touch_pages(void *arg) * * 'volatile' to stop compiler optimizing this away * to a no-op - * - * TODO: get a better solution from kernel so we - * don't need to write at all so we don't cause - * wear on the storage backing the region... */ *(volatile char *)addr =3D *addr; addr +=3D hpagesize; @@ -497,6 +493,27 @@ static void *do_touch_pages(void *arg) return NULL; } =20 +static void *do_madv_populate_write_pages(void *arg) +{ + MemsetThread *memset_args =3D (MemsetThread *)arg; + const size_t size =3D memset_args->numpages * memset_args->hpagesize; + char * const addr =3D memset_args->addr; + int ret; + + /* See do_touch_pages(). */ + qemu_mutex_lock(&page_mutex); + while (!threads_created_flag) { + qemu_cond_wait(&page_cond, &page_mutex); + } + qemu_mutex_unlock(&page_mutex); + + ret =3D qemu_madvise(addr, size, QEMU_MADV_POPULATE_WRITE); + if (ret) { + memset_thread_failed =3D true; + } + return NULL; +} + static inline int get_memset_num_threads(int smp_cpus) { long host_procs =3D sysconf(_SC_NPROCESSORS_ONLN); @@ -510,10 +527,11 @@ static inline int get_memset_num_threads(int smp_cpus) } =20 static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, - int smp_cpus) + int smp_cpus, bool use_madv_populate_write) { static gsize initialized =3D 0; size_t numpages_per_thread, leftover; + void *(*touch_fn)(void *); char *addr =3D area; int i =3D 0; =20 @@ -523,6 +541,12 @@ static bool touch_all_pages(char *area, size_t hpagesi= ze, size_t numpages, g_once_init_leave(&initialized, 1); } =20 + if (use_madv_populate_write) { + touch_fn =3D do_madv_populate_write_pages; + } else { + touch_fn =3D do_touch_pages; + } + memset_thread_failed =3D false; threads_created_flag =3D false; memset_num_threads =3D get_memset_num_threads(smp_cpus); @@ -534,7 +558,7 @@ static bool touch_all_pages(char *area, size_t hpagesiz= e, size_t numpages, memset_thread[i].numpages =3D numpages_per_thread + (i < leftover); memset_thread[i].hpagesize =3D hpagesize; qemu_thread_create(&memset_thread[i].pgthread, "touch_pages", - do_touch_pages, &memset_thread[i], + touch_fn, &memset_thread[i], QEMU_THREAD_JOINABLE); addr +=3D memset_thread[i].numpages * hpagesize; } @@ -553,6 +577,12 @@ static bool touch_all_pages(char *area, size_t hpagesi= ze, size_t numpages, return memset_thread_failed; } =20 +static bool madv_populate_write_possible(char *area, size_t pagesize) +{ + return !qemu_madvise(area, pagesize, QEMU_MADV_POPULATE_WRITE) || + errno !=3D EINVAL; +} + void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, Error **errp) { @@ -560,29 +590,43 @@ void os_mem_prealloc(int fd, char *area, size_t memor= y, int smp_cpus, struct sigaction act, oldact; size_t hpagesize =3D qemu_fd_getpagesize(fd); size_t numpages =3D DIV_ROUND_UP(memory, hpagesize); + bool use_madv_populate_write; + + /* + * Sense on every invocation, as MADV_POPULATE_WRITE cannot be used for + * some special mappings, such as mapping /dev/mem. + */ + if (madv_populate_write_possible(area, hpagesize)) { + use_madv_populate_write =3D true; + } =20 - memset(&act, 0, sizeof(act)); - act.sa_handler =3D &sigbus_handler; - act.sa_flags =3D 0; + if (!use_madv_populate_write) { + memset(&act, 0, sizeof(act)); + act.sa_handler =3D &sigbus_handler; + act.sa_flags =3D 0; =20 - ret =3D sigaction(SIGBUS, &act, &oldact); - if (ret) { - error_setg_errno(errp, errno, - "os_mem_prealloc: failed to install signal handler"); - return; + ret =3D sigaction(SIGBUS, &act, &oldact); + if (ret) { + error_setg_errno(errp, errno, + "os_mem_prealloc: failed to install signal handler"); + return; + } } =20 /* touch pages simultaneously */ - if (touch_all_pages(area, hpagesize, numpages, smp_cpus)) { + if (touch_all_pages(area, hpagesize, numpages, smp_cpus, + use_madv_populate_write)) { error_setg(errp, "os_mem_prealloc: Insufficient free host memory " "pages available to allocate guest RAM"); } =20 - ret =3D sigaction(SIGBUS, &oldact, NULL); - if (ret) { - /* Terminate QEMU since it can't recover from error */ - perror("os_mem_prealloc: failed to reinstall signal handler"); - exit(1); + if (!use_madv_populate_write) { + ret =3D sigaction(SIGBUS, &oldact, NULL); + if (ret) { + /* Terminate QEMU since it can't recover from error */ + perror("os_mem_prealloc: failed to reinstall signal handler"); + exit(1); + } } } =20 --=20 2.31.1 From nobody Sun May 19 17:58:01 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626261915419444.649223612201; Wed, 14 Jul 2021 04:25:15 -0700 (PDT) Received: from localhost ([::1]:60484 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m3d0s-0003EL-78 for importer@patchew.org; Wed, 14 Jul 2021 07:25:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59316) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3czC-0000i5-35 for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:27872) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3czA-0007rk-Ap for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:29 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-353-TudpkQdEPtGqBXSxKjJO0A-1; Wed, 14 Jul 2021 07:23:26 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6FF478042DE; Wed, 14 Jul 2021 11:23:25 +0000 (UTC) Received: from t480s.redhat.com (ovpn-114-63.ams2.redhat.com [10.36.114.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2C10A1001281; Wed, 14 Jul 2021 11:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626261807; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=isMNh9Zy3pmtK90KwW4EyEyvo40SNqRnAyWu0aw6gfk=; b=ctYl70JDlFW8GwAgb4kCVZQ5WMNdoZZ+P1wDXYhfoWvGvJBIwxymDUU+3Hw6aaSlqstBrE 1xaSQboL0QtNDvwxmC0/x70ztDuVHyE9bQAhP70zqNHJ76Ow+s7DMfWicVTJpk61tVOVpK IfDRkzAkkiDYPxhfYKageOymuqnIbn0= X-MC-Unique: TudpkQdEPtGqBXSxKjJO0A-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v1 2/3] util/oslib-posix: Introduce and use MemsetContext for touch_all_pages() Date: Wed, 14 Jul 2021 13:23:05 +0200 Message-Id: <20210714112306.67793-3-david@redhat.com> In-Reply-To: <20210714112306.67793-1-david@redhat.com> References: <20210714112306.67793-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.699, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pankaj Gupta , Eduardo Habkost , "Michael S. Tsirkin" , David Hildenbrand , "Dr . David Alan Gilbert" , Igor Mammedov , Paolo Bonzini , Marek Kedzierski Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626261916730100001 Content-Type: text/plain; charset="utf-8" Let's minimize the number of global variables to prepare for os_mem_prealloc() getting called concurrently and make the code a bit easier to read. The only consumer that really needs a global variable is the sigbus handler, which will require protection via a mutex in the future either way as we cannot concurrently mess with the SIGBUS handler. Signed-off-by: David Hildenbrand Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Pankaj Gupta --- util/oslib-posix.c | 81 ++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 679796ac1f..60d1da2d6c 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -73,22 +73,30 @@ =20 #define MAX_MEM_PREALLOC_THREAD_COUNT 16 =20 +struct MemsetThread; + +typedef struct MemsetContext { + bool all_threads_created; + bool any_thread_failed; + struct MemsetThread *threads; + int num_threads; +} MemsetContext; + struct MemsetThread { char *addr; size_t numpages; size_t hpagesize; QemuThread pgthread; sigjmp_buf env; + MemsetContext *context; }; typedef struct MemsetThread MemsetThread; =20 -static MemsetThread *memset_thread; -static int memset_num_threads; -static bool memset_thread_failed; +/* used by sigbus_handler() */ +static MemsetContext *sigbus_memset_context; =20 static QemuMutex page_mutex; static QemuCond page_cond; -static bool threads_created_flag; =20 int qemu_get_thread_id(void) { @@ -439,10 +447,13 @@ const char *qemu_get_exec_dir(void) static void sigbus_handler(int signal) { int i; - if (memset_thread) { - for (i =3D 0; i < memset_num_threads; i++) { - if (qemu_thread_is_self(&memset_thread[i].pgthread)) { - siglongjmp(memset_thread[i].env, 1); + + if (sigbus_memset_context) { + for (i =3D 0; i < sigbus_memset_context->num_threads; i++) { + MemsetThread *thread =3D &sigbus_memset_context->threads[i]; + + if (qemu_thread_is_self(&thread->pgthread)) { + siglongjmp(thread->env, 1); } } } @@ -459,7 +470,7 @@ static void *do_touch_pages(void *arg) * clearing until all threads have been created. */ qemu_mutex_lock(&page_mutex); - while(!threads_created_flag){ + while (!memset_args->context->all_threads_created) { qemu_cond_wait(&page_cond, &page_mutex); } qemu_mutex_unlock(&page_mutex); @@ -470,7 +481,7 @@ static void *do_touch_pages(void *arg) pthread_sigmask(SIG_UNBLOCK, &set, &oldset); =20 if (sigsetjmp(memset_args->env, 1)) { - memset_thread_failed =3D true; + memset_args->context->any_thread_failed =3D true; } else { char *addr =3D memset_args->addr; size_t numpages =3D memset_args->numpages; @@ -502,14 +513,14 @@ static void *do_madv_populate_write_pages(void *arg) =20 /* See do_touch_pages(). */ qemu_mutex_lock(&page_mutex); - while (!threads_created_flag) { + while (!memset_args->context->all_threads_created) { qemu_cond_wait(&page_cond, &page_mutex); } qemu_mutex_unlock(&page_mutex); =20 ret =3D qemu_madvise(addr, size, QEMU_MADV_POPULATE_WRITE); if (ret) { - memset_thread_failed =3D true; + memset_args->context->any_thread_failed =3D true; } return NULL; } @@ -530,6 +541,9 @@ static bool touch_all_pages(char *area, size_t hpagesiz= e, size_t numpages, int smp_cpus, bool use_madv_populate_write) { static gsize initialized =3D 0; + MemsetContext context =3D { + .num_threads =3D get_memset_num_threads(smp_cpus), + }; size_t numpages_per_thread, leftover; void *(*touch_fn)(void *); char *addr =3D area; @@ -547,34 +561,39 @@ static bool touch_all_pages(char *area, size_t hpages= ize, size_t numpages, touch_fn =3D do_touch_pages; } =20 - memset_thread_failed =3D false; - threads_created_flag =3D false; - memset_num_threads =3D get_memset_num_threads(smp_cpus); - memset_thread =3D g_new0(MemsetThread, memset_num_threads); - numpages_per_thread =3D numpages / memset_num_threads; - leftover =3D numpages % memset_num_threads; - for (i =3D 0; i < memset_num_threads; i++) { - memset_thread[i].addr =3D addr; - memset_thread[i].numpages =3D numpages_per_thread + (i < leftover); - memset_thread[i].hpagesize =3D hpagesize; - qemu_thread_create(&memset_thread[i].pgthread, "touch_pages", - touch_fn, &memset_thread[i], + context.threads =3D g_new0(MemsetThread, context.num_threads); + numpages_per_thread =3D numpages / context.num_threads; + leftover =3D numpages % context.num_threads; + for (i =3D 0; i < context.num_threads; i++) { + context.threads[i].addr =3D addr; + context.threads[i].numpages =3D numpages_per_thread + (i < leftove= r); + context.threads[i].hpagesize =3D hpagesize; + context.threads[i].context =3D &context; + qemu_thread_create(&context.threads[i].pgthread, "touch_pages", + touch_fn, &context.threads[i], QEMU_THREAD_JOINABLE); - addr +=3D memset_thread[i].numpages * hpagesize; + addr +=3D context.threads[i].numpages * hpagesize; + } + + if (!use_madv_populate_write) { + sigbus_memset_context =3D &context; } =20 qemu_mutex_lock(&page_mutex); - threads_created_flag =3D true; + context.all_threads_created =3D true; qemu_cond_broadcast(&page_cond); qemu_mutex_unlock(&page_mutex); =20 - for (i =3D 0; i < memset_num_threads; i++) { - qemu_thread_join(&memset_thread[i].pgthread); + for (i =3D 0; i < context.num_threads; i++) { + qemu_thread_join(&context.threads[i].pgthread); + } + + if (!use_madv_populate_write) { + sigbus_memset_context =3D NULL; } - g_free(memset_thread); - memset_thread =3D NULL; + g_free(context.threads); =20 - return memset_thread_failed; + return context.any_thread_failed; } =20 static bool madv_populate_write_possible(char *area, size_t pagesize) --=20 2.31.1 From nobody Sun May 19 17:58:01 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1626261940304288.38360736925574; Wed, 14 Jul 2021 04:25:40 -0700 (PDT) Received: from localhost ([::1]:33350 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m3d1H-0003xz-8O for importer@patchew.org; Wed, 14 Jul 2021 07:25:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59354) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3czN-0001GN-IK for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:56077) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m3czL-0007zb-SD for qemu-devel@nongnu.org; Wed, 14 Jul 2021 07:23:41 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-376-mxaYE6vXNtWTWARBu8ZaSg-1; Wed, 14 Jul 2021 07:23:36 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 15C47100CF6E; Wed, 14 Jul 2021 11:23:35 +0000 (UTC) Received: from t480s.redhat.com (ovpn-114-63.ams2.redhat.com [10.36.114.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id CD2561001281; Wed, 14 Jul 2021 11:23:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1626261819; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=d8Ju46ooO+LpOYtWfQ0zrbry10jP0PKilFnn/DoA13E=; b=gqggPKPJ9vLqdPYfWTnHJZPNTI/u/BHZy53K6Y3vjaAlxzWnj3mj09gV2wbRB4fwUAY11R DAgg54pU7Oy60h/9qq2y0OTl0R7JY5GJMMqknNd7IuOYDCbW+2410Jm7M+DcecHJEvhLmc IBnIQoDV5z63kXyPbJLvnXJSgek8pGI= X-MC-Unique: mxaYE6vXNtWTWARBu8ZaSg-1 From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v1 3/3] util/oslib-posix: Support concurrent os_mem_prealloc() invocation Date: Wed, 14 Jul 2021 13:23:06 +0200 Message-Id: <20210714112306.67793-4-david@redhat.com> In-Reply-To: <20210714112306.67793-1-david@redhat.com> References: <20210714112306.67793-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=david@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.699, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pankaj Gupta , Eduardo Habkost , "Michael S. Tsirkin" , David Hildenbrand , "Dr . David Alan Gilbert" , Igor Mammedov , Paolo Bonzini , Marek Kedzierski Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1626261942031100005 Content-Type: text/plain; charset="utf-8" Add a mutext 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. Signed-off-by: David Hildenbrand Reviewed-by: Pankaj Gupta --- util/oslib-posix.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 60d1da2d6c..181f6bbf1a 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -94,6 +94,7 @@ typedef struct MemsetThread MemsetThread; =20 /* used by sigbus_handler() */ static MemsetContext *sigbus_memset_context; +static QemuMutex sigbus_mutex; =20 static QemuMutex page_mutex; static QemuCond page_cond; @@ -605,12 +606,17 @@ 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 =3D qemu_fd_getpagesize(fd); size_t numpages =3D DIV_ROUND_UP(memory, hpagesize); bool use_madv_populate_write; =20 + if (g_once_init_enter(&initialized)) { + qemu_mutex_init(&sigbus_mutex); + } + /* * Sense on every invocation, as MADV_POPULATE_WRITE cannot be used for * some special mappings, such as mapping /dev/mem. @@ -620,6 +626,7 @@ void os_mem_prealloc(int fd, char *area, size_t memory,= int smp_cpus, } =20 if (!use_madv_populate_write) { + qemu_mutex_lock(&sigbus_mutex); memset(&act, 0, sizeof(act)); act.sa_handler =3D &sigbus_handler; act.sa_flags =3D 0; @@ -646,6 +653,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); } } =20 --=20 2.31.1