public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Xiao Guangrong <guangrong.xiao@gmail.com>,
	mst@redhat.com, mtosatti@redhat.com
Cc: kvm@vger.kernel.org, quintela@redhat.com,
	Xiao Guangrong <xiaoguangrong@tencent.com>,
	qemu-devel@nongnu.org, peterx@redhat.com, dgilbert@redhat.com,
	wei.w.wang@intel.com, "Emilio G. Cota" <cota@braap.org>,
	jiang.biao2@zte.com.cn
Subject: Re: [PATCH 2/4] migration: introduce lockless multithreads model
Date: Thu, 18 Oct 2018 12:39:46 +0200	[thread overview]
Message-ID: <eccc2932-0d2f-aca5-5425-d4a04e080d2b@redhat.com> (raw)
In-Reply-To: <fb967d04-d189-5bc4-4747-27ad8342d526@gmail.com>

On 18/10/2018 11:30, Xiao Guangrong wrote:
> Beside that... i think we get the chance to remove ptr_ring gracefully,
> as the bitmap can indicate the ownership of the request as well. If
> the bit is 1 (supposing all bits are 1 on default), only the user can
> operate it, the bit will be cleared after the user fills the info
> to the request. After that, the thread sees the bit is cleared, then
> it gets the ownership and finishes the request, then sets bit in
> the bitmap. The ownership is returned to the user again.

Yes, even better. :)

> One thing may be disadvantage is, it can't differentiate the case if the
> request is empty or contains the result which need the user call
> threads_wait_done(), that will slow threads_wait_done() a little as it
> need check all requests, but it is not a big deal as
> 1) at the point needing flush, it's high possible that all most requests
>    have been used.
> 2) the total number of requests is going to be very small.

threads_wait_done only needs to check bitmap_equal for the two bitmaps,
no?  (I'm not sure if, with the code below, it would be bitmap_equal or
"all bits are different", i.e. xor is all ones.  But it's a trivial change).

> 
> It is illustrated by following code by combining the "flip" bitmaps:
> 
> struct Threads {
>    ......
> 
>    /*
>     * the bit in these two bitmaps indicates the index of the requests
>     * respectively. If it's the same, the request is owned by the user,
>     * i.e, only the use can use the request. Otherwise, it is owned by
>     * the thread.
>     */
> 
>    /* after the user fills the request, the bit is flipped. */
>    unsigned long *request_fill_bitmap QEMU_ALIGNED(SMP_CACHE_BYTES);
> 
>    /* after handles the request, the thread flips the bit. */
>    unsigned long *request_done_bitmap QEMU_ALIGNED(SMP_CACHE_BYTES);
> }

Note that the pointers need not be aligned, because they are only read.
 It's the data that should be aligned instead (qemu_memalign to allocate
it).

> threads_submit_request_prepare()
> {
>     request_done_bitmap = READ_ONCE(threads->request_done_bitmap);
>         result_bitmap = bitmap_xor(&request_done_bitmap,
> threads->request_fill_bitmap);
> 
>     index = find_first_zero_bit(current-thread-to-request-index,
> &result_bitmap);

find_next_zero_bit.

>     /* make sure we get the data the thread written. */
>         smp_rmb();
> 
>         thread_request_done(requests[index]);
>         ...
> }
> 
> threads_submit_request_commit()
> {
>         /* make sure the user have filled the request before we make it
> be viable to the threads. */
>     smp_wmb();
> 
>     /* after that, the thread can handle the request. */
>         bitmap_change_bit(request-to-index, threads->request_fill_bitmap);
>         ......
> }
> 
> In the thread, it does:
> thread_run()
> {
>     index_start = threads->requests + itself->index *
> threads->thread_ring_size;
>     index_end = index_start + threads->thread_ring_size;
> 
> loop:
>     request_fill_bitmap = READ_ONCE(threads->request_fill_bitmap);
>     request_done_bitmap = READ_ONCE(threads->request_done_bitmap);

No need for READ_ONCE (atomic_read in QEMU), as the pointers are never
written.  Technically READ_ONCE _would_ be needed in bitmap_xor.  Either
just ignore the issue or write a find_{equal,different}_bit yourself in
util/threads.c, so that it can use atomic_read.

>     result_bitmap = bitmap_xor(&request_fill_bitmap, &request_done_bitmap);
>     index = find_first_bit_set(&result_bitmap, .start = index_start,
> .end = index_end);
> 
>     /*
>          * paired with smp_wmb() in threads_submit_request_commit to
> make sure the
>          * thread can get data filled by the user.
>          */
>     smp_rmb();
> 
>     request = threads->requests[index];
>     thread_request_handler(request);
> 
>     /*
>          * updating the request is viable before flip the bitmap, paired
>          * with smp_rmb() in threads_submit_request_prepare().
>          */
>     smp_wmb();

No need for smp_wmb before atomic_xor.

>     bitmap_change_bit_atomic(&threads->request_done_bitmap, index);
>         ......
> }

  reply	other threads:[~2018-10-18 10:39 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-16 11:10 [PATCH 0/4] migration: improve multithreads guangrong.xiao
2018-10-16 11:10 ` [PATCH 1/4] ptr_ring: port ptr_ring from linux kernel to QEMU guangrong.xiao
2018-10-16 16:40   ` Emilio G. Cota
2018-10-17  8:14     ` Paolo Bonzini
2018-10-18  6:52       ` Xiao Guangrong
2018-10-16 11:10 ` [PATCH 2/4] migration: introduce lockless multithreads model guangrong.xiao
2018-10-17 10:10   ` Paolo Bonzini
2018-10-18  9:30     ` Xiao Guangrong
2018-10-18 10:39       ` Paolo Bonzini [this message]
2018-10-26 23:33     ` Emilio G. Cota
2018-10-28  7:50       ` Paolo Bonzini
2018-10-29  2:52         ` Xiao Guangrong
2018-10-16 11:10 ` [PATCH 3/4] migration: use lockless Multithread model for compression guangrong.xiao
2018-10-16 11:10 ` [PATCH 4/4] migration: use lockless Multithread model for decompression guangrong.xiao

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=eccc2932-0d2f-aca5-5425-d4a04e080d2b@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=cota@braap.org \
    --cc=dgilbert@redhat.com \
    --cc=guangrong.xiao@gmail.com \
    --cc=jiang.biao2@zte.com.cn \
    --cc=kvm@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=mtosatti@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=wei.w.wang@intel.com \
    --cc=xiaoguangrong@tencent.com \
    /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