Skip to content

Commit 522a777

Browse files
osandovaxboe
authored andcommitted
block: consolidate struct request timestamp fields
Currently, struct request has four timestamp fields: - A start time, set at get_request time, in jiffies, used for iostats - An I/O start time, set at start_request time, in ktime nanoseconds, used for blk-stats (i.e., wbt, kyber, hybrid polling) - Another start time and another I/O start time, used for cfq and bfq These can all be consolidated into one start time and one I/O start time, both in ktime nanoseconds, shaving off up to 16 bytes from struct request depending on the kernel config. Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 4bc6339 commit 522a777

File tree

10 files changed

+30
-76
lines changed

10 files changed

+30
-76
lines changed

block/bfq-iosched.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4778,8 +4778,8 @@ static void bfq_finish_requeue_request(struct request *rq)
47784778

47794779
if (rq->rq_flags & RQF_STARTED)
47804780
bfqg_stats_update_completion(bfqq_group(bfqq),
4781-
rq_start_time_ns(rq),
4782-
rq_io_start_time_ns(rq),
4781+
rq->start_time_ns,
4782+
rq->io_start_time_ns,
47834783
rq->cmd_flags);
47844784

47854785
if (likely(rq->rq_flags & RQF_STARTED)) {

block/blk-core.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
196196
RB_CLEAR_NODE(&rq->rb_node);
197197
rq->tag = -1;
198198
rq->internal_tag = -1;
199-
rq->start_time = jiffies;
200-
set_start_time_ns(rq);
199+
rq->start_time_ns = ktime_get_ns();
201200
rq->part = NULL;
202201
seqcount_init(&rq->gstate_seq);
203202
u64_stats_init(&rq->aborted_gstate_sync);
@@ -2726,19 +2725,20 @@ void blk_account_io_completion(struct request *req, unsigned int bytes)
27262725
}
27272726
}
27282727

2729-
void blk_account_io_done(struct request *req)
2728+
void blk_account_io_done(struct request *req, u64 now)
27302729
{
27312730
/*
27322731
* Account IO completion. flush_rq isn't accounted as a
27332732
* normal IO on queueing nor completion. Accounting the
27342733
* containing request is enough.
27352734
*/
27362735
if (blk_do_io_stat(req) && !(req->rq_flags & RQF_FLUSH_SEQ)) {
2737-
unsigned long duration = jiffies - req->start_time;
2736+
unsigned long duration;
27382737
const int rw = rq_data_dir(req);
27392738
struct hd_struct *part;
27402739
int cpu;
27412740

2741+
duration = nsecs_to_jiffies(now - req->start_time_ns);
27422742
cpu = part_stat_lock();
27432743
part = req->part;
27442744

@@ -2969,10 +2969,8 @@ static void blk_dequeue_request(struct request *rq)
29692969
* and to it is freed is accounted as io that is in progress at
29702970
* the driver side.
29712971
*/
2972-
if (blk_account_rq(rq)) {
2972+
if (blk_account_rq(rq))
29732973
q->in_flight[rq_is_sync(rq)]++;
2974-
set_io_start_time_ns(rq);
2975-
}
29762974
}
29772975

29782976
/**
@@ -3192,12 +3190,13 @@ EXPORT_SYMBOL_GPL(blk_unprep_request);
31923190
void blk_finish_request(struct request *req, blk_status_t error)
31933191
{
31943192
struct request_queue *q = req->q;
3193+
u64 now = ktime_get_ns();
31953194

31963195
lockdep_assert_held(req->q->queue_lock);
31973196
WARN_ON_ONCE(q->mq_ops);
31983197

31993198
if (req->rq_flags & RQF_STATS)
3200-
blk_stat_add(req);
3199+
blk_stat_add(req, now);
32013200

32023201
if (req->rq_flags & RQF_QUEUED)
32033202
blk_queue_end_tag(q, req);
@@ -3212,7 +3211,7 @@ void blk_finish_request(struct request *req, blk_status_t error)
32123211
if (req->rq_flags & RQF_DONTPREP)
32133212
blk_unprep_request(req);
32143213

3215-
blk_account_io_done(req);
3214+
blk_account_io_done(req, now);
32163215

32173216
if (req->end_io) {
32183217
wbt_done(req->q->rq_wb, req);

block/blk-merge.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -724,13 +724,12 @@ static struct request *attempt_merge(struct request_queue *q,
724724
}
725725

726726
/*
727-
* At this point we have either done a back merge
728-
* or front merge. We need the smaller start_time of
729-
* the merged requests to be the current request
730-
* for accounting purposes.
727+
* At this point we have either done a back merge or front merge. We
728+
* need the smaller start_time_ns of the merged requests to be the
729+
* current request for accounting purposes.
731730
*/
732-
if (time_after(req->start_time, next->start_time))
733-
req->start_time = next->start_time;
731+
if (next->start_time_ns < req->start_time_ns)
732+
req->start_time_ns = next->start_time_ns;
734733

735734
req->biotail->bi_next = next->bio;
736735
req->biotail = next->biotail;

block/blk-mq.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
309309
RB_CLEAR_NODE(&rq->rb_node);
310310
rq->rq_disk = NULL;
311311
rq->part = NULL;
312-
rq->start_time = jiffies;
312+
rq->start_time_ns = ktime_get_ns();
313313
rq->io_start_time_ns = 0;
314314
rq->nr_phys_segments = 0;
315315
#if defined(CONFIG_BLK_DEV_INTEGRITY)
@@ -329,8 +329,6 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
329329

330330
#ifdef CONFIG_BLK_CGROUP
331331
rq->rl = NULL;
332-
set_start_time_ns(rq);
333-
rq->cgroup_io_start_time_ns = 0;
334332
#endif
335333

336334
data->ctx->rq_dispatched[op_is_sync(op)]++;
@@ -506,12 +504,14 @@ EXPORT_SYMBOL_GPL(blk_mq_free_request);
506504

507505
inline void __blk_mq_end_request(struct request *rq, blk_status_t error)
508506
{
507+
u64 now = ktime_get_ns();
508+
509509
if (rq->rq_flags & RQF_STATS) {
510510
blk_mq_poll_stats_start(rq->q);
511-
blk_stat_add(rq);
511+
blk_stat_add(rq, now);
512512
}
513513

514-
blk_account_io_done(rq);
514+
blk_account_io_done(rq, now);
515515

516516
if (rq->end_io) {
517517
wbt_done(rq->q->rq_wb, rq);

block/blk-stat.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,14 @@ static void __blk_stat_add(struct blk_rq_stat *stat, u64 value)
4747
stat->nr_samples++;
4848
}
4949

50-
void blk_stat_add(struct request *rq)
50+
void blk_stat_add(struct request *rq, u64 now)
5151
{
5252
struct request_queue *q = rq->q;
5353
struct blk_stat_callback *cb;
5454
struct blk_rq_stat *stat;
5555
int bucket;
56-
u64 now, value;
56+
u64 value;
5757

58-
now = ktime_get_ns();
5958
value = (now >= rq->io_start_time_ns) ? now - rq->io_start_time_ns : 0;
6059

6160
blk_throtl_stat_add(rq, value);

block/blk-stat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct blk_stat_callback {
6565
struct blk_queue_stats *blk_alloc_queue_stats(void);
6666
void blk_free_queue_stats(struct blk_queue_stats *);
6767

68-
void blk_stat_add(struct request *);
68+
void blk_stat_add(struct request *rq, u64 now);
6969

7070
/* record time/size info in request but not add a callback */
7171
void blk_stat_enable_accounting(struct request_queue *q);

block/blk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ unsigned int blk_plug_queued_count(struct request_queue *q);
186186

187187
void blk_account_io_start(struct request *req, bool new_io);
188188
void blk_account_io_completion(struct request *req, unsigned int bytes);
189-
void blk_account_io_done(struct request *req);
189+
void blk_account_io_done(struct request *req, u64 now);
190190

191191
/*
192192
* EH timer and IO completion will both attempt to 'grab' the request, make

block/cfq-iosched.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4228,8 +4228,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
42284228
cfqd->rq_in_driver--;
42294229
cfqq->dispatched--;
42304230
(RQ_CFQG(rq))->dispatched--;
4231-
cfqg_stats_update_completion(cfqq->cfqg, rq_start_time_ns(rq),
4232-
rq_io_start_time_ns(rq), rq->cmd_flags);
4231+
cfqg_stats_update_completion(cfqq->cfqg, rq->start_time_ns,
4232+
rq->io_start_time_ns, rq->cmd_flags);
42334233

42344234
cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
42354235

@@ -4245,16 +4245,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
42454245
cfqq_type(cfqq));
42464246

42474247
st->ttime.last_end_request = now;
4248-
/*
4249-
* We have to do this check in jiffies since start_time is in
4250-
* jiffies and it is not trivial to convert to ns. If
4251-
* cfq_fifo_expire[1] ever comes close to 1 jiffie, this test
4252-
* will become problematic but so far we are fine (the default
4253-
* is 128 ms).
4254-
*/
4255-
if (!time_after(rq->start_time +
4256-
nsecs_to_jiffies(cfqd->cfq_fifo_expire[1]),
4257-
jiffies))
4248+
if (rq->start_time_ns + cfqd->cfq_fifo_expire[1] <= now)
42584249
cfqd->last_delayed_sync = now;
42594250
}
42604251

drivers/md/dm-rq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ static blk_status_t dm_dispatch_clone_request(struct request *clone, struct requ
406406
if (blk_queue_io_stat(clone->q))
407407
clone->rq_flags |= RQF_IO_STAT;
408408

409-
clone->start_time = jiffies;
409+
clone->start_time_ns = ktime_get_ns();
410410
r = blk_insert_cloned_request(clone->q, clone);
411411
if (r != BLK_STS_OK && r != BLK_STS_RESOURCE && r != BLK_STS_DEV_RESOURCE)
412412
/* must complete clone in terms of original request */

include/linux/blkdev.h

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ struct request {
205205

206206
struct gendisk *rq_disk;
207207
struct hd_struct *part;
208-
unsigned long start_time;
208+
/* Time that I/O was submitted to the kernel. */
209+
u64 start_time_ns;
209210
/* Time that I/O was submitted to the device. */
210211
u64 io_start_time_ns;
211212

@@ -277,8 +278,6 @@ struct request {
277278

278279
#ifdef CONFIG_BLK_CGROUP
279280
struct request_list *rl; /* rl this rq is alloced from */
280-
unsigned long long cgroup_start_time_ns;
281-
unsigned long long cgroup_io_start_time_ns; /* when passed to hardware */
282281
#endif
283282
};
284283

@@ -1798,39 +1797,6 @@ int kblockd_schedule_work(struct work_struct *work);
17981797
int kblockd_schedule_work_on(int cpu, struct work_struct *work);
17991798
int kblockd_mod_delayed_work_on(int cpu, struct delayed_work *dwork, unsigned long delay);
18001799

1801-
#ifdef CONFIG_BLK_CGROUP
1802-
static inline void set_start_time_ns(struct request *req)
1803-
{
1804-
req->cgroup_start_time_ns = ktime_get_ns();
1805-
}
1806-
1807-
static inline void set_io_start_time_ns(struct request *req)
1808-
{
1809-
req->cgroup_io_start_time_ns = ktime_get_ns();
1810-
}
1811-
1812-
static inline u64 rq_start_time_ns(struct request *req)
1813-
{
1814-
return req->cgroup_start_time_ns;
1815-
}
1816-
1817-
static inline u64 rq_io_start_time_ns(struct request *req)
1818-
{
1819-
return req->cgroup_io_start_time_ns;
1820-
}
1821-
#else
1822-
static inline void set_start_time_ns(struct request *req) {}
1823-
static inline void set_io_start_time_ns(struct request *req) {}
1824-
static inline u64 rq_start_time_ns(struct request *req)
1825-
{
1826-
return 0;
1827-
}
1828-
static inline u64 rq_io_start_time_ns(struct request *req)
1829-
{
1830-
return 0;
1831-
}
1832-
#endif
1833-
18341800
#define MODULE_ALIAS_BLOCKDEV(major,minor) \
18351801
MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
18361802
#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \

0 commit comments

Comments
 (0)