All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
To: Emanuele Giuseppe Esposito <eesposit@redhat.com>, qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>, John Snow <jsnow@redhat.com>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	Wen Congyang <wencongyang2@huawei.com>,
	Xie Changlong <xiechanglong.d@gmail.com>,
	Markus Armbruster <armbru@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>, Fam Zheng <fam@euphon.net>,
	qemu-devel@nongnu.org
Subject: Re: [PATCH v8 08/20] blockjob.h: introduce block_job _locked() APIs
Date: Wed, 6 Jul 2022 15:23:25 +0300	[thread overview]
Message-ID: <a48ea347-3a44-28c7-b154-ce3dadbae23c@yandex-team.ru> (raw)
In-Reply-To: <95c3dae0-a8dd-1ec6-0ba1-5a4b1e92c1a3@redhat.com>

On 7/6/22 15:05, Emanuele Giuseppe Esposito wrote:
> 
> 
> Am 05/07/2022 um 17:01 schrieb Vladimir Sementsov-Ogievskiy:
>> On 6/29/22 17:15, Emanuele Giuseppe Esposito wrote:
>>> Just as done with job.h, create _locked() functions in blockjob.h
>>
>> We modify not only blockjob.h, I'd s/blockjob.h/blockjob/ in subject.
>>
>> Also, we start to introduce _locked block_job_* APIs.
>>
>> Does it mean that BlockJob and Job share the global mutex to protect
>> themselves? Than I think we should document in BlockJob struct what is
>> protected by job_mutex.
> 
> There is nothing in the struct (apart from Job) that is protected by the
> job lock. I can add a comment "Protected by job mutex" on top of Job job
> field?

Yes, I think that's worth doing.

Other fields doesn't need the lock?

> 
>>
>> And please, let's be consistent on whether we add or not add "with mutex
>> held" / "with mutex not held" comments. For job API you mostly add it
>> for each function.. Let's do same here? Same for "temporary unlock"
>> comments.
> 
> Where did I miss the mutex lock/unlock comments? Yes I forgot the
> "temporary unlock" thing but apart from that all functions have a
> comment saying if they take the lock or not.

Probably that's my impression because you add some comments in separate patches. OK.

> 
>>
>>>
>>> These functions will be later useful when caller has already taken
>>> the lock. All blockjob _locked functions call job _locked functions.
>>>
>>> Note: at this stage, job_{lock/unlock} and job lock guard macros
>>> are *nop*.
>>>
>>> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
>>> ---
>>>    blockjob.c               | 52 ++++++++++++++++++++++++++++++++--------
>>>    include/block/blockjob.h | 15 ++++++++++++
>>>    2 files changed, 57 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/blockjob.c b/blockjob.c
>>> index 7da59a1f1c..0d59aba439 100644
>>> --- a/blockjob.c
>>> +++ b/blockjob.c
>>> @@ -44,21 +44,27 @@ static bool is_block_job(Job *job)
>>>               job_type(job) == JOB_TYPE_STREAM;
>>>    }
>>>    -BlockJob *block_job_next(BlockJob *bjob)
>>> +BlockJob *block_job_next_locked(BlockJob *bjob)
>>>    {
>>>        Job *job = bjob ? &bjob->job : NULL;
>>>        GLOBAL_STATE_CODE();
>>>          do {
>>> -        job = job_next(job);
>>> +        job = job_next_locked(job);
>>>        } while (job && !is_block_job(job));
>>>          return job ? container_of(job, BlockJob, job) : NULL;
>>>    }
>>>    -BlockJob *block_job_get(const char *id)
>>> +BlockJob *block_job_next(BlockJob *bjob)
>>>    {
>>> -    Job *job = job_get(id);
>>> +    JOB_LOCK_GUARD();
>>> +    return block_job_next_locked(bjob);
>>> +}
>>> +
>>> +BlockJob *block_job_get_locked(const char *id)
>>> +{
>>> +    Job *job = job_get_locked(id);
>>>        GLOBAL_STATE_CODE();
>>>          if (job && is_block_job(job)) {
>>> @@ -68,6 +74,12 @@ BlockJob *block_job_get(const char *id)
>>>        }
>>>    }
>>>    +BlockJob *block_job_get(const char *id)
>>> +{
>>> +    JOB_LOCK_GUARD();
>>> +    return block_job_get_locked(id);
>>> +}
>>> +
>>>    void block_job_free(Job *job)
>>>    {
>>>        BlockJob *bjob = container_of(job, BlockJob, job);
>>> @@ -256,14 +268,14 @@ static bool job_timer_pending(Job *job)
>>>        return timer_pending(&job->sleep_timer);
>>>    }
>>>    -bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
>>> +bool block_job_set_speed_locked(BlockJob *job, int64_t speed, Error
>>> **errp)
>>>    {
>>>        const BlockJobDriver *drv = block_job_driver(job);
>>>        int64_t old_speed = job->speed;
>>>          GLOBAL_STATE_CODE();
>>>    -    if (job_apply_verb(&job->job, JOB_VERB_SET_SPEED, errp) < 0) {
>>> +    if (job_apply_verb_locked(&job->job, JOB_VERB_SET_SPEED, errp) <
>>> 0) {
>>>            return false;
>>>        }
>>>        if (speed < 0) {
>>> @@ -277,7 +289,9 @@ bool block_job_set_speed(BlockJob *job, int64_t
>>> speed, Error **errp)
>>>        job->speed = speed;
>>>          if (drv->set_speed) {
>>> +        job_unlock();
>>>            drv->set_speed(job, speed);
>>> +        job_lock();
>>>        }
>>>          if (speed && speed <= old_speed) {
>>> @@ -285,18 +299,24 @@ bool block_job_set_speed(BlockJob *job, int64_t
>>> speed, Error **errp)
>>>        }
>>>          /* kick only if a timer is pending */
>>> -    job_enter_cond(&job->job, job_timer_pending);
>>> +    job_enter_cond_locked(&job->job, job_timer_pending);
>>>          return true;
>>>    }
>>>    +bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
>>> +{
>>> +    JOB_LOCK_GUARD();
>>> +    return block_job_set_speed_locked(job, speed, errp);
>>> +}
>>> +
>>>    int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
>>>    {
>>>        IO_CODE();
>>>        return ratelimit_calculate_delay(&job->limit, n);
>>>    }
>>>    -BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
>>> +BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp)
>>>    {
>>>        BlockJobInfo *info;
>>>        uint64_t progress_current, progress_total;
>>> @@ -320,7 +340,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error
>>> **errp)
>>>        info->len       = progress_total;
>>>        info->speed     = job->speed;
>>>        info->io_status = job->iostatus;
>>> -    info->ready     = job_is_ready(&job->job),
>>> +    info->ready     = job_is_ready_locked(&job->job),
>>>        info->status    = job->job.status;
>>>        info->auto_finalize = job->job.auto_finalize;
>>>        info->auto_dismiss  = job->job.auto_dismiss;
>>> @@ -333,6 +353,12 @@ BlockJobInfo *block_job_query(BlockJob *job,
>>> Error **errp)
>>>        return info;
>>>    }
>>>    +BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
>>> +{
>>> +    JOB_LOCK_GUARD();
>>> +    return block_job_query_locked(job, errp);
>>> +}
>>> +
>>>    static void block_job_iostatus_set_err(BlockJob *job, int error)
>>>    {
>>>        if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
>>> @@ -478,7 +504,7 @@ fail:
>>>        return NULL;
>>>    }
>>>    -void block_job_iostatus_reset(BlockJob *job)
>>> +void block_job_iostatus_reset_locked(BlockJob *job)
>>>    {
>>>        GLOBAL_STATE_CODE();
>>>        if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
>>> @@ -488,6 +514,12 @@ void block_job_iostatus_reset(BlockJob *job)
>>>        job->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
>>>    }
>>>    +void block_job_iostatus_reset(BlockJob *job)
>>> +{
>>> +    JOB_LOCK_GUARD();
>>> +    block_job_iostatus_reset_locked(job);
>>> +}
>>> +
>>>    void block_job_user_resume(Job *job)
>>>    {
>>>        BlockJob *bjob = container_of(job, BlockJob, job);
>>> diff --git a/include/block/blockjob.h b/include/block/blockjob.h
>>> index 6525e16fd5..3959a98612 100644
>>> --- a/include/block/blockjob.h
>>> +++ b/include/block/blockjob.h
>>> @@ -92,6 +92,9 @@ typedef struct BlockJob {
>>>     */
>>>    BlockJob *block_job_next(BlockJob *job);
>>>    +/* Same as block_job_next(), but called with job lock held. */
>>> +BlockJob *block_job_next_locked(BlockJob *job);
>>> +
>>>    /**
>>>     * block_job_get:
>>>     * @id: The id of the block job.
>>> @@ -102,6 +105,9 @@ BlockJob *block_job_next(BlockJob *job);
>>>     */
>>>    BlockJob *block_job_get(const char *id);
>>>    +/* Same as block_job_get(), but called with job lock held. */
>>> +BlockJob *block_job_get_locked(const char *id);
>>> +
>>>    /**
>>>     * block_job_add_bdrv:
>>>     * @job: A block job
>>> @@ -145,6 +151,9 @@ bool block_job_has_bdrv(BlockJob *job,
>>> BlockDriverState *bs);
>>>     */
>>>    bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
>>>    +/* Same as block_job_set_speed(), but called with job lock held. */
>>> +bool block_job_set_speed_locked(BlockJob *job, int64_t speed, Error
>>> **errp);
>>> +
>>>    /**
>>>     * block_job_query:
>>>     * @job: The job to get information about.
>>> @@ -153,6 +162,9 @@ bool block_job_set_speed(BlockJob *job, int64_t
>>> speed, Error **errp);
>>>     */
>>>    BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
>>>    +/* Same as block_job_query(), but called with job lock held. */
>>> +BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp);
>>> +
>>>    /**
>>>     * block_job_iostatus_reset:
>>>     * @job: The job whose I/O status should be reset.
>>> @@ -162,6 +174,9 @@ BlockJobInfo *block_job_query(BlockJob *job, Error
>>> **errp);
>>>     */
>>>    void block_job_iostatus_reset(BlockJob *job);
>>>    +/* Same as block_job_iostatus_reset(), but called with job lock
>>> held. */
>>> +void block_job_iostatus_reset_locked(BlockJob *job);
>>> +
>>>    /*
>>>     * block_job_get_aio_context:
>>>     *
>>
>>
> 


-- 
Best regards,
Vladimir


  reply	other threads:[~2022-07-06 12:26 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-29 14:15 [PATCH v8 00/20] job: replace AioContext lock with job_mutex Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 01/20] job.c: make job_mutex and job_lock/unlock() public Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 02/20] job.h: categorize fields in struct Job Emanuele Giuseppe Esposito
2022-07-05  7:29   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 03/20] job.c: API functions not used outside should be static Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 04/20] aio-wait.h: introduce AIO_WAIT_WHILE_UNLOCKED Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 05/20] job.c: add job_lock/unlock while keeping job.h intact Emanuele Giuseppe Esposito
2022-07-05  7:39   ` Stefan Hajnoczi
2022-07-05  8:07     ` Emanuele Giuseppe Esposito
2022-07-06 10:09       ` Stefan Hajnoczi
2022-07-05  7:39   ` Stefan Hajnoczi
2022-07-05 10:23   ` Vladimir Sementsov-Ogievskiy
2022-06-29 14:15 ` [PATCH v8 06/20] job.h: define functions called without job lock held Emanuele Giuseppe Esposito
2022-07-05  7:43   ` Stefan Hajnoczi
2022-07-05 10:53   ` Vladimir Sementsov-Ogievskiy
2022-07-06  8:22     ` Emanuele Giuseppe Esposito
2022-07-06  9:48       ` Vladimir Sementsov-Ogievskiy
2022-07-05 10:54   ` Vladimir Sementsov-Ogievskiy
2022-07-06  8:23     ` Emanuele Giuseppe Esposito
2022-07-06  9:51       ` Vladimir Sementsov-Ogievskiy
2022-06-29 14:15 ` [PATCH v8 07/20] job.h: add _locked public functions Emanuele Giuseppe Esposito
2022-07-05  7:44   ` Stefan Hajnoczi
2022-07-05 10:58   ` Vladimir Sementsov-Ogievskiy
2022-06-29 14:15 ` [PATCH v8 08/20] blockjob.h: introduce block_job _locked() APIs Emanuele Giuseppe Esposito
2022-07-05  7:58   ` Stefan Hajnoczi
2022-07-05  8:12     ` Emanuele Giuseppe Esposito
2022-07-05 15:01   ` Vladimir Sementsov-Ogievskiy
2022-07-06 12:05     ` Emanuele Giuseppe Esposito
2022-07-06 12:23       ` Vladimir Sementsov-Ogievskiy [this message]
2022-07-06 12:36         ` Emanuele Giuseppe Esposito
2022-07-06 12:59           ` Emanuele Giuseppe Esposito
2022-07-06 17:23             ` Vladimir Sementsov-Ogievskiy
2022-06-29 14:15 ` [PATCH v8 09/20] blockjob: rename notifier callbacks as _locked Emanuele Giuseppe Esposito
2022-07-05  8:00   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 10/20] jobs: add job lock in find_* functions Emanuele Giuseppe Esposito
2022-07-05  8:03   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 11/20] jobs: use job locks also in the unit tests Emanuele Giuseppe Esposito
2022-07-05  8:04   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 12/20] block/mirror.c: use of job helpers in drivers to avoid TOC/TOU Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 13/20] jobs: group together API calls under the same job lock Emanuele Giuseppe Esposito
2022-07-05  8:14   ` Stefan Hajnoczi
2022-07-05  8:17     ` Emanuele Giuseppe Esposito
2022-07-05 13:01       ` Emanuele Giuseppe Esposito
2022-07-05 13:22         ` Vladimir Sementsov-Ogievskiy
2022-07-06 10:13           ` Stefan Hajnoczi
2022-07-05 14:55   ` Vladimir Sementsov-Ogievskiy
2022-06-29 14:15 ` [PATCH v8 14/20] commit and mirror: create new nodes using bdrv_get_aio_context, and not the job aiocontext Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 15/20] job: detect change of aiocontext within job coroutine Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 16/20] jobs: protect job.aio_context with BQL and job_mutex Emanuele Giuseppe Esposito
2022-07-05 12:44   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 17/20] job.c: enable job lock/unlock and remove Aiocontext locks Emanuele Giuseppe Esposito
2022-07-05 13:07   ` Stefan Hajnoczi
2022-07-06 21:29     ` Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 18/20] block_job_query: remove atomic read Emanuele Giuseppe Esposito
2022-06-29 14:15 ` [PATCH v8 19/20] blockjob: remove unused functions Emanuele Giuseppe Esposito
2022-07-05 13:10   ` Stefan Hajnoczi
2022-06-29 14:15 ` [PATCH v8 20/20] job: " Emanuele Giuseppe Esposito
2022-07-05 13:11   ` Stefan Hajnoczi
2022-07-05 13:12 ` [PATCH v8 00/20] job: replace AioContext lock with job_mutex Stefan Hajnoczi

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=a48ea347-3a44-28c7-b154-ce3dadbae23c@yandex-team.ru \
    --to=vsementsov@yandex-team.ru \
    --cc=armbru@redhat.com \
    --cc=eesposit@redhat.com \
    --cc=fam@euphon.net \
    --cc=hreitz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=vsementsov@virtuozzo.com \
    --cc=wencongyang2@huawei.com \
    --cc=xiechanglong.d@gmail.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 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.