[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v7 13/18] job.h: define unlocked functions
From: |
Emanuele Giuseppe Esposito |
Subject: |
[PATCH v7 13/18] job.h: define unlocked functions |
Date: |
Thu, 16 Jun 2022 09:18:30 -0400 |
All these functions assume that the lock is not held, and acquire
it internally.
These functions will be useful when job_lock is globally applied,
as they will allow callers to access the job struct fields
without worrying about the job lock.
Update also the comments in blockjob.c (and move them in job.c).
Note: at this stage, job_{lock/unlock} and job lock guard macros
are *nop*.
No functional change intended.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
blockjob.c | 20 --------------------
include/qemu/job.h | 36 +++++++++++++++++++++++++++++++++---
job.c | 16 ++++++++++++++++
3 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/blockjob.c b/blockjob.c
index 0745f4e745..2c075db45b 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -36,21 +36,6 @@
#include "qemu/main-loop.h"
#include "qemu/timer.h"
-/*
- * The block job API is composed of two categories of functions.
- *
- * The first includes functions used by the monitor. The monitor is
- * peculiar in that it accesses the block job list with block_job_get, and
- * therefore needs consistency across block_job_get and the actual operation
- * (e.g. block_job_set_speed). The consistency is achieved with
- * aio_context_acquire/release. These functions are declared in blockjob.h.
- *
- * The second includes functions used by the block job drivers and sometimes
- * by the core block layer. These do not care about locking, because the
- * whole coroutine runs under the AioContext lock, and are declared in
- * blockjob_int.h.
- */
-
static bool is_block_job(Job *job)
{
return job_type(job) == JOB_TYPE_BACKUP ||
@@ -446,11 +431,6 @@ static void block_job_event_ready_locked(Notifier *n, void
*opaque)
}
-/*
- * API for block job drivers and the block layer. These functions are
- * declared in blockjob_int.h.
- */
-
void *block_job_create(const char *job_id, const BlockJobDriver *driver,
JobTxn *txn, BlockDriverState *bs, uint64_t perm,
uint64_t shared_perm, int64_t speed, int flags,
diff --git a/include/qemu/job.h b/include/qemu/job.h
index 246af068a1..2c9011329a 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -362,6 +362,7 @@ void job_txn_unref_locked(JobTxn *txn);
/**
* Create a new long-running job and return it.
+ * Called with job_mutex *not* held.
*
* @job_id: The id of the newly-created job, or %NULL for internal jobs
* @driver: The class object for the newly-created job.
@@ -397,6 +398,8 @@ void job_unref_locked(Job *job);
* @done: How much progress the job made since the last call
*
* Updates the progress counter of the job.
+ *
+ * Progress API is thread safe.
*/
void job_progress_update(Job *job, uint64_t done);
@@ -407,6 +410,8 @@ void job_progress_update(Job *job, uint64_t done);
*
* Sets the expected end value of the progress counter of a job so that a
* completion percentage can be calculated when the progress is updated.
+ *
+ * Progress API is thread safe.
*/
void job_progress_set_remaining(Job *job, uint64_t remaining);
@@ -422,6 +427,8 @@ void job_progress_set_remaining(Job *job, uint64_t
remaining);
* length before, and job_progress_update() afterwards.
* (So the operation acts as a parenthesis in regards to the main job
* operation running in background.)
+ *
+ * Progress API is thread safe.
*/
void job_progress_increase_remaining(Job *job, uint64_t delta);
@@ -439,6 +446,8 @@ void job_enter_cond_locked(Job *job, bool(*fn)(Job *job));
*
* Begins execution of a job.
* Takes ownership of one reference to the job object.
+ *
+ * Called with job_mutex *not* held.
*/
void job_start(Job *job);
@@ -446,6 +455,7 @@ void job_start(Job *job);
* @job: The job to enter.
*
* Continue the specified job by entering the coroutine.
+ * Called with job_mutex lock *not* held.
*/
void job_enter(Job *job);
@@ -454,6 +464,9 @@ void job_enter(Job *job);
*
* Pause now if job_pause_locked() has been called. Jobs that perform lots of
* I/O must call this between requests so that the job can be paused.
+ *
+ * Called with job_mutex *not* held (we don't want the coroutine
+ * to yield with the lock held!).
*/
void coroutine_fn job_pause_point(Job *job);
@@ -461,6 +474,8 @@ void coroutine_fn job_pause_point(Job *job);
* @job: The job that calls the function.
*
* Yield the job coroutine.
+ * Called with job_mutex *not* held (we don't want the coroutine
+ * to yield with the lock held!).
*/
void job_yield(Job *job);
@@ -471,6 +486,9 @@ void job_yield(Job *job);
* Put the job to sleep (assuming that it wasn't canceled) for @ns
* %QEMU_CLOCK_REALTIME nanoseconds. Canceling the job will immediately
* interrupt the wait.
+ *
+ * Called with job_mutex *not* held (we don't want the coroutine
+ * to yield with the lock held!).
*/
void coroutine_fn job_sleep_ns(Job *job, int64_t ns);
@@ -582,10 +600,16 @@ Job *job_get_locked(const char *id);
*/
int job_apply_verb_locked(Job *job, JobVerb verb, Error **errp);
-/** The @job could not be started, free it. */
+/**
+ * The @job could not be started, free it.
+ * Called with job_mutex *not* held.
+ */
void job_early_fail(Job *job);
-/** Moves the @job from RUNNING to READY */
+/**
+ * Moves the @job from RUNNING to READY.
+ * Called with job_mutex *not* held.
+ */
void job_transition_to_ready(Job *job);
/**
@@ -624,7 +648,13 @@ void job_user_cancel_locked(Job *job, bool force, Error
**errp);
*/
int job_cancel_sync_locked(Job *job, bool force);
-/** Synchronously force-cancels all jobs using job_cancel_sync_locked(). */
+/**
+ * Synchronously force-cancels all jobs using job_cancel_sync_locked().
+ *
+ * Called with job_lock *not* held, unlike most other APIs consumed
+ * by the monitor! This is primarly to avoid adding unnecessary lock-unlock
+ * patterns in the caller.
+ */
void job_cancel_sync_all(void);
/**
diff --git a/job.c b/job.c
index 5c0cb37175..b6b9431b2d 100644
--- a/job.c
+++ b/job.c
@@ -32,12 +32,27 @@
#include "trace/trace-root.h"
#include "qapi/qapi-events-job.h"
+/*
+ * The job API is composed of two categories of functions.
+ *
+ * The first includes functions used by the monitor. The monitor is
+ * peculiar in that it accesses the block job list with job_get, and
+ * therefore needs consistency across job_get and the actual operation
+ * (e.g. job_user_cancel). To achieve this consistency, the caller
+ * calls job_lock/job_unlock itself around the whole operation.
+ *
+ *
+ * The second includes functions used by the block job drivers and sometimes
+ * by the core block layer. These delegate the locking to the callee instead.
+ */
+
/*
* job_mutex protects the jobs list, but also makes the
* struct job fields thread-safe.
*/
QemuMutex job_mutex;
+/* Protected by job_mutex */
static QLIST_HEAD(, Job) jobs = QLIST_HEAD_INITIALIZER(jobs);
/* Job State Transition Table */
@@ -353,6 +368,7 @@ Job *job_get_locked(const char *id)
return NULL;
}
+/* Called with job_mutex *not* held. */
static void job_sleep_timer_cb(void *opaque)
{
Job *job = opaque;
--
2.31.1
- [PATCH v7 12/18] block_job: rename block_job functions called with job_mutex held, (continued)
- [PATCH v7 16/18] jobs: protect job.aio_context with BQL and job_mutex, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 06/18] jobs: protect jobs with job_lock/unlock, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 13/18] job.h: define unlocked functions,
Emanuele Giuseppe Esposito <=
- [PATCH v7 07/18] jobs: add job lock in find_* functions, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 11/18] job.h: rename job API functions called with job_mutex held, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 02/18] job.h: categorize fields in struct Job, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 08/18] jobs: use job locks also in the unit tests, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 03/18] job.c: API functions not used outside should be static, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 17/18] job.c: enable job lock/unlock and remove Aiocontext locks, Emanuele Giuseppe Esposito, 2022/06/16
- [PATCH v7 10/18] jobs: rename static functions called with job_mutex held, Emanuele Giuseppe Esposito, 2022/06/16