Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309278
b: refs/heads/master
c: aaf7c68
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jens Axboe committed Apr 20, 2012
1 parent c23d226 commit f2c7fca
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 29e2b09ab5fa790514d47838f3c05497130908b3
refs/heads/master: aaf7c680682f1999ef2e574f743c45d1674a8b8a
53 changes: 36 additions & 17 deletions trunk/block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/fault-inject.h>
#include <linux/list_sort.h>
#include <linux/delay.h>
#include <linux/ratelimit.h>

#define CREATE_TRACE_POINTS
#include <trace/events/block.h>
Expand Down Expand Up @@ -930,17 +931,6 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
rw_flags |= REQ_IO_STAT;
spin_unlock_irq(q->queue_lock);

/* create icq if missing */
if ((rw_flags & REQ_ELVPRIV) && unlikely(et->icq_cache && !icq)) {
create_io_context(gfp_mask, q->node);
ioc = rq_ioc(bio);
if (!ioc)
goto fail_alloc;
icq = ioc_create_icq(ioc, q, gfp_mask);
if (!icq)
goto fail_alloc;
}

/* allocate and init request */
rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
if (!rq)
Expand All @@ -949,17 +939,28 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
blk_rq_init(q, rq);
rq->cmd_flags = rw_flags | REQ_ALLOCED;

/* init elvpriv */
if (rw_flags & REQ_ELVPRIV) {
rq->elv.icq = icq;
if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
mempool_free(rq, q->rq.rq_pool);
goto fail_alloc;
if (unlikely(et->icq_cache && !icq)) {
create_io_context(gfp_mask, q->node);
ioc = rq_ioc(bio);
if (!ioc)
goto fail_elvpriv;

icq = ioc_create_icq(ioc, q, gfp_mask);
if (!icq)
goto fail_elvpriv;
}
/* @rq->elv.icq holds on to io_context until @rq is freed */

rq->elv.icq = icq;
if (unlikely(elv_set_request(q, rq, bio, gfp_mask)))
goto fail_elvpriv;

/* @rq->elv.icq holds io_context until @rq is freed */
if (icq)
get_io_context(icq->ioc);
}

out:
/*
* ioc may be NULL here, and ioc_batching will be false. That's
* OK, if the queue is under the request limit then requests need
Expand All @@ -972,6 +973,24 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
trace_block_getrq(q, bio, rw_flags & 1);
return rq;

fail_elvpriv:
/*
* elvpriv init failed. ioc, icq and elvpriv aren't mempool backed
* and may fail indefinitely under memory pressure and thus
* shouldn't stall IO. Treat this request as !elvpriv. This will
* disturb iosched and blkcg but weird is bettern than dead.
*/
printk_ratelimited(KERN_WARNING "%s: request aux data allocation failed, iosched may be disturbed\n",
dev_name(q->backing_dev_info.dev));

rq->cmd_flags &= ~REQ_ELVPRIV;
rq->elv.icq = NULL;

spin_lock_irq(q->queue_lock);
rl->elvpriv--;
spin_unlock_irq(q->queue_lock);
goto out;

fail_alloc:
/*
* Allocation failed presumably due to memory. Undo anything we
Expand Down

0 comments on commit f2c7fca

Please sign in to comment.