Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
* 'for-linus' of git://git.kernel.dk/linux-block:
  block: fix blk_queue_end_tag()
  block: re-use existing 'reading' variable instead of checking direction again
  block, cfq: fix empty queue crash caused by request merge
  • Loading branch information
Linus Torvalds committed Dec 30, 2011
2 parents b0365c8 + f2b20d4 commit 1cac8e8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 12 deletions.
2 changes: 1 addition & 1 deletion block/blk-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
if (IS_ERR(bio))
return PTR_ERR(bio);

if (rq_data_dir(rq) == WRITE)
if (!reading)
bio->bi_rw |= REQ_WRITE;

if (do_copy)
Expand Down
13 changes: 2 additions & 11 deletions block/blk-tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,18 +282,9 @@ EXPORT_SYMBOL(blk_queue_resize_tags);
void blk_queue_end_tag(struct request_queue *q, struct request *rq)
{
struct blk_queue_tag *bqt = q->queue_tags;
int tag = rq->tag;
unsigned tag = rq->tag; /* negative tags invalid */

BUG_ON(tag == -1);

if (unlikely(tag >= bqt->max_depth)) {
/*
* This can happen after tag depth has been reduced.
* But tag shouldn't be larger than real_max_depth.
*/
WARN_ON(tag >= bqt->real_max_depth);
return;
}
BUG_ON(tag >= bqt->real_max_depth);

list_del_init(&rq->queuelist);
rq->cmd_flags &= ~REQ_QUEUED;
Expand Down
12 changes: 12 additions & 0 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,8 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
struct request *next)
{
struct cfq_queue *cfqq = RQ_CFQQ(rq);
struct cfq_data *cfqd = q->elevator->elevator_data;

/*
* reposition in fifo if next is older than rq
*/
Expand All @@ -1669,6 +1671,16 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
cfq_remove_request(next);
cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg,
rq_data_dir(next), rq_is_sync(next));

cfqq = RQ_CFQQ(next);
/*
* all requests of this queue are merged to other queues, delete it
* from the service tree. If it's the active_queue,
* cfq_dispatch_requests() will choose to expire it or do idle
*/
if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list) &&
cfqq != cfqd->active_queue)
cfq_del_cfqq_rr(cfqd, cfqq);
}

static int cfq_allow_merge(struct request_queue *q, struct request *rq,
Expand Down

0 comments on commit 1cac8e8

Please sign in to comment.