Commit 65299a3b authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

block: separate priority boosting from REQ_META

Add a new REQ_PRIO to let requests preempt others in the cfq I/O schedule,
and lave REQ_META purely for marking requests as metadata in blktrace.

All existing callers of REQ_META except for XFS are updated to also
set REQ_PRIO for now.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent 5dc06c5a
...@@ -130,8 +130,8 @@ struct cfq_queue { ...@@ -130,8 +130,8 @@ struct cfq_queue {
unsigned long slice_end; unsigned long slice_end;
long slice_resid; long slice_resid;
/* pending metadata requests */ /* pending priority requests */
int meta_pending; int prio_pending;
/* number of requests that are on the dispatch list or inside driver */ /* number of requests that are on the dispatch list or inside driver */
int dispatched; int dispatched;
...@@ -684,8 +684,8 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2, ...@@ -684,8 +684,8 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2,
if (rq_is_sync(rq1) != rq_is_sync(rq2)) if (rq_is_sync(rq1) != rq_is_sync(rq2))
return rq_is_sync(rq1) ? rq1 : rq2; return rq_is_sync(rq1) ? rq1 : rq2;
if ((rq1->cmd_flags ^ rq2->cmd_flags) & REQ_META) if ((rq1->cmd_flags ^ rq2->cmd_flags) & REQ_PRIO)
return rq1->cmd_flags & REQ_META ? rq1 : rq2; return rq1->cmd_flags & REQ_PRIO ? rq1 : rq2;
s1 = blk_rq_pos(rq1); s1 = blk_rq_pos(rq1);
s2 = blk_rq_pos(rq2); s2 = blk_rq_pos(rq2);
...@@ -1612,9 +1612,9 @@ static void cfq_remove_request(struct request *rq) ...@@ -1612,9 +1612,9 @@ static void cfq_remove_request(struct request *rq)
cfqq->cfqd->rq_queued--; cfqq->cfqd->rq_queued--;
cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg,
rq_data_dir(rq), rq_is_sync(rq)); rq_data_dir(rq), rq_is_sync(rq));
if (rq->cmd_flags & REQ_META) { if (rq->cmd_flags & REQ_PRIO) {
WARN_ON(!cfqq->meta_pending); WARN_ON(!cfqq->prio_pending);
cfqq->meta_pending--; cfqq->prio_pending--;
} }
} }
...@@ -3372,7 +3372,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, ...@@ -3372,7 +3372,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
* So both queues are sync. Let the new request get disk time if * So both queues are sync. Let the new request get disk time if
* it's a metadata request and the current queue is doing regular IO. * it's a metadata request and the current queue is doing regular IO.
*/ */
if ((rq->cmd_flags & REQ_META) && !cfqq->meta_pending) if ((rq->cmd_flags & REQ_PRIO) && !cfqq->prio_pending)
return true; return true;
/* /*
...@@ -3439,8 +3439,8 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -3439,8 +3439,8 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
struct cfq_io_context *cic = RQ_CIC(rq); struct cfq_io_context *cic = RQ_CIC(rq);
cfqd->rq_queued++; cfqd->rq_queued++;
if (rq->cmd_flags & REQ_META) if (rq->cmd_flags & REQ_PRIO)
cfqq->meta_pending++; cfqq->prio_pending++;
cfq_update_io_thinktime(cfqd, cfqq, cic); cfq_update_io_thinktime(cfqd, cfqq, cic);
cfq_update_io_seektime(cfqd, cfqq, rq); cfq_update_io_seektime(cfqd, cfqq, rq);
......
...@@ -926,6 +926,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, ...@@ -926,6 +926,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
/* /*
* Reliable writes are used to implement Forced Unit Access and * Reliable writes are used to implement Forced Unit Access and
* REQ_META accesses, and are supported only on MMCs. * REQ_META accesses, and are supported only on MMCs.
*
* XXX: this really needs a good explanation of why REQ_META
* is treated special.
*/ */
bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
(req->cmd_flags & REQ_META)) && (req->cmd_flags & REQ_META)) &&
......
...@@ -1134,7 +1134,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode, ...@@ -1134,7 +1134,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode,
return bh; return bh;
if (buffer_uptodate(bh)) if (buffer_uptodate(bh))
return bh; return bh;
ll_rw_block(READ | REQ_META, 1, &bh); ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (buffer_uptodate(bh)) if (buffer_uptodate(bh))
return bh; return bh;
...@@ -2807,7 +2807,7 @@ static int __ext3_get_inode_loc(struct inode *inode, ...@@ -2807,7 +2807,7 @@ static int __ext3_get_inode_loc(struct inode *inode,
trace_ext3_load_inode(inode); trace_ext3_load_inode(inode);
get_bh(bh); get_bh(bh);
bh->b_end_io = end_buffer_read_sync; bh->b_end_io = end_buffer_read_sync;
submit_bh(READ | REQ_META, bh); submit_bh(READ | REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
ext3_error(inode->i_sb, "ext3_get_inode_loc", ext3_error(inode->i_sb, "ext3_get_inode_loc",
......
...@@ -922,7 +922,8 @@ static struct buffer_head *ext3_find_entry(struct inode *dir, ...@@ -922,7 +922,8 @@ static struct buffer_head *ext3_find_entry(struct inode *dir,
bh = ext3_getblk(NULL, dir, b++, 0, &err); bh = ext3_getblk(NULL, dir, b++, 0, &err);
bh_use[ra_max] = bh; bh_use[ra_max] = bh;
if (bh) if (bh)
ll_rw_block(READ | REQ_META, 1, &bh); ll_rw_block(READ | REQ_META | REQ_PRIO,
1, &bh);
} }
} }
if ((bh = bh_use[ra_ptr++]) == NULL) if ((bh = bh_use[ra_ptr++]) == NULL)
......
...@@ -650,7 +650,7 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, ...@@ -650,7 +650,7 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
return bh; return bh;
if (buffer_uptodate(bh)) if (buffer_uptodate(bh))
return bh; return bh;
ll_rw_block(READ | REQ_META, 1, &bh); ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (buffer_uptodate(bh)) if (buffer_uptodate(bh))
return bh; return bh;
...@@ -3301,7 +3301,7 @@ static int __ext4_get_inode_loc(struct inode *inode, ...@@ -3301,7 +3301,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
trace_ext4_load_inode(inode); trace_ext4_load_inode(inode);
get_bh(bh); get_bh(bh);
bh->b_end_io = end_buffer_read_sync; bh->b_end_io = end_buffer_read_sync;
submit_bh(READ | REQ_META, bh); submit_bh(READ | REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
EXT4_ERROR_INODE_BLOCK(inode, block, EXT4_ERROR_INODE_BLOCK(inode, block,
......
...@@ -922,7 +922,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, ...@@ -922,7 +922,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
bh = ext4_getblk(NULL, dir, b++, 0, &err); bh = ext4_getblk(NULL, dir, b++, 0, &err);
bh_use[ra_max] = bh; bh_use[ra_max] = bh;
if (bh) if (bh)
ll_rw_block(READ | REQ_META, 1, &bh); ll_rw_block(READ | REQ_META | REQ_PRIO,
1, &bh);
} }
} }
if ((bh = bh_use[ra_ptr++]) == NULL) if ((bh = bh_use[ra_ptr++]) == NULL)
......
...@@ -624,9 +624,9 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) ...@@ -624,9 +624,9 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
bh->b_end_io = end_buffer_write_sync; bh->b_end_io = end_buffer_write_sync;
get_bh(bh); get_bh(bh);
if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
submit_bh(WRITE_SYNC | REQ_META, bh); submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh);
else else
submit_bh(WRITE_FLUSH_FUA | REQ_META, bh); submit_bh(WRITE_FLUSH_FUA | REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) if (!buffer_uptodate(bh))
......
...@@ -37,7 +37,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb ...@@ -37,7 +37,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb
{ {
struct buffer_head *bh, *head; struct buffer_head *bh, *head;
int nr_underway = 0; int nr_underway = 0;
int write_op = REQ_META | int write_op = REQ_META | REQ_PRIO |
(wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
BUG_ON(!PageLocked(page)); BUG_ON(!PageLocked(page));
...@@ -225,7 +225,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, ...@@ -225,7 +225,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
} }
bh->b_end_io = end_buffer_read_sync; bh->b_end_io = end_buffer_read_sync;
get_bh(bh); get_bh(bh);
submit_bh(READ_SYNC | REQ_META, bh); submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh);
if (!(flags & DIO_WAIT)) if (!(flags & DIO_WAIT))
return 0; return 0;
...@@ -435,7 +435,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) ...@@ -435,7 +435,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
if (buffer_uptodate(first_bh)) if (buffer_uptodate(first_bh))
goto out; goto out;
if (!buffer_locked(first_bh)) if (!buffer_locked(first_bh))
ll_rw_block(READ_SYNC | REQ_META, 1, &first_bh); ll_rw_block(READ_SYNC | REQ_META | REQ_PRIO, 1, &first_bh);
dblock++; dblock++;
extlen--; extlen--;
......
...@@ -224,7 +224,7 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent) ...@@ -224,7 +224,7 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent)
bio->bi_end_io = end_bio_io_page; bio->bi_end_io = end_bio_io_page;
bio->bi_private = page; bio->bi_private = page;
submit_bio(READ_SYNC | REQ_META, bio); submit_bio(READ_SYNC | REQ_META | REQ_PRIO, bio);
wait_on_page_locked(page); wait_on_page_locked(page);
bio_put(bio); bio_put(bio);
if (!PageUptodate(page)) { if (!PageUptodate(page)) {
......
...@@ -709,7 +709,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, ...@@ -709,7 +709,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
ll_rw_block(READ | REQ_META, 1, &bh); ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) if (!buffer_uptodate(bh))
goto unlock_out; goto unlock_out;
......
...@@ -124,6 +124,7 @@ enum rq_flag_bits { ...@@ -124,6 +124,7 @@ enum rq_flag_bits {
__REQ_SYNC, /* request is sync (sync write or read) */ __REQ_SYNC, /* request is sync (sync write or read) */
__REQ_META, /* metadata io request */ __REQ_META, /* metadata io request */
__REQ_PRIO, /* boost priority in cfq */
__REQ_DISCARD, /* request to discard sectors */ __REQ_DISCARD, /* request to discard sectors */
__REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */ __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
...@@ -161,14 +162,15 @@ enum rq_flag_bits { ...@@ -161,14 +162,15 @@ enum rq_flag_bits {
#define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER)
#define REQ_SYNC (1 << __REQ_SYNC) #define REQ_SYNC (1 << __REQ_SYNC)
#define REQ_META (1 << __REQ_META) #define REQ_META (1 << __REQ_META)
#define REQ_PRIO (1 << __REQ_PRIO)
#define REQ_DISCARD (1 << __REQ_DISCARD) #define REQ_DISCARD (1 << __REQ_DISCARD)
#define REQ_NOIDLE (1 << __REQ_NOIDLE) #define REQ_NOIDLE (1 << __REQ_NOIDLE)
#define REQ_FAILFAST_MASK \ #define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
#define REQ_COMMON_MASK \ #define REQ_COMMON_MASK \
(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
#define REQ_CLONE_MASK REQ_COMMON_MASK #define REQ_CLONE_MASK REQ_COMMON_MASK
#define REQ_RAHEAD (1 << __REQ_RAHEAD) #define REQ_RAHEAD (1 << __REQ_RAHEAD)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment