All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: Emanuele Giuseppe Esposito <eesposit@redhat.com>, qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Eric Blake <eblake@redhat.com>,
	qemu-devel@nongnu.org
Subject: Re: [PATCH v4 6/6] blkdebug: protect rules and suspended_reqs with a lock
Date: Sat, 5 Jun 2021 22:40:47 +0300	[thread overview]
Message-ID: <27f7888a-2b11-08e1-ac2a-c7a8dda5ab21@virtuozzo.com> (raw)
In-Reply-To: <763e2193-6505-016b-227a-490ad0119336@redhat.com>

05.06.2021 20:53, Emanuele Giuseppe Esposito wrote:
> 
> 
> On 05/06/2021 17:15, Vladimir Sementsov-Ogievskiy wrote:
>> 04.06.2021 13:07, Emanuele Giuseppe Esposito wrote:
>>> First, categorize the structure fields to identify what needs
>>> to be protected and what doesn't.
>>>
>>> We essentially need to protect only .state, and the 3 lists in
>>> BDRVBlkdebugState.
>>>
>>> Then, add the lock and mark the functions accordingly.
>>>
>>> Co-developed-by: Paolo Bonzini <pbonzini@redhat.com>
>>> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
>>> ---
>>>   block/blkdebug.c | 46 +++++++++++++++++++++++++++++++++++-----------
>>>   1 file changed, 35 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/block/blkdebug.c b/block/blkdebug.c
>>> index d597753139..ac3799f739 100644
>>> --- a/block/blkdebug.c
>>> +++ b/block/blkdebug.c
>>> @@ -38,24 +38,27 @@
>>>   #include "qapi/qobject-input-visitor.h"
>>>   #include "sysemu/qtest.h"
>>> +/* All APIs are thread-safe */
>>> +
>>>   typedef struct BDRVBlkdebugState {
>>> -    int state;
>>> +    /* IN: initialized in blkdebug_open() and never changed */
>>>       uint64_t align;
>>>       uint64_t max_transfer;
>>>       uint64_t opt_write_zero;
>>>       uint64_t max_write_zero;
>>>       uint64_t opt_discard;
>>>       uint64_t max_discard;
>>> -
>>> +    char *config_file; /* For blkdebug_refresh_filename() */
>>> +    /* initialized in blkdebug_parse_perms() */
>>>       uint64_t take_child_perms;
>>>       uint64_t unshare_child_perms;
>>> -    /* For blkdebug_refresh_filename() */
>>> -    char *config_file;
>>> -
>>> +    /* State. Protected by lock */
>>> +    int state;
>>>       QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX];
>>>       QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
>>>       QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
>>> +    QemuMutex lock;
>>>   } BDRVBlkdebugState;
>>>   typedef struct BlkdebugAIOCB {
>>> @@ -64,6 +67,7 @@ typedef struct BlkdebugAIOCB {
>>>   } BlkdebugAIOCB;
>>>   typedef struct BlkdebugSuspendedReq {
>>> +    /* IN: initialized in suspend_request() */
>>>       Coroutine *co;
>>>       char *tag;
>>
>> @next is part of *suspended_reqs list (in a manner), so it should be protected by lock
>>
>>>       QLIST_ENTRY(BlkdebugSuspendedReq) next;
>>> @@ -77,6 +81,7 @@ enum {
>>>   };
>>>   typedef struct BlkdebugRule {
>>> +    /* IN: initialized in add_rule() or blkdebug_debug_breakpoint() */
>>>       BlkdebugEvent event;
>>>       int action;
>>>       int state;
>>
>> as well as @next and @active_next here.
> 
> They all are already protected by the lock, I will just update the comments in case I need to re-spin.
> 
> [...]
> 
>>
>> Optional suggestion for additional comments and more use of QEMU_LOCK_GUARD (it looks large because of indentation change):
> 
> Exactly, indentation change. If I recall correctly, you (rightly) complained about that in one of my patches (not sure if it was in this series).

Probably here, indentation doesn't become so big :)

Maximum is

WITH_ () {
   FOR {
      if {
         ***

And this if contains only one simple "break".

Of course, that's a kind of taste. I hope I was not too insistent that past time.

> 
>>
>> diff --git a/block/blkdebug.c b/block/blkdebug.c
>> index ac3799f739..b4f8844e76 100644
>> --- a/block/blkdebug.c
>> +++ b/block/blkdebug.c
>> @@ -70,6 +70,8 @@ typedef struct BlkdebugSuspendedReq {
>>       /* IN: initialized in suspend_request() */
>>       Coroutine *co;
>>       char *tag;
>> +
>> +    /* List entry protected BDRVBlkdebugState::lock */
> 
> Is this C++ style ok to be used here? I don't think I have seen it used in QEMU. But I might be wrong, someone with better style taste and experience should comment here. Maybe it's better to have
> 
> /* List entry protected BDRVBlkdebugState's lock */

OK for me, I don't care)

Hmm, looking at git log, I see :: syntax in my commits. And not only my.

> 
>>       QLIST_ENTRY(BlkdebugSuspendedReq) next;
>>   } BlkdebugSuspendedReq;
>>
>> @@ -100,6 +102,8 @@ typedef struct BlkdebugRule {
>>               char *tag;
>>           } suspend;
>>       } options;
>> +
>> +    /* List entries protected BDRVBlkdebugState::lock */
>>       QLIST_ENTRY(BlkdebugRule) next;
>>       QSIMPLEQ_ENTRY(BlkdebugRule) active_next;
>>   } BlkdebugRule;
>> @@ -249,9 +253,9 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
>>       };
>>
>>       /* Add the rule */
>> -    qemu_mutex_lock(&s->lock);
>> -    QLIST_INSERT_HEAD(&s->rules[event], rule, next);
>> -    qemu_mutex_unlock(&s->lock);
>> +    WITH_QEMU_LOCK_GUARD(&s->lock) {
>> +        QLIST_INSERT_HEAD(&s->rules[event], rule, next);
>> +    }
> Same lines used, just additional indentation added. For one line it might be okay? not sure.

Same three lines, but don't need to call _unlock()..

I think, for last time I just get used to the thought that WITH_QEMU_LOCK_GUARD(){} is a good thing.

Here it's really doesn't make real sense. So, take the suggestion only if you like it, my r-b stands without it as well.

>>
>>       return 0;
>>   }
>> @@ -591,33 +595,32 @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
>>       int error;
>>       bool immediately;
>>
>> -    qemu_mutex_lock(&s->lock);
>> -    QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
>> -        uint64_t inject_offset = rule->options.inject.offset;
>> -
>> -        if ((inject_offset == -1 ||
>> -             (bytes && inject_offset >= offset &&
>> -              inject_offset < offset + bytes)) &&
>> -            (rule->options.inject.iotype_mask & (1ull << iotype)))
>> -        {
>> -            break;
>> +    WITH_QEMU_LOCK_GUARD(&s->lock) {
>> +        QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
>> +            uint64_t inject_offset = rule->options.inject.offset;
>> +
>> +            if ((inject_offset == -1 ||
>> +                 (bytes && inject_offset >= offset &&
>> +                  inject_offset < offset + bytes)) &&
>> +                (rule->options.inject.iotype_mask & (1ull << iotype)))
>> +            {
>> +                break;
>> +            }
>>           }
>> -    }
>>
>> -    if (!rule || !rule->options.inject.error) {
>> -        qemu_mutex_unlock(&s->lock);
>> -        return 0;
>> -    }
>> +        if (!rule || !rule->options.inject.error) {
>> +            return 0;
>> +        }
>>
>> -    immediately = rule->options.inject.immediately;
>> -    error = rule->options.inject.error;
>> +        immediately = rule->options.inject.immediately;
>> +        error = rule->options.inject.error;
>>
>> -    if (rule->options.inject.once) {
>> -        QSIMPLEQ_REMOVE(&s->active_rules, rule, BlkdebugRule, active_next);
>> -        remove_rule(rule);
>> +        if (rule->options.inject.once) {
>> +            QSIMPLEQ_REMOVE(&s->active_rules, rule, BlkdebugRule, active_next);
>> +            remove_rule(rule);
>> +        }
>>       }
>>
>> -    qemu_mutex_unlock(&s->lock);
> 
> Too much indentation added for a couple of lock/unlock IMO.
> 
>>       if (!immediately) {
>>           aio_co_schedule(qemu_get_current_aio_context(), qemu_coroutine_self());
>>           qemu_coroutine_yield();
>> @@ -880,9 +883,9 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
>>           .options.suspend.tag = g_strdup(tag),
>>       };
>>
>> -    qemu_mutex_lock(&s->lock);
>> -    QLIST_INSERT_HEAD(&s->rules[blkdebug_event], rule, next);
>> -    qemu_mutex_unlock(&s->lock);
>> +    WITH_QEMU_LOCK_GUARD(&s->lock) {
>> +        QLIST_INSERT_HEAD(&s->rules[blkdebug_event], rule, next);
>> +    }
> 
> Same as above.
> 
> Thank you,
> Emanuele
> 


-- 
Best regards,
Vladimir


  reply	other threads:[~2021-06-05 19:41 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-04 10:07 [PATCH v4 0/6] blkdebug: fix racing condition when iterating on Emanuele Giuseppe Esposito
2021-06-04 10:07 ` [PATCH v4 1/6] blkdebug: refactor removal of a suspended request Emanuele Giuseppe Esposito
2021-06-04 16:16   ` Eric Blake
2021-06-07  9:23     ` Paolo Bonzini
2021-06-08  8:00       ` Emanuele Giuseppe Esposito
2021-06-08 14:16         ` Eric Blake
2021-06-04 10:07 ` [PATCH v4 2/6] blkdebug: move post-resume handling to resume_req_by_tag Emanuele Giuseppe Esposito
2021-06-04 10:07 ` [PATCH v4 3/6] blkdebug: track all actions Emanuele Giuseppe Esposito
2021-06-04 10:07 ` [PATCH v4 4/6] blkdebug: do not suspend in the middle of QLIST_FOREACH_SAFE Emanuele Giuseppe Esposito
2021-06-04 10:07 ` [PATCH v4 5/6] block/blkdebug: remove new_state field and instead use a local variable Emanuele Giuseppe Esposito
2021-06-05 14:32   ` Vladimir Sementsov-Ogievskiy
2021-06-04 10:07 ` [PATCH v4 6/6] blkdebug: protect rules and suspended_reqs with a lock Emanuele Giuseppe Esposito
2021-06-05 15:15   ` Vladimir Sementsov-Ogievskiy
2021-06-05 17:53     ` Emanuele Giuseppe Esposito
2021-06-05 19:40       ` Vladimir Sementsov-Ogievskiy [this message]
2021-06-07  9:29   ` Paolo Bonzini

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=27f7888a-2b11-08e1-ac2a-c7a8dda5ab21@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=eblake@redhat.com \
    --cc=eesposit@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.