blk-iocost.c (54c52e10dc9b939084a7e6e3d32ce8fd8dee7898) blk-iocost.c (cd006509b0a93cb7ee9d9fd50ae274098997a460)
1/* SPDX-License-Identifier: GPL-2.0
2 *
3 * IO cost model based controller.
4 *
5 * Copyright (C) 2019 Tejun Heo <tj@kernel.org>
6 * Copyright (C) 2019 Andy Newell <newella@fb.com>
7 * Copyright (C) 2019 Facebook
8 *

--- 246 unchanged lines hidden (view full) ---

255 * convenient during operation.
256 *
257 * 1s worth of vtime is 2^37. This gives us both sub-nanosecond
258 * granularity and days of wrap-around time even at extreme vrates.
259 */
260 VTIME_PER_SEC_SHIFT = 37,
261 VTIME_PER_SEC = 1LLU << VTIME_PER_SEC_SHIFT,
262 VTIME_PER_USEC = VTIME_PER_SEC / USEC_PER_SEC,
1/* SPDX-License-Identifier: GPL-2.0
2 *
3 * IO cost model based controller.
4 *
5 * Copyright (C) 2019 Tejun Heo <tj@kernel.org>
6 * Copyright (C) 2019 Andy Newell <newella@fb.com>
7 * Copyright (C) 2019 Facebook
8 *

--- 246 unchanged lines hidden (view full) ---

255 * convenient during operation.
256 *
257 * 1s worth of vtime is 2^37. This gives us both sub-nanosecond
258 * granularity and days of wrap-around time even at extreme vrates.
259 */
260 VTIME_PER_SEC_SHIFT = 37,
261 VTIME_PER_SEC = 1LLU << VTIME_PER_SEC_SHIFT,
262 VTIME_PER_USEC = VTIME_PER_SEC / USEC_PER_SEC,
263 VTIME_PER_NSEC = VTIME_PER_SEC / NSEC_PER_SEC,
263
264 /* bound vrate adjustments within two orders of magnitude */
265 VRATE_MIN_PPM = 10000, /* 1% */
266 VRATE_MAX_PPM = 100000000, /* 10000% */
267
268 VRATE_MIN = VTIME_PER_USEC * VRATE_MIN_PPM / MILLION,
269 VRATE_CLAMP_ADJ_PCT = 4,
270

--- 1392 unchanged lines hidden (view full) ---

1663static u64 calc_vtime_cost(struct bio *bio, struct ioc_gq *iocg, bool is_merge)
1664{
1665 u64 cost;
1666
1667 calc_vtime_cost_builtin(bio, iocg, is_merge, &cost);
1668 return cost;
1669}
1670
264
265 /* bound vrate adjustments within two orders of magnitude */
266 VRATE_MIN_PPM = 10000, /* 1% */
267 VRATE_MAX_PPM = 100000000, /* 10000% */
268
269 VRATE_MIN = VTIME_PER_USEC * VRATE_MIN_PPM / MILLION,
270 VRATE_CLAMP_ADJ_PCT = 4,
271

--- 1392 unchanged lines hidden (view full) ---

1664static u64 calc_vtime_cost(struct bio *bio, struct ioc_gq *iocg, bool is_merge)
1665{
1666 u64 cost;
1667
1668 calc_vtime_cost_builtin(bio, iocg, is_merge, &cost);
1669 return cost;
1670}
1671
1672static void calc_size_vtime_cost_builtin(struct request *rq, struct ioc *ioc,
1673 u64 *costp)
1674{
1675 unsigned int pages = blk_rq_stats_sectors(rq) >> IOC_SECT_TO_PAGE_SHIFT;
1676
1677 switch (req_op(rq)) {
1678 case REQ_OP_READ:
1679 *costp = pages * ioc->params.lcoefs[LCOEF_RPAGE];
1680 break;
1681 case REQ_OP_WRITE:
1682 *costp = pages * ioc->params.lcoefs[LCOEF_WPAGE];
1683 break;
1684 default:
1685 *costp = 0;
1686 }
1687}
1688
1689static u64 calc_size_vtime_cost(struct request *rq, struct ioc *ioc)
1690{
1691 u64 cost;
1692
1693 calc_size_vtime_cost_builtin(rq, ioc, &cost);
1694 return cost;
1695}
1696
1671static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio)
1672{
1673 struct blkcg_gq *blkg = bio->bi_blkg;
1674 struct ioc *ioc = rqos_to_ioc(rqos);
1675 struct ioc_gq *iocg = blkg_to_iocg(blkg);
1676 struct ioc_now now;
1677 struct iocg_wait wait;
1678 u32 hw_active, hw_inuse;

--- 153 unchanged lines hidden (view full) ---

1832
1833 if (iocg && bio->bi_iocost_cost)
1834 atomic64_add(bio->bi_iocost_cost, &iocg->done_vtime);
1835}
1836
1837static void ioc_rqos_done(struct rq_qos *rqos, struct request *rq)
1838{
1839 struct ioc *ioc = rqos_to_ioc(rqos);
1697static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio)
1698{
1699 struct blkcg_gq *blkg = bio->bi_blkg;
1700 struct ioc *ioc = rqos_to_ioc(rqos);
1701 struct ioc_gq *iocg = blkg_to_iocg(blkg);
1702 struct ioc_now now;
1703 struct iocg_wait wait;
1704 u32 hw_active, hw_inuse;

--- 153 unchanged lines hidden (view full) ---

1858
1859 if (iocg && bio->bi_iocost_cost)
1860 atomic64_add(bio->bi_iocost_cost, &iocg->done_vtime);
1861}
1862
1863static void ioc_rqos_done(struct rq_qos *rqos, struct request *rq)
1864{
1865 struct ioc *ioc = rqos_to_ioc(rqos);
1840 u64 on_q_ns, rq_wait_ns;
1866 u64 on_q_ns, rq_wait_ns, size_nsec;
1841 int pidx, rw;
1842
1843 if (!ioc->enabled || !rq->alloc_time_ns || !rq->start_time_ns)
1844 return;
1845
1846 switch (req_op(rq) & REQ_OP_MASK) {
1847 case REQ_OP_READ:
1848 pidx = QOS_RLAT;

--- 4 unchanged lines hidden (view full) ---

1853 rw = WRITE;
1854 break;
1855 default:
1856 return;
1857 }
1858
1859 on_q_ns = ktime_get_ns() - rq->alloc_time_ns;
1860 rq_wait_ns = rq->start_time_ns - rq->alloc_time_ns;
1867 int pidx, rw;
1868
1869 if (!ioc->enabled || !rq->alloc_time_ns || !rq->start_time_ns)
1870 return;
1871
1872 switch (req_op(rq) & REQ_OP_MASK) {
1873 case REQ_OP_READ:
1874 pidx = QOS_RLAT;

--- 4 unchanged lines hidden (view full) ---

1879 rw = WRITE;
1880 break;
1881 default:
1882 return;
1883 }
1884
1885 on_q_ns = ktime_get_ns() - rq->alloc_time_ns;
1886 rq_wait_ns = rq->start_time_ns - rq->alloc_time_ns;
1887 size_nsec = div64_u64(calc_size_vtime_cost(rq, ioc), VTIME_PER_NSEC);
1861
1888
1862 if (on_q_ns <= ioc->params.qos[pidx] * NSEC_PER_USEC)
1889 if (on_q_ns <= size_nsec ||
1890 on_q_ns - size_nsec <= ioc->params.qos[pidx] * NSEC_PER_USEC)
1863 this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_met);
1864 else
1865 this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_missed);
1866
1867 this_cpu_add(ioc->pcpu_stat->rq_wait_ns, rq_wait_ns);
1868}
1869
1870static void ioc_rqos_queue_depth_changed(struct rq_qos *rqos)

--- 391 unchanged lines hidden (view full) ---

2262 }
2263
2264 if (qos[QOS_MIN] > qos[QOS_MAX])
2265 goto einval;
2266
2267 spin_lock_irq(&ioc->lock);
2268
2269 if (enable) {
1891 this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_met);
1892 else
1893 this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_missed);
1894
1895 this_cpu_add(ioc->pcpu_stat->rq_wait_ns, rq_wait_ns);
1896}
1897
1898static void ioc_rqos_queue_depth_changed(struct rq_qos *rqos)

--- 391 unchanged lines hidden (view full) ---

2290 }
2291
2292 if (qos[QOS_MIN] > qos[QOS_MAX])
2293 goto einval;
2294
2295 spin_lock_irq(&ioc->lock);
2296
2297 if (enable) {
2298 blk_stat_enable_accounting(ioc->rqos.q);
2270 blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
2271 ioc->enabled = true;
2272 } else {
2273 blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
2274 ioc->enabled = false;
2275 }
2276
2277 if (user) {

--- 187 unchanged lines hidden ---
2299 blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
2300 ioc->enabled = true;
2301 } else {
2302 blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
2303 ioc->enabled = false;
2304 }
2305
2306 if (user) {

--- 187 unchanged lines hidden ---