ARM64: configs: tizen: Adjust for mipi csi camera of rpi5
[platform/kernel/linux-rpi.git] / block / blk-iocost.c
index 285ced3..7ee8d85 100644 (file)
@@ -1353,6 +1353,13 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now)
 
        lockdep_assert_held(&iocg->waitq.lock);
 
+       /*
+        * If the delay is set by another CPU, we may be in the past. No need to
+        * change anything if so. This avoids decay calculation underflow.
+        */
+       if (time_before64(now->now, iocg->delay_at))
+               return false;
+
        /* calculate the current delay in effect - 1/2 every second */
        tdelta = now->now - iocg->delay_at;
        if (iocg->delay)
@@ -2455,6 +2462,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
        u32 hwi, adj_step;
        s64 margin;
        u64 cost, new_inuse;
+       unsigned long flags;
 
        current_hweight(iocg, NULL, &hwi);
        old_hwi = hwi;
@@ -2473,11 +2481,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
            iocg->inuse == iocg->active)
                return cost;
 
-       spin_lock_irq(&ioc->lock);
+       spin_lock_irqsave(&ioc->lock, flags);
 
        /* we own inuse only when @iocg is in the normal active state */
        if (iocg->abs_vdebt || list_empty(&iocg->active_list)) {
-               spin_unlock_irq(&ioc->lock);
+               spin_unlock_irqrestore(&ioc->lock, flags);
                return cost;
        }
 
@@ -2498,7 +2506,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime,
        } while (time_after64(vtime + cost, now->vnow) &&
                 iocg->inuse != iocg->active);
 
-       spin_unlock_irq(&ioc->lock);
+       spin_unlock_irqrestore(&ioc->lock, flags);
 
        TRACE_IOCG_PATH(inuse_adjust, iocg, now,
                        old_inuse, iocg->inuse, old_hwi, hwi);
@@ -2515,6 +2523,10 @@ static void calc_vtime_cost_builtin(struct bio *bio, struct ioc_gq *iocg,
        u64 seek_pages = 0;
        u64 cost = 0;
 
+       /* Can't calculate cost for empty bio */
+       if (!bio->bi_iter.bi_size)
+               goto out;
+
        switch (bio_op(bio)) {
        case REQ_OP_READ:
                coef_seqio      = ioc->params.lcoefs[LCOEF_RSEQIO];
@@ -3296,15 +3308,14 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
        if (qos[QOS_MIN] > qos[QOS_MAX])
                goto einval;
 
-       if (enable) {
+       if (enable && !ioc->enabled) {
                blk_stat_enable_accounting(disk->queue);
                blk_queue_flag_set(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
                ioc->enabled = true;
-               wbt_disable_default(disk);
-       } else {
+       } else if (!enable && ioc->enabled) {
+               blk_stat_disable_accounting(disk->queue);
                blk_queue_flag_clear(QUEUE_FLAG_RQ_ALLOC_TIME, disk->queue);
                ioc->enabled = false;
-               wbt_enable_default(disk);
        }
 
        if (user) {
@@ -3317,6 +3328,11 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
        ioc_refresh_params(ioc, true);
        spin_unlock_irq(&ioc->lock);
 
+       if (enable)
+               wbt_disable_default(disk);
+       else
+               wbt_enable_default(disk);
+
        blk_mq_unquiesce_queue(disk->queue);
        blk_mq_unfreeze_queue(disk->queue);