VTIME_PER_SEC_SHIFT     = 37,
        VTIME_PER_SEC           = 1LLU << VTIME_PER_SEC_SHIFT,
        VTIME_PER_USEC          = VTIME_PER_SEC / USEC_PER_SEC,
+       VTIME_PER_NSEC          = VTIME_PER_SEC / NSEC_PER_SEC,
 
        /* bound vrate adjustments within two orders of magnitude */
        VRATE_MIN_PPM           = 10000,        /* 1% */
        return cost;
 }
 
+static void calc_size_vtime_cost_builtin(struct request *rq, struct ioc *ioc,
+                                        u64 *costp)
+{
+       unsigned int pages = blk_rq_stats_sectors(rq) >> IOC_SECT_TO_PAGE_SHIFT;
+
+       switch (req_op(rq)) {
+       case REQ_OP_READ:
+               *costp = pages * ioc->params.lcoefs[LCOEF_RPAGE];
+               break;
+       case REQ_OP_WRITE:
+               *costp = pages * ioc->params.lcoefs[LCOEF_WPAGE];
+               break;
+       default:
+               *costp = 0;
+       }
+}
+
+static u64 calc_size_vtime_cost(struct request *rq, struct ioc *ioc)
+{
+       u64 cost;
+
+       calc_size_vtime_cost_builtin(rq, ioc, &cost);
+       return cost;
+}
+
 static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio)
 {
        struct blkcg_gq *blkg = bio->bi_blkg;
 static void ioc_rqos_done(struct rq_qos *rqos, struct request *rq)
 {
        struct ioc *ioc = rqos_to_ioc(rqos);
-       u64 on_q_ns, rq_wait_ns;
+       u64 on_q_ns, rq_wait_ns, size_nsec;
        int pidx, rw;
 
        if (!ioc->enabled || !rq->alloc_time_ns || !rq->start_time_ns)
 
        on_q_ns = ktime_get_ns() - rq->alloc_time_ns;
        rq_wait_ns = rq->start_time_ns - rq->alloc_time_ns;
+       size_nsec = div64_u64(calc_size_vtime_cost(rq, ioc), VTIME_PER_NSEC);
 
-       if (on_q_ns <= ioc->params.qos[pidx] * NSEC_PER_USEC)
+       if (on_q_ns <= size_nsec ||
+           on_q_ns - size_nsec <= ioc->params.qos[pidx] * NSEC_PER_USEC)
                this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_met);
        else
                this_cpu_inc(ioc->pcpu_stat->missed[rw].nr_missed);
        spin_lock_irq(&ioc->lock);
 
        if (enable) {
+               blk_stat_enable_accounting(ioc->rqos.q);
                blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, ioc->rqos.q);
                ioc->enabled = true;
        } else {