@@ -543,11 +543,12 @@ void job_enter_cond_locked(Job *job, bool(*fn)(Job *job))
return;
}
- assert(!job->deferred_to_main_loop);
timer_del(&job->sleep_timer);
job->busy = true;
real_job_unlock();
- aio_co_enter(job->aio_context, job->co);
+ job_unlock();
+ aio_co_wake(job->co);
+ job_lock();
}
void job_enter(Job *job)
@@ -568,6 +569,8 @@ void job_enter(Job *job)
*/
static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns)
{
+ AioContext *next_aio_context;
+
real_job_lock();
if (ns != -1) {
timer_mod(&job->sleep_timer, ns);
@@ -579,6 +582,19 @@ static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns)
qemu_coroutine_yield();
job_lock();
+ next_aio_context = job->aio_context;
+ /*
+ * Coroutine has resumed, but in the meanwhile the job AioContext
+ * might have changed via bdrv_try_set_aio_context(), so we need to move
+ * the coroutine too in the new aiocontext.
+ */
+ while (qemu_get_current_aio_context() != next_aio_context) {
+ job_unlock();
+ aio_co_reschedule_self(next_aio_context);
+ job_lock();
+ next_aio_context = job->aio_context;
+ }
+
/* Set by job_enter_cond_locked() before re-entering the coroutine. */
assert(job->busy);
}
@@ -1122,6 +1138,8 @@ static void coroutine_fn job_co_entry(void *opaque)
void job_start(Job *job)
{
+ assert(qemu_in_main_thread());
+
WITH_JOB_LOCK_GUARD() {
assert(job && !job_started(job) && job->paused &&
job->driver && job->driver->run);