io.c (c7bc05f78ab31fb02fc9635f60b9bd22efc8d121) | io.c (299403aedaeb7f08d8e98aa8614b29d4e5546066) |
---|---|
1/* 2 * Block layer I/O functions 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 222 unchanged lines hidden (view full) --- 231 assert(old >= 1); 232} 233 234typedef struct { 235 Coroutine *co; 236 BlockDriverState *bs; 237 bool done; 238 bool begin; | 1/* 2 * Block layer I/O functions 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 222 unchanged lines hidden (view full) --- 231 assert(old >= 1); 232} 233 234typedef struct { 235 Coroutine *co; 236 BlockDriverState *bs; 237 bool done; 238 bool begin; |
239 bool recursive; | |
240 bool poll; 241 BdrvChild *parent; 242 bool ignore_bds_parents; 243} BdrvCoDrainData; 244 245/* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() */ | 239 bool poll; 240 BdrvChild *parent; 241 bool ignore_bds_parents; 242} BdrvCoDrainData; 243 244/* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() */ |
246bool bdrv_drain_poll(BlockDriverState *bs, bool recursive, 247 BdrvChild *ignore_parent, bool ignore_bds_parents) | 245bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent, 246 bool ignore_bds_parents) |
248{ | 247{ |
249 BdrvChild *child, *next; | |
250 IO_OR_GS_CODE(); 251 252 if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) { 253 return true; 254 } 255 256 if (qatomic_read(&bs->in_flight)) { 257 return true; 258 } 259 | 248 IO_OR_GS_CODE(); 249 250 if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) { 251 return true; 252 } 253 254 if (qatomic_read(&bs->in_flight)) { 255 return true; 256 } 257 |
260 if (recursive) { 261 assert(!ignore_bds_parents); 262 QLIST_FOREACH_SAFE(child, &bs->children, next, next) { 263 if (bdrv_drain_poll(child->bs, recursive, child, false)) { 264 return true; 265 } 266 } 267 } 268 | |
269 return false; 270} 271 | 258 return false; 259} 260 |
272static bool bdrv_drain_poll_top_level(BlockDriverState *bs, bool recursive, | 261static bool bdrv_drain_poll_top_level(BlockDriverState *bs, |
273 BdrvChild *ignore_parent) 274{ | 262 BdrvChild *ignore_parent) 263{ |
275 return bdrv_drain_poll(bs, recursive, ignore_parent, false); | 264 return bdrv_drain_poll(bs, ignore_parent, false); |
276} 277 | 265} 266 |
278static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive, 279 BdrvChild *parent, bool ignore_bds_parents, 280 bool poll); 281static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive, 282 BdrvChild *parent, bool ignore_bds_parents); | 267static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, 268 bool ignore_bds_parents, bool poll); 269static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent, 270 bool ignore_bds_parents); |
283 284static void bdrv_co_drain_bh_cb(void *opaque) 285{ 286 BdrvCoDrainData *data = opaque; 287 Coroutine *co = data->co; 288 BlockDriverState *bs = data->bs; 289 290 if (bs) { 291 AioContext *ctx = bdrv_get_aio_context(bs); 292 aio_context_acquire(ctx); 293 bdrv_dec_in_flight(bs); 294 if (data->begin) { | 271 272static void bdrv_co_drain_bh_cb(void *opaque) 273{ 274 BdrvCoDrainData *data = opaque; 275 Coroutine *co = data->co; 276 BlockDriverState *bs = data->bs; 277 278 if (bs) { 279 AioContext *ctx = bdrv_get_aio_context(bs); 280 aio_context_acquire(ctx); 281 bdrv_dec_in_flight(bs); 282 if (data->begin) { |
295 bdrv_do_drained_begin(bs, data->recursive, data->parent, 296 data->ignore_bds_parents, data->poll); | 283 bdrv_do_drained_begin(bs, data->parent, data->ignore_bds_parents, 284 data->poll); |
297 } else { 298 assert(!data->poll); | 285 } else { 286 assert(!data->poll); |
299 bdrv_do_drained_end(bs, data->recursive, data->parent, 300 data->ignore_bds_parents); | 287 bdrv_do_drained_end(bs, data->parent, data->ignore_bds_parents); |
301 } 302 aio_context_release(ctx); 303 } else { 304 assert(data->begin); 305 bdrv_drain_all_begin(); 306 } 307 308 data->done = true; 309 aio_co_wake(co); 310} 311 312static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, | 288 } 289 aio_context_release(ctx); 290 } else { 291 assert(data->begin); 292 bdrv_drain_all_begin(); 293 } 294 295 data->done = true; 296 aio_co_wake(co); 297} 298 299static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, |
313 bool begin, bool recursive, | 300 bool begin, |
314 BdrvChild *parent, 315 bool ignore_bds_parents, 316 bool poll) 317{ 318 BdrvCoDrainData data; 319 Coroutine *self = qemu_coroutine_self(); 320 AioContext *ctx = bdrv_get_aio_context(bs); 321 AioContext *co_ctx = qemu_coroutine_get_aio_context(self); 322 323 /* Calling bdrv_drain() from a BH ensures the current coroutine yields and 324 * other coroutines run if they were queued by aio_co_enter(). */ 325 326 assert(qemu_in_coroutine()); 327 data = (BdrvCoDrainData) { 328 .co = self, 329 .bs = bs, 330 .done = false, 331 .begin = begin, | 301 BdrvChild *parent, 302 bool ignore_bds_parents, 303 bool poll) 304{ 305 BdrvCoDrainData data; 306 Coroutine *self = qemu_coroutine_self(); 307 AioContext *ctx = bdrv_get_aio_context(bs); 308 AioContext *co_ctx = qemu_coroutine_get_aio_context(self); 309 310 /* Calling bdrv_drain() from a BH ensures the current coroutine yields and 311 * other coroutines run if they were queued by aio_co_enter(). */ 312 313 assert(qemu_in_coroutine()); 314 data = (BdrvCoDrainData) { 315 .co = self, 316 .bs = bs, 317 .done = false, 318 .begin = begin, |
332 .recursive = recursive, | |
333 .parent = parent, 334 .ignore_bds_parents = ignore_bds_parents, 335 .poll = poll, 336 }; 337 338 if (bs) { 339 bdrv_inc_in_flight(bs); 340 } --- 34 unchanged lines hidden (view full) --- 375 } 376 377 bdrv_parent_drained_begin(bs, parent, ignore_bds_parents); 378 if (bs->drv && bs->drv->bdrv_drain_begin) { 379 bs->drv->bdrv_drain_begin(bs); 380 } 381} 382 | 319 .parent = parent, 320 .ignore_bds_parents = ignore_bds_parents, 321 .poll = poll, 322 }; 323 324 if (bs) { 325 bdrv_inc_in_flight(bs); 326 } --- 34 unchanged lines hidden (view full) --- 361 } 362 363 bdrv_parent_drained_begin(bs, parent, ignore_bds_parents); 364 if (bs->drv && bs->drv->bdrv_drain_begin) { 365 bs->drv->bdrv_drain_begin(bs); 366 } 367} 368 |
383static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive, 384 BdrvChild *parent, bool ignore_bds_parents, 385 bool poll) | 369static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, 370 bool ignore_bds_parents, bool poll) |
386{ | 371{ |
387 BdrvChild *child, *next; 388 | |
389 if (qemu_in_coroutine()) { | 372 if (qemu_in_coroutine()) { |
390 bdrv_co_yield_to_drain(bs, true, recursive, parent, ignore_bds_parents, 391 poll); | 373 bdrv_co_yield_to_drain(bs, true, parent, ignore_bds_parents, poll); |
392 return; 393 } 394 395 bdrv_do_drained_begin_quiesce(bs, parent, ignore_bds_parents); 396 | 374 return; 375 } 376 377 bdrv_do_drained_begin_quiesce(bs, parent, ignore_bds_parents); 378 |
397 if (recursive) { 398 assert(!ignore_bds_parents); 399 bs->recursive_quiesce_counter++; 400 QLIST_FOREACH_SAFE(child, &bs->children, next, next) { 401 bdrv_do_drained_begin(child->bs, true, child, ignore_bds_parents, 402 false); 403 } 404 } 405 | |
406 /* 407 * Wait for drained requests to finish. 408 * 409 * Calling BDRV_POLL_WHILE() only once for the top-level node is okay: The 410 * call is needed so things in this AioContext can make progress even 411 * though we don't return to the main AioContext loop - this automatically 412 * includes other nodes in the same AioContext and therefore all child 413 * nodes. 414 */ 415 if (poll) { 416 assert(!ignore_bds_parents); | 379 /* 380 * Wait for drained requests to finish. 381 * 382 * Calling BDRV_POLL_WHILE() only once for the top-level node is okay: The 383 * call is needed so things in this AioContext can make progress even 384 * though we don't return to the main AioContext loop - this automatically 385 * includes other nodes in the same AioContext and therefore all child 386 * nodes. 387 */ 388 if (poll) { 389 assert(!ignore_bds_parents); |
417 BDRV_POLL_WHILE(bs, bdrv_drain_poll_top_level(bs, recursive, parent)); | 390 BDRV_POLL_WHILE(bs, bdrv_drain_poll_top_level(bs, parent)); |
418 } 419} 420 421void bdrv_drained_begin(BlockDriverState *bs) 422{ 423 IO_OR_GS_CODE(); | 391 } 392} 393 394void bdrv_drained_begin(BlockDriverState *bs) 395{ 396 IO_OR_GS_CODE(); |
424 bdrv_do_drained_begin(bs, false, NULL, false, true); | 397 bdrv_do_drained_begin(bs, NULL, false, true); |
425} 426 | 398} 399 |
427void bdrv_subtree_drained_begin(BlockDriverState *bs) 428{ 429 IO_OR_GS_CODE(); 430 bdrv_do_drained_begin(bs, true, NULL, false, true); 431} 432 | |
433/** 434 * This function does not poll, nor must any of its recursively called 435 * functions. 436 */ | 400/** 401 * This function does not poll, nor must any of its recursively called 402 * functions. 403 */ |
437static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive, 438 BdrvChild *parent, bool ignore_bds_parents) | 404static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent, 405 bool ignore_bds_parents) |
439{ | 406{ |
440 BdrvChild *child; | |
441 int old_quiesce_counter; 442 443 if (qemu_in_coroutine()) { | 407 int old_quiesce_counter; 408 409 if (qemu_in_coroutine()) { |
444 bdrv_co_yield_to_drain(bs, false, recursive, parent, ignore_bds_parents, 445 false); | 410 bdrv_co_yield_to_drain(bs, false, parent, ignore_bds_parents, false); |
446 return; 447 } 448 assert(bs->quiesce_counter > 0); 449 450 /* Re-enable things in child-to-parent order */ 451 if (bs->drv && bs->drv->bdrv_drain_end) { 452 bs->drv->bdrv_drain_end(bs); 453 } 454 bdrv_parent_drained_end(bs, parent, ignore_bds_parents); 455 456 old_quiesce_counter = qatomic_fetch_dec(&bs->quiesce_counter); 457 if (old_quiesce_counter == 1) { 458 aio_enable_external(bdrv_get_aio_context(bs)); 459 } | 411 return; 412 } 413 assert(bs->quiesce_counter > 0); 414 415 /* Re-enable things in child-to-parent order */ 416 if (bs->drv && bs->drv->bdrv_drain_end) { 417 bs->drv->bdrv_drain_end(bs); 418 } 419 bdrv_parent_drained_end(bs, parent, ignore_bds_parents); 420 421 old_quiesce_counter = qatomic_fetch_dec(&bs->quiesce_counter); 422 if (old_quiesce_counter == 1) { 423 aio_enable_external(bdrv_get_aio_context(bs)); 424 } |
460 461 if (recursive) { 462 assert(!ignore_bds_parents); 463 bs->recursive_quiesce_counter--; 464 QLIST_FOREACH(child, &bs->children, next) { 465 bdrv_do_drained_end(child->bs, true, child, ignore_bds_parents); 466 } 467 } | |
468} 469 470void bdrv_drained_end(BlockDriverState *bs) 471{ 472 IO_OR_GS_CODE(); | 425} 426 427void bdrv_drained_end(BlockDriverState *bs) 428{ 429 IO_OR_GS_CODE(); |
473 bdrv_do_drained_end(bs, false, NULL, false); | 430 bdrv_do_drained_end(bs, NULL, false); |
474} 475 | 431} 432 |
476void bdrv_subtree_drained_end(BlockDriverState *bs) 477{ 478 IO_OR_GS_CODE(); 479 bdrv_do_drained_end(bs, true, NULL, false); 480} 481 482void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent) 483{ 484 int i; 485 IO_OR_GS_CODE(); 486 487 for (i = 0; i < new_parent->recursive_quiesce_counter; i++) { 488 bdrv_do_drained_begin(child->bs, true, child, false, true); 489 } 490} 491 492void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent) 493{ 494 int i; 495 IO_OR_GS_CODE(); 496 497 for (i = 0; i < old_parent->recursive_quiesce_counter; i++) { 498 bdrv_do_drained_end(child->bs, true, child, false); 499 } 500} 501 | |
502void bdrv_drain(BlockDriverState *bs) 503{ 504 IO_OR_GS_CODE(); 505 bdrv_drained_begin(bs); 506 bdrv_drained_end(bs); 507} 508 509static void bdrv_drain_assert_idle(BlockDriverState *bs) --- 14 unchanged lines hidden (view full) --- 524 bool result = false; 525 GLOBAL_STATE_CODE(); 526 527 /* bdrv_drain_poll() can't make changes to the graph and we are holding the 528 * main AioContext lock, so iterating bdrv_next_all_states() is safe. */ 529 while ((bs = bdrv_next_all_states(bs))) { 530 AioContext *aio_context = bdrv_get_aio_context(bs); 531 aio_context_acquire(aio_context); | 433void bdrv_drain(BlockDriverState *bs) 434{ 435 IO_OR_GS_CODE(); 436 bdrv_drained_begin(bs); 437 bdrv_drained_end(bs); 438} 439 440static void bdrv_drain_assert_idle(BlockDriverState *bs) --- 14 unchanged lines hidden (view full) --- 455 bool result = false; 456 GLOBAL_STATE_CODE(); 457 458 /* bdrv_drain_poll() can't make changes to the graph and we are holding the 459 * main AioContext lock, so iterating bdrv_next_all_states() is safe. */ 460 while ((bs = bdrv_next_all_states(bs))) { 461 AioContext *aio_context = bdrv_get_aio_context(bs); 462 aio_context_acquire(aio_context); |
532 result |= bdrv_drain_poll(bs, false, NULL, true); | 463 result |= bdrv_drain_poll(bs, NULL, true); |
533 aio_context_release(aio_context); 534 } 535 536 return result; 537} 538 539/* 540 * Wait for pending requests to complete across all BlockDriverStates --- 8 unchanged lines hidden (view full) --- 549 * the bdrv_drain_all_begin() and bdrv_drain_all_end() calls. 550 */ 551void bdrv_drain_all_begin(void) 552{ 553 BlockDriverState *bs = NULL; 554 GLOBAL_STATE_CODE(); 555 556 if (qemu_in_coroutine()) { | 464 aio_context_release(aio_context); 465 } 466 467 return result; 468} 469 470/* 471 * Wait for pending requests to complete across all BlockDriverStates --- 8 unchanged lines hidden (view full) --- 480 * the bdrv_drain_all_begin() and bdrv_drain_all_end() calls. 481 */ 482void bdrv_drain_all_begin(void) 483{ 484 BlockDriverState *bs = NULL; 485 GLOBAL_STATE_CODE(); 486 487 if (qemu_in_coroutine()) { |
557 bdrv_co_yield_to_drain(NULL, true, false, NULL, true, true); | 488 bdrv_co_yield_to_drain(NULL, true, NULL, true, true); |
558 return; 559 } 560 561 /* 562 * bdrv queue is managed by record/replay, 563 * waiting for finishing the I/O requests may 564 * be infinite 565 */ --- 8 unchanged lines hidden (view full) --- 574 bdrv_drain_all_count++; 575 576 /* Quiesce all nodes, without polling in-flight requests yet. The graph 577 * cannot change during this loop. */ 578 while ((bs = bdrv_next_all_states(bs))) { 579 AioContext *aio_context = bdrv_get_aio_context(bs); 580 581 aio_context_acquire(aio_context); | 489 return; 490 } 491 492 /* 493 * bdrv queue is managed by record/replay, 494 * waiting for finishing the I/O requests may 495 * be infinite 496 */ --- 8 unchanged lines hidden (view full) --- 505 bdrv_drain_all_count++; 506 507 /* Quiesce all nodes, without polling in-flight requests yet. The graph 508 * cannot change during this loop. */ 509 while ((bs = bdrv_next_all_states(bs))) { 510 AioContext *aio_context = bdrv_get_aio_context(bs); 511 512 aio_context_acquire(aio_context); |
582 bdrv_do_drained_begin(bs, false, NULL, true, false); | 513 bdrv_do_drained_begin(bs, NULL, true, false); |
583 aio_context_release(aio_context); 584 } 585 586 /* Now poll the in-flight requests */ 587 AIO_WAIT_WHILE(NULL, bdrv_drain_all_poll()); 588 589 while ((bs = bdrv_next_all_states(bs))) { 590 bdrv_drain_assert_idle(bs); 591 } 592} 593 594void bdrv_drain_all_end_quiesce(BlockDriverState *bs) 595{ 596 GLOBAL_STATE_CODE(); 597 598 g_assert(bs->quiesce_counter > 0); 599 g_assert(!bs->refcnt); 600 601 while (bs->quiesce_counter) { | 514 aio_context_release(aio_context); 515 } 516 517 /* Now poll the in-flight requests */ 518 AIO_WAIT_WHILE(NULL, bdrv_drain_all_poll()); 519 520 while ((bs = bdrv_next_all_states(bs))) { 521 bdrv_drain_assert_idle(bs); 522 } 523} 524 525void bdrv_drain_all_end_quiesce(BlockDriverState *bs) 526{ 527 GLOBAL_STATE_CODE(); 528 529 g_assert(bs->quiesce_counter > 0); 530 g_assert(!bs->refcnt); 531 532 while (bs->quiesce_counter) { |
602 bdrv_do_drained_end(bs, false, NULL, true); | 533 bdrv_do_drained_end(bs, NULL, true); |
603 } 604} 605 606void bdrv_drain_all_end(void) 607{ 608 BlockDriverState *bs = NULL; 609 GLOBAL_STATE_CODE(); 610 --- 5 unchanged lines hidden (view full) --- 616 if (replay_events_enabled()) { 617 return; 618 } 619 620 while ((bs = bdrv_next_all_states(bs))) { 621 AioContext *aio_context = bdrv_get_aio_context(bs); 622 623 aio_context_acquire(aio_context); | 534 } 535} 536 537void bdrv_drain_all_end(void) 538{ 539 BlockDriverState *bs = NULL; 540 GLOBAL_STATE_CODE(); 541 --- 5 unchanged lines hidden (view full) --- 547 if (replay_events_enabled()) { 548 return; 549 } 550 551 while ((bs = bdrv_next_all_states(bs))) { 552 AioContext *aio_context = bdrv_get_aio_context(bs); 553 554 aio_context_acquire(aio_context); |
624 bdrv_do_drained_end(bs, false, NULL, true); | 555 bdrv_do_drained_end(bs, NULL, true); |
625 aio_context_release(aio_context); 626 } 627 628 assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 629 assert(bdrv_drain_all_count > 0); 630 bdrv_drain_all_count--; 631} 632 --- 2956 unchanged lines hidden --- | 556 aio_context_release(aio_context); 557 } 558 559 assert(qemu_get_current_aio_context() == qemu_get_aio_context()); 560 assert(bdrv_drain_all_count > 0); 561 bdrv_drain_all_count--; 562} 563 --- 2956 unchanged lines hidden --- |