[PATCH v2 0/7] block-copy: protect block-copy internal structures

Emanuele Giuseppe Esposito posted 7 patches 2 years, 11 months ago
Failed in applying to current master (apply log)
There is a newer version of this series
block/block-copy.c | 234 +++++++++++++++++++++++++++++----------------
1 file changed, 150 insertions(+), 84 deletions(-)
[PATCH v2 0/7] block-copy: protect block-copy internal structures
Posted by Emanuele Giuseppe Esposito 2 years, 11 months ago
This serie of patches aims to reduce the usage of the global
AioContexlock in block-copy, by introducing smaller granularity
locks thus on making the block layer thread safe. 

This serie depends on Paolo's coroutine_sleep API and my previous
serie that brings thread safety to the smaller API used by block-copy,
like ratelimit, progressmeter abd co-shared-resource.

What's missing for block-copy to be fully thread-safe is fixing
the CoSleep API to allow cross-thread sleep and wakeup.
Paolo is working on it and will post the patches once his new
CoSleep API is accepted.

Patch 1 introduces the .method field instead of .use_copy_range
and .copy_size, so that it can be later used as atomic.
Patch 2-3 provide comments and refactoring in preparation to
the locks added in patch 4 on BlockCopyTask, patch 5-6 on
BlockCopyCallState and 7 BlockCopyState.

Based-on: <20210517100548.28806-1-pbonzini@redhat.com>
Based-on: <20210518094058.25952-1-eesposit@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
v1 -> v2:
* More field categorized as IN/State/OUT in the various struct, better
  documentation in the structs
* Fix a couple of places where I missed locks [Vladimir, Paolo]


Emanuele Giuseppe Esposito (6):
  block-copy: improve documentation of BlockCopyTask and BlockCopyState
    types and functions
  block-copy: move progress_set_remaining in block_copy_task_end
  block-copy: add a CoMutex to the BlockCopyTask list
  block-copy: add QemuMutex lock for BlockCopyCallState list
  block-copy: atomic .cancelled and .finished fields in
    BlockCopyCallState
  block-copy: protect BlockCopyState .method fields

Paolo Bonzini (1):
  block-copy: streamline choice of copy_range vs. read/write

 block/block-copy.c | 234 +++++++++++++++++++++++++++++----------------
 1 file changed, 150 insertions(+), 84 deletions(-)

-- 
2.30.2


Re: [PATCH v2 0/7] block-copy: protect block-copy internal structures
Posted by Vladimir Sementsov-Ogievskiy 2 years, 11 months ago
18.05.2021 13:07, Emanuele Giuseppe Esposito wrote:
> This serie of patches aims to reduce the usage of the global
> AioContexlock in block-copy, by introducing smaller granularity
> locks thus on making the block layer thread safe.
> 
> This serie depends on Paolo's coroutine_sleep API and my previous
> serie that brings thread safety to the smaller API used by block-copy,
> like ratelimit, progressmeter abd co-shared-resource.
> 
> What's missing for block-copy to be fully thread-safe is fixing
> the CoSleep API to allow cross-thread sleep and wakeup.
> Paolo is working on it and will post the patches once his new
> CoSleep API is accepted.
> 
> Patch 1 introduces the .method field instead of .use_copy_range
> and .copy_size, so that it can be later used as atomic.
> Patch 2-3 provide comments and refactoring in preparation to
> the locks added in patch 4 on BlockCopyTask, patch 5-6 on
> BlockCopyCallState and 7 BlockCopyState.
> 
> Based-on: <20210517100548.28806-1-pbonzini@redhat.com>
> Based-on: <20210518094058.25952-1-eesposit@redhat.com>

Hi! I failed to apply this all. Could you please export your branch with your patches at some public git repo?

> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
> ---
> v1 -> v2:
> * More field categorized as IN/State/OUT in the various struct, better
>    documentation in the structs
> * Fix a couple of places where I missed locks [Vladimir, Paolo]
> 
> 
> Emanuele Giuseppe Esposito (6):
>    block-copy: improve documentation of BlockCopyTask and BlockCopyState
>      types and functions
>    block-copy: move progress_set_remaining in block_copy_task_end
>    block-copy: add a CoMutex to the BlockCopyTask list
>    block-copy: add QemuMutex lock for BlockCopyCallState list
>    block-copy: atomic .cancelled and .finished fields in
>      BlockCopyCallState
>    block-copy: protect BlockCopyState .method fields
> 
> Paolo Bonzini (1):
>    block-copy: streamline choice of copy_range vs. read/write
> 
>   block/block-copy.c | 234 +++++++++++++++++++++++++++++----------------
>   1 file changed, 150 insertions(+), 84 deletions(-)
> 


-- 
Best regards,
Vladimir

Re: [PATCH v2 0/7] block-copy: protect block-copy internal structures
Posted by Emanuele Giuseppe Esposito 2 years, 11 months ago

On 20/05/2021 15:47, Vladimir Sementsov-Ogievskiy wrote:
> 18.05.2021 13:07, Emanuele Giuseppe Esposito wrote:
>> This serie of patches aims to reduce the usage of the global
>> AioContexlock in block-copy, by introducing smaller granularity
>> locks thus on making the block layer thread safe.
>>
>> This serie depends on Paolo's coroutine_sleep API and my previous
>> serie that brings thread safety to the smaller API used by block-copy,
>> like ratelimit, progressmeter abd co-shared-resource.
>>
>> What's missing for block-copy to be fully thread-safe is fixing
>> the CoSleep API to allow cross-thread sleep and wakeup.
>> Paolo is working on it and will post the patches once his new
>> CoSleep API is accepted.
>>
>> Patch 1 introduces the .method field instead of .use_copy_range
>> and .copy_size, so that it can be later used as atomic.
>> Patch 2-3 provide comments and refactoring in preparation to
>> the locks added in patch 4 on BlockCopyTask, patch 5-6 on
>> BlockCopyCallState and 7 BlockCopyState.
>>
>> Based-on: <20210517100548.28806-1-pbonzini@redhat.com>
>> Based-on: <20210518094058.25952-1-eesposit@redhat.com>
> 
> Hi! I failed to apply this all. Could you please export your branch with 
> your patches at some public git repo?

Hi, thank you for applying the patches. My branch is here:

https://gitlab.com/eesposit/qemu/-/commits/dataplane_new

Emanuele
> 
>> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
>> ---
>> v1 -> v2:
>> * More field categorized as IN/State/OUT in the various struct, better
>>    documentation in the structs
>> * Fix a couple of places where I missed locks [Vladimir, Paolo]
>>
>>
>> Emanuele Giuseppe Esposito (6):
>>    block-copy: improve documentation of BlockCopyTask and BlockCopyState
>>      types and functions
>>    block-copy: move progress_set_remaining in block_copy_task_end
>>    block-copy: add a CoMutex to the BlockCopyTask list
>>    block-copy: add QemuMutex lock for BlockCopyCallState list
>>    block-copy: atomic .cancelled and .finished fields in
>>      BlockCopyCallState
>>    block-copy: protect BlockCopyState .method fields
>>
>> Paolo Bonzini (1):
>>    block-copy: streamline choice of copy_range vs. read/write
>>
>>   block/block-copy.c | 234 +++++++++++++++++++++++++++++----------------
>>   1 file changed, 150 insertions(+), 84 deletions(-)
>>
> 
> 


Re: [PATCH v2 0/7] block-copy: protect block-copy internal structures
Posted by Stefan Hajnoczi 2 years, 11 months ago
On Tue, May 18, 2021 at 12:07:50PM +0200, Emanuele Giuseppe Esposito wrote:
> This serie of patches aims to reduce the usage of the global
> AioContexlock in block-copy, by introducing smaller granularity
> locks thus on making the block layer thread safe. 
> 
> This serie depends on Paolo's coroutine_sleep API and my previous
> serie that brings thread safety to the smaller API used by block-copy,
> like ratelimit, progressmeter abd co-shared-resource.
> 
> What's missing for block-copy to be fully thread-safe is fixing
> the CoSleep API to allow cross-thread sleep and wakeup.
> Paolo is working on it and will post the patches once his new
> CoSleep API is accepted.
> 
> Patch 1 introduces the .method field instead of .use_copy_range
> and .copy_size, so that it can be later used as atomic.
> Patch 2-3 provide comments and refactoring in preparation to
> the locks added in patch 4 on BlockCopyTask, patch 5-6 on
> BlockCopyCallState and 7 BlockCopyState.
> 
> Based-on: <20210517100548.28806-1-pbonzini@redhat.com>
> Based-on: <20210518094058.25952-1-eesposit@redhat.com>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>

Here is my understanding of thread-safety in your
https://gitlab.com/eesposit/qemu.git dataplane_new branch:

Reading the code was much more satisfying than trying to review the
patches. That's probably because I'm not familiar with the block-copy.c
implementation and needed the context. I noticed you already addressed
some of Vladimir's comments in your git branch, so that may have helped
too.

The backup block job and the backup-top filter driver have a
BlockCopyState. QEMU threads that call bdrv_co_preadv/pwritev() invoke
the block_copy() coroutine function, so BlockCopyState needs to be
protected between threads. Additionally, the backup block job invokes
block_copy_async() to perform a background copy operation.

The relationships are as follows:

BlockCopyState - shared state that any thread can access
BlockCopyCallState - per-block_copy()/block_copy_async() state, not
                     accessed by other coroutines/threads
BlockCopyTask - per-aiotask state, find_conflicting_task_locked()
                accesses this for a given BlockCopyState

What is the purpose of the BlockCopyState->calls list?

Existing issue: the various
block_copy_call_finished/succeeded/failed/cancelled/status() APIs are a
bit extreme. They all end up being called by block/backup.c in
succession when it seems like a single call should be enough to report
the status.

It's not immediately obvious to me that BlockCopyCallState needs to be
thread-safe. So I wondered why finished needs to be atomic. Then I
realized the set_speed/cancel code runs in the monitor, so at least
block_copy_call_cancel() and block_copy_kick() need to be thread-safe. I
guess the BlockCopyCallState status APIs were made thread-safe for
consistency even though it's not needed at the moment?

Please add doc comments to block-copy.h explaining the thread-safety of
the APIs (it might be as simple as "all APIs are thread-safe" at the top
of the file).

Summarizing everything, this series adds BlockCopyState->lock to protect
shared state and makes BlockCopyCallState's status atomic so it can be
queried from threads other than the one performing the copy operation.

Stefan