Commit 6ae0516b8a50ece5d766be608a305707e0450060
Committed by
Jens Axboe
1 parent
4eabc94125
Exists in
master
and in
6 other branches
block, cfq: fix empty queue crash caused by request merge
All requests of a queue could be merged to other requests of other queue. Such queue will not have request in it, but it's in service tree. This will cause kernel oops. I encounter a BUG_ON() in cfq_dispatch_request() with next patch, but the issue should exist without the patch. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Showing 1 changed file with 12 additions and 0 deletions Side-by-side Diff
block/cfq-iosched.c
... | ... | @@ -1655,6 +1655,8 @@ |
1655 | 1655 | struct request *next) |
1656 | 1656 | { |
1657 | 1657 | struct cfq_queue *cfqq = RQ_CFQQ(rq); |
1658 | + struct cfq_data *cfqd = q->elevator->elevator_data; | |
1659 | + | |
1658 | 1660 | /* |
1659 | 1661 | * reposition in fifo if next is older than rq |
1660 | 1662 | */ |
... | ... | @@ -1669,6 +1671,16 @@ |
1669 | 1671 | cfq_remove_request(next); |
1670 | 1672 | cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg, |
1671 | 1673 | rq_data_dir(next), rq_is_sync(next)); |
1674 | + | |
1675 | + cfqq = RQ_CFQQ(next); | |
1676 | + /* | |
1677 | + * all requests of this queue are merged to other queues, delete it | |
1678 | + * from the service tree. If it's the active_queue, | |
1679 | + * cfq_dispatch_requests() will choose to expire it or do idle | |
1680 | + */ | |
1681 | + if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list) && | |
1682 | + cfqq != cfqd->active_queue) | |
1683 | + cfq_del_cfqq_rr(cfqd, cfqq); | |
1672 | 1684 | } |
1673 | 1685 | |
1674 | 1686 | static int cfq_allow_merge(struct request_queue *q, struct request *rq, |