Merge branch 'selftests: xsk: Add test case for packets at end of UMEM'
[platform/kernel/linux-starfive.git] / block / blk-iocost.c
index 6955605..ff534e9 100644 (file)
@@ -258,6 +258,11 @@ enum {
        VRATE_MIN               = VTIME_PER_USEC * VRATE_MIN_PPM / MILLION,
        VRATE_CLAMP_ADJ_PCT     = 4,
 
+       /* switch iff the conditions are met for longer than this */
+       AUTOP_CYCLE_NSEC        = 10LLU * NSEC_PER_SEC,
+};
+
+enum {
        /* if IOs end up waiting for requests, issue less */
        RQ_WAIT_BUSY_PCT        = 5,
 
@@ -296,9 +301,6 @@ enum {
        /* don't let cmds which take a very long time pin lagging for too long */
        MAX_LAGGING_PERIODS     = 10,
 
-       /* switch iff the conditions are met for longer than this */
-       AUTOP_CYCLE_NSEC        = 10LLU * NSEC_PER_SEC,
-
        /*
         * Count IO size in 4k pages.  The 12bit shift helps keeping
         * size-proportional components of cost calculation in closer
@@ -667,7 +669,7 @@ static struct ioc *q_to_ioc(struct request_queue *q)
 
 static const char __maybe_unused *ioc_name(struct ioc *ioc)
 {
-       struct gendisk *disk = ioc->rqos.q->disk;
+       struct gendisk *disk = ioc->rqos.disk;
 
        if (!disk)
                return "<unknown>";
@@ -806,11 +808,11 @@ static int ioc_autop_idx(struct ioc *ioc)
        u64 now_ns;
 
        /* rotational? */
-       if (!blk_queue_nonrot(ioc->rqos.q))
+       if (!blk_queue_nonrot(ioc->rqos.disk->queue))
                return AUTOP_HDD;
 
        /* handle SATA SSDs w/ broken NCQ */
-       if (blk_queue_depth(ioc->rqos.q) == 1)
+       if (blk_queue_depth(ioc->rqos.disk->queue) == 1)
                return AUTOP_SSD_QD1;
 
        /* use one of the normal ssd sets */
@@ -866,9 +868,14 @@ static void calc_lcoefs(u64 bps, u64 seqiops, u64 randiops,
 
        *page = *seqio = *randio = 0;
 
-       if (bps)
-               *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC,
-                                          DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE));
+       if (bps) {
+               u64 bps_pages = DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE);
+
+               if (bps_pages)
+                       *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, bps_pages);
+               else
+                       *page = 1;
+       }
 
        if (seqiops) {
                v = DIV64_U64_ROUND_UP(VTIME_PER_SEC, seqiops);
@@ -926,8 +933,8 @@ static bool ioc_refresh_params(struct ioc *ioc, bool force)
 
        ioc->vrate_min = DIV64_U64_ROUND_UP((u64)ioc->params.qos[QOS_MIN] *
                                            VTIME_PER_USEC, MILLION);
-       ioc->vrate_max = div64_u64((u64)ioc->params.qos[QOS_MAX] *
-                                  VTIME_PER_USEC, MILLION);
+       ioc->vrate_max = DIV64_U64_ROUND_UP((u64)ioc->params.qos[QOS_MAX] *
+                                           VTIME_PER_USEC, MILLION);
 
        return true;
 }
@@ -2642,7 +2649,7 @@ retry_lock:
        if (use_debt) {
                iocg_incur_debt(iocg, abs_cost, &now);
                if (iocg_kick_delay(iocg, &now))
-                       blkcg_schedule_throttle(rqos->q->disk,
+                       blkcg_schedule_throttle(rqos->disk,
                                        (bio->bi_opf & REQ_SWAP) == REQ_SWAP);
                iocg_unlock(iocg, ioc_locked, &flags);
                return;
@@ -2743,7 +2750,7 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq,
        if (likely(!list_empty(&iocg->active_list))) {
                iocg_incur_debt(iocg, abs_cost, &now);
                if (iocg_kick_delay(iocg, &now))
-                       blkcg_schedule_throttle(rqos->q->disk,
+                       blkcg_schedule_throttle(rqos->disk,
                                        (bio->bi_opf & REQ_SWAP) == REQ_SWAP);
        } else {
                iocg_commit_bio(iocg, bio, abs_cost, cost);
@@ -2814,7 +2821,7 @@ static void ioc_rqos_exit(struct rq_qos *rqos)
 {
        struct ioc *ioc = rqos_to_ioc(rqos);
 
-       blkcg_deactivate_policy(rqos->q, &blkcg_policy_iocost);
+       blkcg_deactivate_policy(rqos->disk, &blkcg_policy_iocost);
 
        spin_lock_irq(&ioc->lock);
        ioc->running = IOC_STOP;
@@ -2825,7 +2832,7 @@ static void ioc_rqos_exit(struct rq_qos *rqos)
        kfree(ioc);
 }
 
-static struct rq_qos_ops ioc_rqos_ops = {
+static const struct rq_qos_ops ioc_rqos_ops = {
        .throttle = ioc_rqos_throttle,
        .merge = ioc_rqos_merge,
        .done_bio = ioc_rqos_done_bio,
@@ -2836,9 +2843,7 @@ static struct rq_qos_ops ioc_rqos_ops = {
 
 static int blk_iocost_init(struct gendisk *disk)
 {
-       struct request_queue *q = disk->queue;
        struct ioc *ioc;
-       struct rq_qos *rqos;
        int i, cpu, ret;
 
        ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
@@ -2861,11 +2866,6 @@ static int blk_iocost_init(struct gendisk *disk)
                local64_set(&ccs->rq_wait_ns, 0);
        }
 
-       rqos = &ioc->rqos;
-       rqos->id = RQ_QOS_COST;
-       rqos->ops = &ioc_rqos_ops;
-       rqos->q = q;
-
        spin_lock_init(&ioc->lock);
        timer_setup(&ioc->timer, ioc_timer_fn, 0);
        INIT_LIST_HEAD(&ioc->active_iocgs);
@@ -2889,17 +2889,17 @@ static int blk_iocost_init(struct gendisk *disk)
         * called before policy activation completion, can't assume that the
         * target bio has an iocg associated and need to test for NULL iocg.
         */
-       ret = rq_qos_add(q, rqos);
+       ret = rq_qos_add(&ioc->rqos, disk, RQ_QOS_COST, &ioc_rqos_ops);
        if (ret)
                goto err_free_ioc;
 
-       ret = blkcg_activate_policy(q, &blkcg_policy_iocost);
+       ret = blkcg_activate_policy(disk, &blkcg_policy_iocost);
        if (ret)
                goto err_del_qos;
        return 0;
 
 err_del_qos:
-       rq_qos_del(q, rqos);
+       rq_qos_del(&ioc->rqos);
 err_free_ioc:
        free_percpu(ioc->pcpu_stat);
        kfree(ioc);
@@ -2923,13 +2923,14 @@ static void ioc_cpd_free(struct blkcg_policy_data *cpd)
        kfree(container_of(cpd, struct ioc_cgrp, cpd));
 }
 
-static struct blkg_policy_data *ioc_pd_alloc(gfp_t gfp, struct request_queue *q,
-                                            struct blkcg *blkcg)
+static struct blkg_policy_data *ioc_pd_alloc(struct gendisk *disk,
+               struct blkcg *blkcg, gfp_t gfp)
 {
        int levels = blkcg->css.cgroup->level + 1;
        struct ioc_gq *iocg;
 
-       iocg = kzalloc_node(struct_size(iocg, ancestors, levels), gfp, q->node);
+       iocg = kzalloc_node(struct_size(iocg, ancestors, levels), gfp,
+                           disk->node_id);
        if (!iocg)
                return NULL;
 
@@ -3129,6 +3130,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
        if (!dname)
                return 0;
 
+       spin_lock_irq(&ioc->lock);
        seq_printf(sf, "%s enable=%d ctrl=%s rpct=%u.%02u rlat=%u wpct=%u.%02u wlat=%u min=%u.%02u max=%u.%02u\n",
                   dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto",
                   ioc->params.qos[QOS_RPPM] / 10000,
@@ -3141,6 +3143,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
                   ioc->params.qos[QOS_MIN] % 10000 / 100,
                   ioc->params.qos[QOS_MAX] / 10000,
                   ioc->params.qos[QOS_MAX] % 10000 / 100);
+       spin_unlock_irq(&ioc->lock);
        return 0;
 }
 
@@ -3185,6 +3188,11 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
                return PTR_ERR(bdev);
 
        disk = bdev->bd_disk;
+       if (!queue_is_mq(disk->queue)) {
+               ret = -EOPNOTSUPP;
+               goto err;
+       }
+
        ioc = q_to_ioc(disk->queue);
        if (!ioc) {
                ret = blk_iocost_init(disk);
@@ -3212,7 +3220,8 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
 
                switch (match_token(p, qos_ctrl_tokens, args)) {
                case QOS_ENABLE:
-                       match_u64(&args[0], &v);
+                       if (match_u64(&args[0], &v))
+                               goto einval;
                        enable = v;
                        continue;
                case QOS_CTRL:
@@ -3270,11 +3279,11 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
                blk_stat_enable_accounting(disk->queue);
                blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
                ioc->enabled = true;
-               wbt_disable_default(disk->queue);
+               wbt_disable_default(disk);
        } else {
                blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
                ioc->enabled = false;
-               wbt_enable_default(disk->queue);
+               wbt_enable_default(disk);
        }
 
        if (user) {
@@ -3314,12 +3323,14 @@ static u64 ioc_cost_model_prfill(struct seq_file *sf,
        if (!dname)
                return 0;
 
+       spin_lock_irq(&ioc->lock);
        seq_printf(sf, "%s ctrl=%s model=linear "
                   "rbps=%llu rseqiops=%llu rrandiops=%llu "
                   "wbps=%llu wseqiops=%llu wrandiops=%llu\n",
                   dname, ioc->user_cost_model ? "user" : "auto",
                   u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS],
                   u[I_LCOEF_WBPS], u[I_LCOEF_WSEQIOPS], u[I_LCOEF_WRANDIOPS]);
+       spin_unlock_irq(&ioc->lock);
        return 0;
 }
 
@@ -3364,6 +3375,11 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
                return PTR_ERR(bdev);
 
        q = bdev_get_queue(bdev);
+       if (!queue_is_mq(q)) {
+               ret = -EOPNOTSUPP;
+               goto err;
+       }
+
        ioc = q_to_ioc(q);
        if (!ioc) {
                ret = blk_iocost_init(bdev->bd_disk);