On Mon, Jan 15, 2024 at 02:53:55PM -0700, Jens Axboe wrote: > If the block plug gets flushed, eg on preempt or schedule out, then > we invalidate the cached clock. There must be something implicitly happening that I am missing. Where is the 'cur_time' cached clock invalidated on a plug flush? > diff --git a/block/blk-core.c b/block/blk-core.c > index 11342af420d0..cc4db4d92c75 100644 > --- a/block/blk-core.c > +++ b/block/blk-core.c > @@ -1073,6 +1073,7 @@ void blk_start_plug_nr_ios(struct blk_plug *plug, unsigned short nr_ios) > if (tsk->plug) > return; > > + plug->cur_ktime = 0; > plug->mq_list = NULL; > plug->cached_rq = NULL; > plug->nr_ios = min_t(unsigned short, nr_ios, BLK_MAX_REQUEST_COUNT); > diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h > index 2f9ceea0e23b..23c237b22071 100644 > --- a/include/linux/blkdev.h > +++ b/include/linux/blkdev.h > @@ -942,6 +942,7 @@ struct blk_plug { > > /* if ios_left is > 1, we can batch tag/rq allocations */ > struct request *cached_rq; > + u64 cur_ktime; > unsigned short nr_ios; > > unsigned short rq_count; > @@ -977,7 +978,15 @@ long nr_blockdev_pages(void); > > static inline u64 blk_time_get_ns(void) > { > - return ktime_get_ns(); > + struct blk_plug *plug = current->plug; > + > + if (!plug) > + return ktime_get_ns(); > + if (!(plug->cur_ktime & 1ULL)) { > + plug->cur_ktime = ktime_get_ns(); > + plug->cur_ktime |= 1ULL; > + } > + return plug->cur_ktime; > } > #else /* CONFIG_BLOCK */ > struct blk_plug {