Skip to content

Commit b49f475

Browse files
stefanhaRHkevmw
authored andcommitted
block: remove AioContext locking
This is the big patch that removes aio_context_acquire()/aio_context_release() from the block layer and affected block layer users. There isn't a clean way to split this patch and the reviewers are likely the same group of people, so I decided to do it in one patch. Signed-off-by: Stefan Hajnoczi <[email protected]> Reviewed-by: Eric Blake <[email protected]> Reviewed-by: Kevin Wolf <[email protected]> Reviewed-by: Paul Durrant <[email protected]> Message-ID: <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent 6bc30f1 commit b49f475

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+104
-1169
lines changed

block.c

+8-226
Large diffs are not rendered by default.

block/block-backend.c

-14
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,6 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
429429
{
430430
BlockBackend *blk;
431431
BlockDriverState *bs;
432-
AioContext *ctx;
433432
uint64_t perm = 0;
434433
uint64_t shared = BLK_PERM_ALL;
435434

@@ -459,23 +458,18 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
459458
shared = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
460459
}
461460

462-
aio_context_acquire(qemu_get_aio_context());
463461
bs = bdrv_open(filename, reference, options, flags, errp);
464-
aio_context_release(qemu_get_aio_context());
465462
if (!bs) {
466463
return NULL;
467464
}
468465

469466
/* bdrv_open() could have moved bs to a different AioContext */
470-
ctx = bdrv_get_aio_context(bs);
471467
blk = blk_new(bdrv_get_aio_context(bs), perm, shared);
472468
blk->perm = perm;
473469
blk->shared_perm = shared;
474470

475-
aio_context_acquire(ctx);
476471
blk_insert_bs(blk, bs, errp);
477472
bdrv_unref(bs);
478-
aio_context_release(ctx);
479473

480474
if (!blk->root) {
481475
blk_unref(blk);
@@ -577,13 +571,9 @@ void blk_remove_all_bs(void)
577571
GLOBAL_STATE_CODE();
578572

579573
while ((blk = blk_all_next(blk)) != NULL) {
580-
AioContext *ctx = blk_get_aio_context(blk);
581-
582-
aio_context_acquire(ctx);
583574
if (blk->root) {
584575
blk_remove_bs(blk);
585576
}
586-
aio_context_release(ctx);
587577
}
588578
}
589579

@@ -2736,20 +2726,16 @@ int blk_commit_all(void)
27362726
GRAPH_RDLOCK_GUARD_MAINLOOP();
27372727

27382728
while ((blk = blk_all_next(blk)) != NULL) {
2739-
AioContext *aio_context = blk_get_aio_context(blk);
27402729
BlockDriverState *unfiltered_bs = bdrv_skip_filters(blk_bs(blk));
27412730

2742-
aio_context_acquire(aio_context);
27432731
if (blk_is_inserted(blk) && bdrv_cow_child(unfiltered_bs)) {
27442732
int ret;
27452733

27462734
ret = bdrv_commit(unfiltered_bs);
27472735
if (ret < 0) {
2748-
aio_context_release(aio_context);
27492736
return ret;
27502737
}
27512738
}
2752-
aio_context_release(aio_context);
27532739
}
27542740
return 0;
27552741
}

block/copy-before-write.c

+5-17
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,6 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
412412
int64_t cluster_size;
413413
g_autoptr(BlockdevOptions) full_opts = NULL;
414414
BlockdevOptionsCbw *opts;
415-
AioContext *ctx;
416415
int ret;
417416

418417
full_opts = cbw_parse_options(options, errp);
@@ -435,15 +434,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
435434

436435
GRAPH_RDLOCK_GUARD_MAINLOOP();
437436

438-
ctx = bdrv_get_aio_context(bs);
439-
aio_context_acquire(ctx);
440-
441437
if (opts->bitmap) {
442438
bitmap = block_dirty_bitmap_lookup(opts->bitmap->node,
443439
opts->bitmap->name, NULL, errp);
444440
if (!bitmap) {
445-
ret = -EINVAL;
446-
goto out;
441+
return -EINVAL;
447442
}
448443
}
449444
s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
@@ -461,24 +456,21 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
461456
s->bcs = block_copy_state_new(bs->file, s->target, bitmap, errp);
462457
if (!s->bcs) {
463458
error_prepend(errp, "Cannot create block-copy-state: ");
464-
ret = -EINVAL;
465-
goto out;
459+
return -EINVAL;
466460
}
467461

468462
cluster_size = block_copy_cluster_size(s->bcs);
469463

470464
s->done_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
471465
if (!s->done_bitmap) {
472-
ret = -EINVAL;
473-
goto out;
466+
return -EINVAL;
474467
}
475468
bdrv_disable_dirty_bitmap(s->done_bitmap);
476469

477470
/* s->access_bitmap starts equal to bcs bitmap */
478471
s->access_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
479472
if (!s->access_bitmap) {
480-
ret = -EINVAL;
481-
goto out;
473+
return -EINVAL;
482474
}
483475
bdrv_disable_dirty_bitmap(s->access_bitmap);
484476
bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
@@ -487,11 +479,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
487479

488480
qemu_co_mutex_init(&s->lock);
489481
QLIST_INIT(&s->frozen_read_reqs);
490-
491-
ret = 0;
492-
out:
493-
aio_context_release(ctx);
494-
return ret;
482+
return 0;
495483
}
496484

497485
static void cbw_close(BlockDriverState *bs)

block/export/export.c

+1-21
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
114114
}
115115

116116
ctx = bdrv_get_aio_context(bs);
117-
aio_context_acquire(ctx);
118117

119118
if (export->iothread) {
120119
IOThread *iothread;
@@ -133,8 +132,6 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
133132
set_context_errp = fixed_iothread ? errp : NULL;
134133
ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp);
135134
if (ret == 0) {
136-
aio_context_release(ctx);
137-
aio_context_acquire(new_ctx);
138135
ctx = new_ctx;
139136
} else if (fixed_iothread) {
140137
goto fail;
@@ -191,16 +188,13 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
191188
assert(exp->blk != NULL);
192189

193190
QLIST_INSERT_HEAD(&block_exports, exp, next);
194-
195-
aio_context_release(ctx);
196191
return exp;
197192

198193
fail:
199194
if (blk) {
200195
blk_set_dev_ops(blk, NULL, NULL);
201196
blk_unref(blk);
202197
}
203-
aio_context_release(ctx);
204198
if (exp) {
205199
g_free(exp->id);
206200
g_free(exp);
@@ -218,9 +212,6 @@ void blk_exp_ref(BlockExport *exp)
218212
static void blk_exp_delete_bh(void *opaque)
219213
{
220214
BlockExport *exp = opaque;
221-
AioContext *aio_context = exp->ctx;
222-
223-
aio_context_acquire(aio_context);
224215

225216
assert(exp->refcount == 0);
226217
QLIST_REMOVE(exp, next);
@@ -230,8 +221,6 @@ static void blk_exp_delete_bh(void *opaque)
230221
qapi_event_send_block_export_deleted(exp->id);
231222
g_free(exp->id);
232223
g_free(exp);
233-
234-
aio_context_release(aio_context);
235224
}
236225

237226
void blk_exp_unref(BlockExport *exp)
@@ -249,32 +238,23 @@ void blk_exp_unref(BlockExport *exp)
249238
* connections and other internally held references start to shut down. When
250239
* the function returns, there may still be active references while the export
251240
* is in the process of shutting down.
252-
*
253-
* Acquires exp->ctx internally. Callers must *not* hold the lock.
254241
*/
255242
void blk_exp_request_shutdown(BlockExport *exp)
256243
{
257-
AioContext *aio_context = exp->ctx;
258-
259-
aio_context_acquire(aio_context);
260-
261244
/*
262245
* If the user doesn't own the export any more, it is already shutting
263246
* down. We must not call .request_shutdown and decrease the refcount a
264247
* second time.
265248
*/
266249
if (!exp->user_owned) {
267-
goto out;
250+
return;
268251
}
269252

270253
exp->drv->request_shutdown(exp);
271254

272255
assert(exp->user_owned);
273256
exp->user_owned = false;
274257
blk_exp_unref(exp);
275-
276-
out:
277-
aio_context_release(aio_context);
278258
}
279259

280260
/*

block/io.c

+5-40
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,13 @@ static void bdrv_co_drain_bh_cb(void *opaque)
294294
BlockDriverState *bs = data->bs;
295295

296296
if (bs) {
297-
AioContext *ctx = bdrv_get_aio_context(bs);
298-
aio_context_acquire(ctx);
299297
bdrv_dec_in_flight(bs);
300298
if (data->begin) {
301299
bdrv_do_drained_begin(bs, data->parent, data->poll);
302300
} else {
303301
assert(!data->poll);
304302
bdrv_do_drained_end(bs, data->parent);
305303
}
306-
aio_context_release(ctx);
307304
} else {
308305
assert(data->begin);
309306
bdrv_drain_all_begin();
@@ -320,8 +317,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
320317
{
321318
BdrvCoDrainData data;
322319
Coroutine *self = qemu_coroutine_self();
323-
AioContext *ctx = bdrv_get_aio_context(bs);
324-
AioContext *co_ctx = qemu_coroutine_get_aio_context(self);
325320

326321
/* Calling bdrv_drain() from a BH ensures the current coroutine yields and
327322
* other coroutines run if they were queued by aio_co_enter(). */
@@ -340,29 +335,13 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
340335
bdrv_inc_in_flight(bs);
341336
}
342337

343-
/*
344-
* Temporarily drop the lock across yield or we would get deadlocks.
345-
* bdrv_co_drain_bh_cb() reaquires the lock as needed.
346-
*
347-
* When we yield below, the lock for the current context will be
348-
* released, so if this is actually the lock that protects bs, don't drop
349-
* it a second time.
350-
*/
351-
if (ctx != co_ctx) {
352-
aio_context_release(ctx);
353-
}
354338
replay_bh_schedule_oneshot_event(qemu_get_aio_context(),
355339
bdrv_co_drain_bh_cb, &data);
356340

357341
qemu_coroutine_yield();
358342
/* If we are resumed from some other event (such as an aio completion or a
359343
* timer callback), it is a bug in the caller that should be fixed. */
360344
assert(data.done);
361-
362-
/* Reacquire the AioContext of bs if we dropped it */
363-
if (ctx != co_ctx) {
364-
aio_context_acquire(ctx);
365-
}
366345
}
367346

368347
static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
@@ -478,13 +457,12 @@ static bool bdrv_drain_all_poll(void)
478457
GLOBAL_STATE_CODE();
479458
GRAPH_RDLOCK_GUARD_MAINLOOP();
480459

481-
/* bdrv_drain_poll() can't make changes to the graph and we are holding the
482-
* main AioContext lock, so iterating bdrv_next_all_states() is safe. */
460+
/*
461+
* bdrv_drain_poll() can't make changes to the graph and we hold the BQL,
462+
* so iterating bdrv_next_all_states() is safe.
463+
*/
483464
while ((bs = bdrv_next_all_states(bs))) {
484-
AioContext *aio_context = bdrv_get_aio_context(bs);
485-
aio_context_acquire(aio_context);
486465
result |= bdrv_drain_poll(bs, NULL, true);
487-
aio_context_release(aio_context);
488466
}
489467

490468
return result;
@@ -525,11 +503,7 @@ void bdrv_drain_all_begin_nopoll(void)
525503
/* Quiesce all nodes, without polling in-flight requests yet. The graph
526504
* cannot change during this loop. */
527505
while ((bs = bdrv_next_all_states(bs))) {
528-
AioContext *aio_context = bdrv_get_aio_context(bs);
529-
530-
aio_context_acquire(aio_context);
531506
bdrv_do_drained_begin(bs, NULL, false);
532-
aio_context_release(aio_context);
533507
}
534508
}
535509

@@ -588,11 +562,7 @@ void bdrv_drain_all_end(void)
588562
}
589563

590564
while ((bs = bdrv_next_all_states(bs))) {
591-
AioContext *aio_context = bdrv_get_aio_context(bs);
592-
593-
aio_context_acquire(aio_context);
594565
bdrv_do_drained_end(bs, NULL);
595-
aio_context_release(aio_context);
596566
}
597567

598568
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
@@ -2368,15 +2338,10 @@ int bdrv_flush_all(void)
23682338
}
23692339

23702340
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
2371-
AioContext *aio_context = bdrv_get_aio_context(bs);
2372-
int ret;
2373-
2374-
aio_context_acquire(aio_context);
2375-
ret = bdrv_flush(bs);
2341+
int ret = bdrv_flush(bs);
23762342
if (ret < 0 && !result) {
23772343
result = ret;
23782344
}
2379-
aio_context_release(aio_context);
23802345
}
23812346

23822347
return result;

0 commit comments

Comments
 (0)