diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-09-15 08:01:40 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-09-15 08:01:40 -0400 |
commit | 27a84d54c02591e815d291ae0ee4bfb9cfd21065 (patch) | |
tree | a65129a8c7053241fe51886f279bb4522599b6b6 /block/blk-core.c | |
parent | 5a7bbad27a410350e64a2d7f5ec18fc73836c14f (diff) |
block: refactor generic_make_request
Move all the checks performed on a bio into a new helper, and call it as
soon as bio is submitted even if it is a re-submission from ->make_request.
We explicitly mark the new helper as beeing non-inlined as the stack
usage for printing the block device name in the failure case is quite
high and this a patch where we have to be extremely conservative about
stack usage.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-core.c')
-rw-r--r-- | block/blk-core.c | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index f58e019be67b..684d7eb33d43 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1412,31 +1412,8 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors) | |||
1412 | return 0; | 1412 | return 0; |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | /** | 1415 | static noinline_for_stack bool |
1416 | * generic_make_request - hand a buffer to its device driver for I/O | 1416 | generic_make_request_checks(struct bio *bio) |
1417 | * @bio: The bio describing the location in memory and on the device. | ||
1418 | * | ||
1419 | * generic_make_request() is used to make I/O requests of block | ||
1420 | * devices. It is passed a &struct bio, which describes the I/O that needs | ||
1421 | * to be done. | ||
1422 | * | ||
1423 | * generic_make_request() does not return any status. The | ||
1424 | * success/failure status of the request, along with notification of | ||
1425 | * completion, is delivered asynchronously through the bio->bi_end_io | ||
1426 | * function described (one day) else where. | ||
1427 | * | ||
1428 | * The caller of generic_make_request must make sure that bi_io_vec | ||
1429 | * are set to describe the memory buffer, and that bi_dev and bi_sector are | ||
1430 | * set to describe the device address, and the | ||
1431 | * bi_end_io and optionally bi_private are set to describe how | ||
1432 | * completion notification should be signaled. | ||
1433 | * | ||
1434 | * generic_make_request and the drivers it calls may use bi_next if this | ||
1435 | * bio happens to be merged with someone else, and may change bi_dev and | ||
1436 | * bi_sector for remaps as it sees fit. So the values of these fields | ||
1437 | * should NOT be depended on after the call to generic_make_request. | ||
1438 | */ | ||
1439 | static inline void __generic_make_request(struct bio *bio) | ||
1440 | { | 1417 | { |
1441 | struct request_queue *q; | 1418 | struct request_queue *q; |
1442 | int nr_sectors = bio_sectors(bio); | 1419 | int nr_sectors = bio_sectors(bio); |
@@ -1515,35 +1492,62 @@ static inline void __generic_make_request(struct bio *bio) | |||
1515 | 1492 | ||
1516 | /* if bio = NULL, bio has been throttled and will be submitted later. */ | 1493 | /* if bio = NULL, bio has been throttled and will be submitted later. */ |
1517 | if (!bio) | 1494 | if (!bio) |
1518 | return; | 1495 | return false; |
1496 | |||
1519 | trace_block_bio_queue(q, bio); | 1497 | trace_block_bio_queue(q, bio); |
1520 | q->make_request_fn(q, bio); | 1498 | return true; |
1521 | return; | ||
1522 | 1499 | ||
1523 | end_io: | 1500 | end_io: |
1524 | bio_endio(bio, err); | 1501 | bio_endio(bio, err); |
1502 | return false; | ||
1525 | } | 1503 | } |
1526 | 1504 | ||
1527 | /* | 1505 | /** |
1528 | * We only want one ->make_request_fn to be active at a time, | 1506 | * generic_make_request - hand a buffer to its device driver for I/O |
1529 | * else stack usage with stacked devices could be a problem. | 1507 | * @bio: The bio describing the location in memory and on the device. |
1530 | * So use current->bio_list to keep a list of requests | 1508 | * |
1531 | * submited by a make_request_fn function. | 1509 | * generic_make_request() is used to make I/O requests of block |
1532 | * current->bio_list is also used as a flag to say if | 1510 | * devices. It is passed a &struct bio, which describes the I/O that needs |
1533 | * generic_make_request is currently active in this task or not. | 1511 | * to be done. |
1534 | * If it is NULL, then no make_request is active. If it is non-NULL, | 1512 | * |
1535 | * then a make_request is active, and new requests should be added | 1513 | * generic_make_request() does not return any status. The |
1536 | * at the tail | 1514 | * success/failure status of the request, along with notification of |
1515 | * completion, is delivered asynchronously through the bio->bi_end_io | ||
1516 | * function described (one day) else where. | ||
1517 | * | ||
1518 | * The caller of generic_make_request must make sure that bi_io_vec | ||
1519 | * are set to describe the memory buffer, and that bi_dev and bi_sector are | ||
1520 | * set to describe the device address, and the | ||
1521 | * bi_end_io and optionally bi_private are set to describe how | ||
1522 | * completion notification should be signaled. | ||
1523 | * | ||
1524 | * generic_make_request and the drivers it calls may use bi_next if this | ||
1525 | * bio happens to be merged with someone else, and may resubmit the bio to | ||
1526 | * a lower device by calling into generic_make_request recursively, which | ||
1527 | * means the bio should NOT be touched after the call to ->make_request_fn. | ||
1537 | */ | 1528 | */ |
1538 | void generic_make_request(struct bio *bio) | 1529 | void generic_make_request(struct bio *bio) |
1539 | { | 1530 | { |
1540 | struct bio_list bio_list_on_stack; | 1531 | struct bio_list bio_list_on_stack; |
1541 | 1532 | ||
1533 | if (!generic_make_request_checks(bio)) | ||
1534 | return; | ||
1535 | |||
1536 | /* | ||
1537 | * We only want one ->make_request_fn to be active at a time, else | ||
1538 | * stack usage with stacked devices could be a problem. So use | ||
1539 | * current->bio_list to keep a list of requests submited by a | ||
1540 | * make_request_fn function. current->bio_list is also used as a | ||
1541 | * flag to say if generic_make_request is currently active in this | ||
1542 | * task or not. If it is NULL, then no make_request is active. If | ||
1543 | * it is non-NULL, then a make_request is active, and new requests | ||
1544 | * should be added at the tail | ||
1545 | */ | ||
1542 | if (current->bio_list) { | 1546 | if (current->bio_list) { |
1543 | /* make_request is active */ | ||
1544 | bio_list_add(current->bio_list, bio); | 1547 | bio_list_add(current->bio_list, bio); |
1545 | return; | 1548 | return; |
1546 | } | 1549 | } |
1550 | |||
1547 | /* following loop may be a bit non-obvious, and so deserves some | 1551 | /* following loop may be a bit non-obvious, and so deserves some |
1548 | * explanation. | 1552 | * explanation. |
1549 | * Before entering the loop, bio->bi_next is NULL (as all callers | 1553 | * Before entering the loop, bio->bi_next is NULL (as all callers |
@@ -1551,22 +1555,21 @@ void generic_make_request(struct bio *bio) | |||
1551 | * We pretend that we have just taken it off a longer list, so | 1555 | * We pretend that we have just taken it off a longer list, so |
1552 | * we assign bio_list to a pointer to the bio_list_on_stack, | 1556 | * we assign bio_list to a pointer to the bio_list_on_stack, |
1553 | * thus initialising the bio_list of new bios to be | 1557 | * thus initialising the bio_list of new bios to be |
1554 | * added. __generic_make_request may indeed add some more bios | 1558 | * added. ->make_request() may indeed add some more bios |
1555 | * through a recursive call to generic_make_request. If it | 1559 | * through a recursive call to generic_make_request. If it |
1556 | * did, we find a non-NULL value in bio_list and re-enter the loop | 1560 | * did, we find a non-NULL value in bio_list and re-enter the loop |
1557 | * from the top. In this case we really did just take the bio | 1561 | * from the top. In this case we really did just take the bio |
1558 | * of the top of the list (no pretending) and so remove it from | 1562 | * of the top of the list (no pretending) and so remove it from |
1559 | * bio_list, and call into __generic_make_request again. | 1563 | * bio_list, and call into ->make_request() again. |
1560 | * | ||
1561 | * The loop was structured like this to make only one call to | ||
1562 | * __generic_make_request (which is important as it is large and | ||
1563 | * inlined) and to keep the structure simple. | ||
1564 | */ | 1564 | */ |
1565 | BUG_ON(bio->bi_next); | 1565 | BUG_ON(bio->bi_next); |
1566 | bio_list_init(&bio_list_on_stack); | 1566 | bio_list_init(&bio_list_on_stack); |
1567 | current->bio_list = &bio_list_on_stack; | 1567 | current->bio_list = &bio_list_on_stack; |
1568 | do { | 1568 | do { |
1569 | __generic_make_request(bio); | 1569 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); |
1570 | |||
1571 | q->make_request_fn(q, bio); | ||
1572 | |||
1570 | bio = bio_list_pop(current->bio_list); | 1573 | bio = bio_list_pop(current->bio_list); |
1571 | } while (bio); | 1574 | } while (bio); |
1572 | current->bio_list = NULL; /* deactivate */ | 1575 | current->bio_list = NULL; /* deactivate */ |