Skip to content

Commit

Permalink
block: enumify ELEVATOR_*_MERGE
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Feb 8, 2017
1 parent 6cf7677 commit 34fe7c0
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 101 deletions.
76 changes: 40 additions & 36 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1511,12 +1511,11 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
{
struct blk_plug *plug;
struct request *rq;
bool ret = false;
struct list_head *plug_list;

plug = current->plug;
if (!plug)
goto out;
return false;
*request_count = 0;

if (q->mq_ops)
Expand All @@ -1525,7 +1524,7 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
plug_list = &plug->list;

list_for_each_entry_reverse(rq, plug_list, queuelist) {
int el_ret;
bool merged = false;

if (rq->q == q) {
(*request_count)++;
Expand All @@ -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))
continue;

el_ret = blk_try_merge(rq, bio);
if (el_ret == ELEVATOR_BACK_MERGE) {
ret = bio_attempt_back_merge(q, rq, bio);
if (ret)
break;
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
ret = bio_attempt_front_merge(q, rq, bio);
if (ret)
break;
switch (blk_try_merge(rq, bio)) {
case ELEVATOR_BACK_MERGE:
merged = bio_attempt_back_merge(q, rq, bio);
break;
case ELEVATOR_FRONT_MERGE:
merged = bio_attempt_front_merge(q, rq, bio);
break;
default:
break;
}

if (merged)
return true;
}
out:
return ret;

return false;
}

unsigned int blk_plug_queued_count(struct request_queue *q)
Expand Down Expand Up @@ -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)
{
struct blk_plug *plug;
int el_ret, where = ELEVATOR_INSERT_SORT;
int where = ELEVATOR_INSERT_SORT;
struct request *req, *free;
unsigned int request_count = 0;
unsigned int wb_acct;
Expand Down Expand Up @@ -1633,27 +1635,29 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)

spin_lock_irq(q->queue_lock);

el_ret = elv_merge(q, &req, bio);
if (el_ret == ELEVATOR_BACK_MERGE) {
if (bio_attempt_back_merge(q, req, bio)) {
elv_bio_merged(q, req, bio);
free = attempt_back_merge(q, req);
if (!free)
elv_merged_request(q, req, el_ret);
else
__blk_put_request(q, free);
goto out_unlock;
}
} else if (el_ret == ELEVATOR_FRONT_MERGE) {
if (bio_attempt_front_merge(q, req, bio)) {
elv_bio_merged(q, req, bio);
free = attempt_front_merge(q, req);
if (!free)
elv_merged_request(q, req, el_ret);
else
__blk_put_request(q, free);
goto out_unlock;
}
switch (elv_merge(q, &req, bio)) {
case ELEVATOR_BACK_MERGE:
if (!bio_attempt_back_merge(q, req, bio))
break;
elv_bio_merged(q, req, bio);
free = attempt_back_merge(q, req);
if (free)
__blk_put_request(q, free);
else
elv_merged_request(q, req, ELEVATOR_BACK_MERGE);
goto out_unlock;
case ELEVATOR_FRONT_MERGE:
if (!bio_attempt_front_merge(q, req, bio))
break;
elv_bio_merged(q, req, bio);
free = attempt_front_merge(q, req);
if (free)
__blk_put_request(q, free);
else
elv_merged_request(q, req, ELEVATOR_FRONT_MERGE);
goto out_unlock;
default:
break;
}

get_rq:
Expand Down
2 changes: 1 addition & 1 deletion block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
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)
return ELEVATOR_BACK_MERGE;
Expand Down
35 changes: 17 additions & 18 deletions block/blk-mq-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,30 +238,29 @@ bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
struct request **merged_request)
{
struct request *rq;
int ret;

ret = elv_merge(q, &rq, bio);
if (ret == ELEVATOR_BACK_MERGE) {
switch (elv_merge(q, &rq, bio)) {
case ELEVATOR_BACK_MERGE:
if (!blk_mq_sched_allow_merge(q, rq, bio))
return false;
if (bio_attempt_back_merge(q, rq, bio)) {
*merged_request = attempt_back_merge(q, rq);
if (!*merged_request)
elv_merged_request(q, rq, ret);
return true;
}
} else if (ret == ELEVATOR_FRONT_MERGE) {
if (!bio_attempt_back_merge(q, rq, bio))
return false;
*merged_request = attempt_back_merge(q, rq);
if (!*merged_request)
elv_merged_request(q, rq, ELEVATOR_BACK_MERGE);
return true;
case ELEVATOR_FRONT_MERGE:
if (!blk_mq_sched_allow_merge(q, rq, bio))
return false;
if (bio_attempt_front_merge(q, rq, bio)) {
*merged_request = attempt_front_merge(q, rq);
if (!*merged_request)
elv_merged_request(q, rq, ret);
return true;
}
if (!bio_attempt_front_merge(q, rq, bio))
return false;
*merged_request = attempt_front_merge(q, rq);
if (!*merged_request)
elv_merged_request(q, rq, ELEVATOR_FRONT_MERGE);
return true;
default:
return false;
}

return false;
}
EXPORT_SYMBOL_GPL(blk_mq_sched_try_merge);

Expand Down
32 changes: 14 additions & 18 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,34 +763,30 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
int checked = 8;

list_for_each_entry_reverse(rq, &ctx->rq_list, queuelist) {
int el_ret;
bool merged = false;

if (!checked--)
break;

if (!blk_rq_merge_ok(rq, bio))
continue;

el_ret = blk_try_merge(rq, bio);
if (el_ret == ELEVATOR_NO_MERGE)
continue;

if (!blk_mq_sched_allow_merge(q, rq, bio))
switch (blk_try_merge(rq, bio)) {
case ELEVATOR_BACK_MERGE:
if (blk_mq_sched_allow_merge(q, rq, bio))
merged = bio_attempt_back_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;
}
case ELEVATOR_FRONT_MERGE:
if (blk_mq_sched_allow_merge(q, rq, bio))
merged = bio_attempt_front_merge(q, rq, bio);
break;
default:
continue;
}

if (merged)
ctx->rq_merged++;
return merged;
}

return false;
Expand Down
2 changes: 1 addition & 1 deletion block/blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_rq_set_mixed_merge(struct request *rq);
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);

Expand Down
4 changes: 2 additions & 2 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 cfq_data *cfqd = q->elevator->elevator_data;
Expand All @@ -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,
int type)
enum elv_merge type)
{
if (type == ELEVATOR_FRONT_MERGE) {
struct cfq_queue *cfqq = RQ_CFQQ(req);
Expand Down
12 changes: 4 additions & 8 deletions block/deadline-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,11 @@ static void deadline_remove_request(struct request_queue *q, struct request *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)
{
struct deadline_data *dd = q->elevator->elevator_data;
struct request *__rq;
int ret;

/*
* check for front merge
Expand All @@ -138,20 +137,17 @@ deadline_merge(struct request_queue *q, struct request **req, struct bio *bio)
BUG_ON(sector != blk_rq_pos(__rq));

if (elv_bio_merge_ok(__rq, bio)) {
ret = ELEVATOR_FRONT_MERGE;
goto out;
*req = __rq;
return ELEVATOR_FRONT_MERGE;
}
}
}

return ELEVATOR_NO_MERGE;
out:
*req = __rq;
return ret;
}

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;

Expand Down
10 changes: 6 additions & 4 deletions block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,11 @@ void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
}
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 request *__rq;
int ret;

/*
* Levels of merges:
Expand All @@ -446,7 +446,8 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
* First try one-hit cache.
*/
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) {
*req = q->last_merge;
return ret;
Expand Down Expand Up @@ -514,7 +515,8 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
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;

Expand Down
2 changes: 1 addition & 1 deletion block/mq-deadline.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
int type)
enum elv_merge type)
{
struct deadline_data *dd = q->elevator->elevator_data;

Expand Down
28 changes: 16 additions & 12 deletions include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@
struct io_cq;
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 *);

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 *,
struct request *, struct bio *);
Expand Down Expand Up @@ -87,7 +96,7 @@ struct elevator_mq_ops {
bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
bool (*bio_merge)(struct blk_mq_hw_ctx *, 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 *);
struct request *(*get_request)(struct request_queue *, unsigned int, struct blk_mq_alloc_data *);
void (*put_request)(struct request *);
Expand Down Expand Up @@ -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_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 *,
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 *,
struct bio *);
extern bool elv_attempt_insert_merge(struct request_queue *, struct request *);
Expand Down Expand Up @@ -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 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
*/
Expand Down

0 comments on commit 34fe7c0

Please sign in to comment.