aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-core.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-09-15 08:01:40 -0400
committerJens Axboe <axboe@kernel.dk>2011-09-15 08:01:40 -0400
commit27a84d54c02591e815d291ae0ee4bfb9cfd21065 (patch)
treea65129a8c7053241fe51886f279bb4522599b6b6 /block/blk-core.c
parent5a7bbad27a410350e64a2d7f5ec18fc73836c14f (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.c95
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/** 1415static noinline_for_stack bool
1416 * generic_make_request - hand a buffer to its device driver for I/O 1416generic_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 */
1439static 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
1523end_io: 1500end_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 */
1538void generic_make_request(struct bio *bio) 1529void 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 */