qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Mark Kanda <mark.kanda@oracle.com>
To: David Hildenbrand <david@redhat.com>, qemu-devel@nongnu.org
Cc: pbonzini@redhat.com
Subject: Re: [PATCH v1 1/2] oslib-posix: refactor memory prealloc threads
Date: Mon, 8 Jan 2024 12:40:38 -0600	[thread overview]
Message-ID: <1854ecdd-88d8-462d-aa0f-990c2bbe57ff@oracle.com> (raw)
In-Reply-To: <2be78fc2-f76a-44de-8db7-fbc1bbdc0d2b@redhat.com>

On 1/8/24 9:40 AM, David Hildenbrand wrote:
> On 08.01.24 16:10, Mark Kanda wrote:
>> Refactor the memory prealloc threads support:
>> - Make memset context a global qlist
>> - Move the memset thread join/cleanup code to a separate routine
>>
>> This is functionally equivalent and facilitates multiple memset contexts
>> (used in a subsequent patch).
>>
>> Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
>> ---
>>   util/oslib-posix.c | 104 +++++++++++++++++++++++++++++----------------
>>   1 file changed, 68 insertions(+), 36 deletions(-)
>>
>> diff --git a/util/oslib-posix.c b/util/oslib-posix.c
>> index e86fd64e09..293297ac6c 100644
>> --- a/util/oslib-posix.c
>> +++ b/util/oslib-posix.c
>> @@ -63,11 +63,15 @@
>>     struct MemsetThread;
>>   +static QLIST_HEAD(, MemsetContext) memset_contexts =
>> +    QLIST_HEAD_INITIALIZER(memset_contexts);
>> +
>>   typedef struct MemsetContext {
>>       bool all_threads_created;
>>       bool any_thread_failed;
>>       struct MemsetThread *threads;
>>       int num_threads;
>> +    QLIST_ENTRY(MemsetContext) next;
>>   } MemsetContext;
>>     struct MemsetThread {
>> @@ -81,7 +85,7 @@ struct MemsetThread {
>>   typedef struct MemsetThread MemsetThread;
>>     /* used by sigbus_handler() */
>> -static MemsetContext *sigbus_memset_context;
>> +static bool sigbus_memset_context;
>>   struct sigaction sigbus_oldact;
>>   static QemuMutex sigbus_mutex;
>>   @@ -295,13 +299,16 @@ static void sigbus_handler(int signal)
>>   #endif /* CONFIG_LINUX */
>>   {
>>       int i;
>> +    MemsetContext *context;
>>         if (sigbus_memset_context) {
>> -        for (i = 0; i < sigbus_memset_context->num_threads; i++) {
>> -            MemsetThread *thread = &sigbus_memset_context->threads[i];
>> +        QLIST_FOREACH(context, &memset_contexts, next) {
>> +            for (i = 0; i < context->num_threads; i++) {
>> +                MemsetThread *thread = &context->threads[i];
>>   -            if (qemu_thread_is_self(&thread->pgthread)) {
>> -                siglongjmp(thread->env, 1);
>> +                if (qemu_thread_is_self(&thread->pgthread)) {
>> +                    siglongjmp(thread->env, 1);
>> +                }
>>               }
>>           }
>>       }
>> @@ -417,14 +424,15 @@ static int touch_all_pages(char *area, size_t 
>> hpagesize, size_t numpages,
>>                              bool use_madv_populate_write)
>>   {
>>       static gsize initialized = 0;
>> -    MemsetContext context = {
>> -        .num_threads = get_memset_num_threads(hpagesize, numpages, 
>> max_threads),
>> -    };
>> +    MemsetContext *context = g_malloc0(sizeof(MemsetContext));
>>       size_t numpages_per_thread, leftover;
>>       void *(*touch_fn)(void *);
>> -    int ret = 0, i = 0;
>> +    int i = 0;
>>       char *addr = area;
>>   +    context->num_threads =
>> +        get_memset_num_threads(hpagesize, numpages, max_threads);
>> +
>>       if (g_once_init_enter(&initialized)) {
>>           qemu_mutex_init(&page_mutex);
>>           qemu_cond_init(&page_cond);
>> @@ -433,7 +441,7 @@ static int touch_all_pages(char *area, size_t 
>> hpagesize, size_t numpages,
>>         if (use_madv_populate_write) {
>>           /* Avoid creating a single thread for MADV_POPULATE_WRITE */
>> -        if (context.num_threads == 1) {
>> +        if (context->num_threads == 1) {
>>               if (qemu_madvise(area, hpagesize * numpages,
>>                                QEMU_MADV_POPULATE_WRITE)) {
>>                   return -errno;
>> @@ -445,49 +453,74 @@ static int touch_all_pages(char *area, size_t 
>> hpagesize, size_t numpages,
>>           touch_fn = do_touch_pages;
>>       }
>>   -    context.threads = g_new0(MemsetThread, context.num_threads);
>> -    numpages_per_thread = numpages / context.num_threads;
>> -    leftover = numpages % context.num_threads;
>> -    for (i = 0; i < context.num_threads; i++) {
>> -        context.threads[i].addr = addr;
>> -        context.threads[i].numpages = numpages_per_thread + (i < 
>> leftover);
>> -        context.threads[i].hpagesize = hpagesize;
>> -        context.threads[i].context = &context;
>> +    context->threads = g_new0(MemsetThread, context->num_threads);
>> +    numpages_per_thread = numpages / context->num_threads;
>> +    leftover = numpages % context->num_threads;
>> +    for (i = 0; i < context->num_threads; i++) {
>> +        context->threads[i].addr = addr;
>> +        context->threads[i].numpages = numpages_per_thread + (i < 
>> leftover);
>> +        context->threads[i].hpagesize = hpagesize;
>> +        context->threads[i].context = context;
>>           if (tc) {
>> -            thread_context_create_thread(tc, 
>> &context.threads[i].pgthread,
>> +            thread_context_create_thread(tc, 
>> &context->threads[i].pgthread,
>>                                            "touch_pages",
>> -                                         touch_fn, &context.threads[i],
>> +                                         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_create(&context->threads[i].pgthread, "touch_pages",
>> +                               touch_fn, &context->threads[i],
>>                                  QEMU_THREAD_JOINABLE);
>>           }
>> -        addr += context.threads[i].numpages * hpagesize;
>> +        addr += context->threads[i].numpages * hpagesize;
>>       }
>>   +    QLIST_INSERT_HEAD(&memset_contexts, context, next);
>> +
>>       if (!use_madv_populate_write) {
>> -        sigbus_memset_context = &context;
>> +        sigbus_memset_context = true;
>
Thanks David,

> Could we just use the sigbus handling alone and support parallel init 
> only when using MADV_POPULATE_WRITE where we don't have to mess with 
> signal handlers?
>

Ideally, we're hoping to support this with earlier kernels which don't 
support MADV_POPULATE _WRITE. But, I will check to see if we really need it.

> Further, how do you changes interact with other callers of 
> qemu_prealloc_mem(), like virtio-mem?
>

I'm not familiar with the intricacies of virtio-mem, but the basic idea 
of this series is to *only* allow parallel init during the start up 
phase (while prealloc_init == false). Once we have parsed all the 
command line args, we set prealloc_init = true 
(wait_mem_prealloc_init()) which causes all subsequent calls to 
qemu_prealloc_mem() to perform initialization synchronously. So, I 
*think* this covers the virtio-mem use case. Am I missing something?

Thanks/regards,
-Mark


  reply	other threads:[~2024-01-08 18:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-08 15:10 [PATCH v1 0/2] Initialize backend memory objects in parallel Mark Kanda
2024-01-08 15:10 ` [PATCH v1 1/2] oslib-posix: refactor memory prealloc threads Mark Kanda
2024-01-08 15:40   ` David Hildenbrand
2024-01-08 18:40     ` Mark Kanda [this message]
2024-01-09 14:02       ` David Hildenbrand
2024-01-09 14:15         ` Daniel P. Berrangé
2024-01-09 14:25           ` David Hildenbrand
2024-01-09 18:42             ` Mark Kanda
2024-01-17 14:44             ` Mark Kanda
2024-01-17 14:51               ` David Hildenbrand
2024-01-08 15:10 ` [PATCH v1 2/2] oslib-posix: initialize backend memory objects in parallel Mark Kanda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1854ecdd-88d8-462d-aa0f-990c2bbe57ff@oracle.com \
    --to=mark.kanda@oracle.com \
    --cc=david@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).