block: enumify ELEVATOR_*_MERGE

Switch these constants to an enum, and make let the compiler ensure that
all callers of blk_try_merge and elv_merge handle all potential values.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Christoph Hellwig 2017-02-08 14:46:48 +01:00 committed by Jens Axboe
parent 6cf7677f1a
commit 34fe7c0540
10 changed files with 103 additions and 102 deletions

View File

@ -1511,12 +1511,11 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
{ {
struct blk_plug *plug; struct blk_plug *plug;
struct request *rq; struct request *rq;
bool ret = false;
struct list_head *plug_list; struct list_head *plug_list;
plug = current->plug; plug = current->plug;
if (!plug) if (!plug)
goto out; return false;
*request_count = 0; *request_count = 0;
if (q->mq_ops) if (q->mq_ops)
@ -1525,7 +1524,7 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
plug_list = &plug->list; plug_list = &plug->list;
list_for_each_entry_reverse(rq, plug_list, queuelist) { list_for_each_entry_reverse(rq, plug_list, queuelist) {
int el_ret; bool merged = false;
if (rq->q == q) { if (rq->q == q) {
(*request_count)++; (*request_count)++;
@ -1541,19 +1540,22 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
if (rq->q != q || !blk_rq_merge_ok(rq, bio)) if (rq->q != q || !blk_rq_merge_ok(rq, bio))
continue; continue;
el_ret = blk_try_merge(rq, bio); switch (blk_try_merge(rq, bio)) {
if (el_ret == ELEVATOR_BACK_MERGE) { case ELEVATOR_BACK_MERGE:
ret = bio_attempt_back_merge(q, rq, bio); merged = bio_attempt_back_merge(q, rq, bio);
if (ret) break;
break; case ELEVATOR_FRONT_MERGE:
} else if (el_ret == ELEVATOR_FRONT_MERGE) { merged = bio_attempt_front_merge(q, rq, bio);
ret = bio_attempt_front_merge(q, rq, bio); break;
if (ret) default:
break; break;
} }
if (merged)
return true;
} }
out:
return ret; return false;
} }
unsigned int blk_plug_queued_count(struct request_queue *q) unsigned int blk_plug_queued_count(struct request_queue *q)
@ -1595,7 +1597,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio) static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
{ {
struct blk_plug *plug; struct blk_plug *plug;
int el_ret, where = ELEVATOR_INSERT_SORT; int where = ELEVATOR_INSERT_SORT;
struct request *req, *free; struct request *req, *free;
unsigned int request_count = 0; unsigned int request_count = 0;
unsigned int wb_acct; unsigned int wb_acct;
@ -1633,27 +1635,29 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
el_ret = elv_merge(q, &req, bio); switch (elv_merge(q, &req, bio)) {
if (el_ret == ELEVATOR_BACK_MERGE) { case ELEVATOR_BACK_MERGE:
if (bio_attempt_back_merge(q, req, bio)) { if (!bio_attempt_back_merge(q, req, bio))
elv_bio_merged(q, req, bio); break;
free = attempt_back_merge(q, req); elv_bio_merged(q, req, bio);
if (!free) free = attempt_back_merge(q, req);
elv_merged_request(q, req, el_ret); if (free)
else __blk_put_request(q, free);
__blk_put_request(q, free); else
goto out_unlock; elv_merged_request(q, req, ELEVATOR_BACK_MERGE);
} goto out_unlock;
} else if (el_ret == ELEVATOR_FRONT_MERGE) { case ELEVATOR_FRONT_MERGE:
if (bio_attempt_front_merge(q, req, bio)) { if (!bio_attempt_front_merge(q, req, bio))
elv_bio_merged(q, req, bio); break;
free = attempt_front_merge(q, req); elv_bio_merged(q, req, bio);
if (!free) free = attempt_front_merge(q, req);
elv_merged_request(q, req, el_ret); if (free)
else __blk_put_request(q, free);
__blk_put_request(q, free); else
goto out_unlock; elv_merged_request(q, req, ELEVATOR_FRONT_MERGE);
} goto out_unlock;
default:
break;
} }
get_rq: get_rq:

View File

@ -801,7 +801,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
return true; return true;
} }
int blk_try_merge(struct request *rq, struct bio *bio) enum elv_merge blk_try_merge(struct request *rq, struct bio *bio)
{ {
if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector) if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector)
return ELEVATOR_BACK_MERGE; return ELEVATOR_BACK_MERGE;

View File

@ -238,30 +238,29 @@ bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
struct request **merged_request) struct request **merged_request)
{ {
struct request *rq; struct request *rq;
int ret;
ret = elv_merge(q, &rq, bio); switch (elv_merge(q, &rq, bio)) {
if (ret == ELEVATOR_BACK_MERGE) { case ELEVATOR_BACK_MERGE:
if (!blk_mq_sched_allow_merge(q, rq, bio)) if (!blk_mq_sched_allow_merge(q, rq, bio))
return false; return false;
if (bio_attempt_back_merge(q, rq, bio)) { if (!bio_attempt_back_merge(q, rq, bio))
*merged_request = attempt_back_merge(q, rq); return false;
if (!*merged_request) *merged_request = attempt_back_merge(q, rq);
elv_merged_request(q, rq, ret); if (!*merged_request)
return true; elv_merged_request(q, rq, ELEVATOR_BACK_MERGE);
} return true;
} else if (ret == ELEVATOR_FRONT_MERGE) { case ELEVATOR_FRONT_MERGE:
if (!blk_mq_sched_allow_merge(q, rq, bio)) if (!blk_mq_sched_allow_merge(q, rq, bio))
return false; return false;
if (bio_attempt_front_merge(q, rq, bio)) { if (!bio_attempt_front_merge(q, rq, bio))
*merged_request = attempt_front_merge(q, rq); return false;
if (!*merged_request) *merged_request = attempt_front_merge(q, rq);
elv_merged_request(q, rq, ret); if (!*merged_request)
return true; elv_merged_request(q, rq, ELEVATOR_FRONT_MERGE);
} return true;
default:
return false;
} }
return false;
} }
EXPORT_SYMBOL_GPL(blk_mq_sched_try_merge); EXPORT_SYMBOL_GPL(blk_mq_sched_try_merge);

View File

@ -763,7 +763,7 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
int checked = 8; int checked = 8;
list_for_each_entry_reverse(rq, &ctx->rq_list, queuelist) { list_for_each_entry_reverse(rq, &ctx->rq_list, queuelist) {
int el_ret; bool merged = false;
if (!checked--) if (!checked--)
break; break;
@ -771,26 +771,22 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
if (!blk_rq_merge_ok(rq, bio)) if (!blk_rq_merge_ok(rq, bio))
continue; continue;
el_ret = blk_try_merge(rq, bio); switch (blk_try_merge(rq, bio)) {
if (el_ret == ELEVATOR_NO_MERGE) case ELEVATOR_BACK_MERGE:
if (blk_mq_sched_allow_merge(q, rq, bio))
merged = bio_attempt_back_merge(q, rq, bio);
break;
case ELEVATOR_FRONT_MERGE:
if (blk_mq_sched_allow_merge(q, rq, bio))
merged = bio_attempt_front_merge(q, rq, bio);
break;
default:
continue; continue;
if (!blk_mq_sched_allow_merge(q, rq, bio))
break;
if (el_ret == ELEVATOR_BACK_MERGE) {
if (bio_attempt_back_merge(q, rq, bio)) {
ctx->rq_merged++;
return true;
}
break;
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
if (bio_attempt_front_merge(q, rq, bio)) {
ctx->rq_merged++;
return true;
}
break;
} }
if (merged)
ctx->rq_merged++;
return merged;
} }
return false; return false;

View File

@ -215,7 +215,7 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
void blk_recalc_rq_segments(struct request *rq); void blk_recalc_rq_segments(struct request *rq);
void blk_rq_set_mixed_merge(struct request *rq); void blk_rq_set_mixed_merge(struct request *rq);
bool blk_rq_merge_ok(struct request *rq, struct bio *bio); bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
int blk_try_merge(struct request *rq, struct bio *bio); enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
void blk_queue_congestion_threshold(struct request_queue *q); void blk_queue_congestion_threshold(struct request_queue *q);

View File

@ -2528,7 +2528,7 @@ static void cfq_remove_request(struct request *rq)
} }
} }
static int cfq_merge(struct request_queue *q, struct request **req, static enum elv_merge cfq_merge(struct request_queue *q, struct request **req,
struct bio *bio) struct bio *bio)
{ {
struct cfq_data *cfqd = q->elevator->elevator_data; struct cfq_data *cfqd = q->elevator->elevator_data;
@ -2544,7 +2544,7 @@ static int cfq_merge(struct request_queue *q, struct request **req,
} }
static void cfq_merged_request(struct request_queue *q, struct request *req, static void cfq_merged_request(struct request_queue *q, struct request *req,
int type) enum elv_merge type)
{ {
if (type == ELEVATOR_FRONT_MERGE) { if (type == ELEVATOR_FRONT_MERGE) {
struct cfq_queue *cfqq = RQ_CFQQ(req); struct cfq_queue *cfqq = RQ_CFQQ(req);

View File

@ -120,12 +120,11 @@ static void deadline_remove_request(struct request_queue *q, struct request *rq)
deadline_del_rq_rb(dd, rq); deadline_del_rq_rb(dd, rq);
} }
static int static enum elv_merge
deadline_merge(struct request_queue *q, struct request **req, struct bio *bio) deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
{ {
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;
struct request *__rq; struct request *__rq;
int ret;
/* /*
* check for front merge * check for front merge
@ -138,20 +137,17 @@ deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
BUG_ON(sector != blk_rq_pos(__rq)); BUG_ON(sector != blk_rq_pos(__rq));
if (elv_bio_merge_ok(__rq, bio)) { if (elv_bio_merge_ok(__rq, bio)) {
ret = ELEVATOR_FRONT_MERGE; *req = __rq;
goto out; return ELEVATOR_FRONT_MERGE;
} }
} }
} }
return ELEVATOR_NO_MERGE; return ELEVATOR_NO_MERGE;
out:
*req = __rq;
return ret;
} }
static void deadline_merged_request(struct request_queue *q, static void deadline_merged_request(struct request_queue *q,
struct request *req, int type) struct request *req, enum elv_merge type)
{ {
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;

View File

@ -427,11 +427,11 @@ void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
} }
EXPORT_SYMBOL(elv_dispatch_add_tail); EXPORT_SYMBOL(elv_dispatch_add_tail);
int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) enum elv_merge elv_merge(struct request_queue *q, struct request **req,
struct bio *bio)
{ {
struct elevator_queue *e = q->elevator; struct elevator_queue *e = q->elevator;
struct request *__rq; struct request *__rq;
int ret;
/* /*
* Levels of merges: * Levels of merges:
@ -446,7 +446,8 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
* First try one-hit cache. * First try one-hit cache.
*/ */
if (q->last_merge && elv_bio_merge_ok(q->last_merge, bio)) { if (q->last_merge && elv_bio_merge_ok(q->last_merge, bio)) {
ret = blk_try_merge(q->last_merge, bio); enum elv_merge ret = blk_try_merge(q->last_merge, bio);
if (ret != ELEVATOR_NO_MERGE) { if (ret != ELEVATOR_NO_MERGE) {
*req = q->last_merge; *req = q->last_merge;
return ret; return ret;
@ -514,7 +515,8 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
return ret; return ret;
} }
void elv_merged_request(struct request_queue *q, struct request *rq, int type) void elv_merged_request(struct request_queue *q, struct request *rq,
enum elv_merge type)
{ {
struct elevator_queue *e = q->elevator; struct elevator_queue *e = q->elevator;

View File

@ -121,7 +121,7 @@ static void deadline_remove_request(struct request_queue *q, struct request *rq)
} }
static void dd_request_merged(struct request_queue *q, struct request *req, static void dd_request_merged(struct request_queue *q, struct request *req,
int type) enum elv_merge type)
{ {
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;

View File

@ -9,12 +9,21 @@
struct io_cq; struct io_cq;
struct elevator_type; struct elevator_type;
typedef int (elevator_merge_fn) (struct request_queue *, struct request **, /*
* Return values from elevator merger
*/
enum elv_merge {
ELEVATOR_NO_MERGE = 0,
ELEVATOR_FRONT_MERGE = 1,
ELEVATOR_BACK_MERGE = 2,
};
typedef enum elv_merge (elevator_merge_fn) (struct request_queue *, struct request **,
struct bio *); struct bio *);
typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *); typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *);
typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int); typedef void (elevator_merged_fn) (struct request_queue *, struct request *, enum elv_merge);
typedef int (elevator_allow_bio_merge_fn) (struct request_queue *, typedef int (elevator_allow_bio_merge_fn) (struct request_queue *,
struct request *, struct bio *); struct request *, struct bio *);
@ -87,7 +96,7 @@ struct elevator_mq_ops {
bool (*allow_merge)(struct request_queue *, struct request *, struct bio *); bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *); bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *);
int (*request_merge)(struct request_queue *q, struct request **, struct bio *); int (*request_merge)(struct request_queue *q, struct request **, struct bio *);
void (*request_merged)(struct request_queue *, struct request *, int); void (*request_merged)(struct request_queue *, struct request *, enum elv_merge);
void (*requests_merged)(struct request_queue *, struct request *, struct request *); void (*requests_merged)(struct request_queue *, struct request *, struct request *);
struct request *(*get_request)(struct request_queue *, unsigned int, struct blk_mq_alloc_data *); struct request *(*get_request)(struct request_queue *, unsigned int, struct blk_mq_alloc_data *);
void (*put_request)(struct request *); void (*put_request)(struct request *);
@ -166,10 +175,12 @@ extern void elv_dispatch_sort(struct request_queue *, struct request *);
extern void elv_dispatch_add_tail(struct request_queue *, struct request *); extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
extern void elv_add_request(struct request_queue *, struct request *, int); extern void elv_add_request(struct request_queue *, struct request *, int);
extern void __elv_add_request(struct request_queue *, struct request *, int); extern void __elv_add_request(struct request_queue *, struct request *, int);
extern int elv_merge(struct request_queue *, struct request **, struct bio *); extern enum elv_merge elv_merge(struct request_queue *, struct request **,
struct bio *);
extern void elv_merge_requests(struct request_queue *, struct request *, extern void elv_merge_requests(struct request_queue *, struct request *,
struct request *); struct request *);
extern void elv_merged_request(struct request_queue *, struct request *, int); extern void elv_merged_request(struct request_queue *, struct request *,
enum elv_merge);
extern void elv_bio_merged(struct request_queue *q, struct request *, extern void elv_bio_merged(struct request_queue *q, struct request *,
struct bio *); struct bio *);
extern bool elv_attempt_insert_merge(struct request_queue *, struct request *); extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
@ -218,13 +229,6 @@ extern void elv_rb_add(struct rb_root *, struct request *);
extern void elv_rb_del(struct rb_root *, struct request *); extern void elv_rb_del(struct rb_root *, struct request *);
extern struct request *elv_rb_find(struct rb_root *, sector_t); extern struct request *elv_rb_find(struct rb_root *, sector_t);
/*
* Return values from elevator merger
*/
#define ELEVATOR_NO_MERGE 0
#define ELEVATOR_FRONT_MERGE 1
#define ELEVATOR_BACK_MERGE 2
/* /*
* Insertion selection * Insertion selection
*/ */