packaging: Add spec file for VisionFive2
[platform/kernel/linux-starfive.git] / block / blk-mq.c
index 108a352..652a31f 100644 (file)
@@ -188,9 +188,11 @@ void blk_mq_freeze_queue(struct request_queue *q)
 }
 EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
 
-void blk_mq_unfreeze_queue(struct request_queue *q)
+void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
 {
        mutex_lock(&q->mq_freeze_lock);
+       if (force_atomic)
+               q->q_usage_counter.data->force_atomic = true;
        q->mq_freeze_depth--;
        WARN_ON_ONCE(q->mq_freeze_depth < 0);
        if (!q->mq_freeze_depth) {
@@ -199,6 +201,11 @@ void blk_mq_unfreeze_queue(struct request_queue *q)
        }
        mutex_unlock(&q->mq_freeze_lock);
 }
+
+void blk_mq_unfreeze_queue(struct request_queue *q)
+{
+       __blk_mq_unfreeze_queue(q, false);
+}
 EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
 
 /*
@@ -1318,6 +1325,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
        int errors, queued;
        blk_status_t ret = BLK_STS_OK;
        LIST_HEAD(zone_list);
+       bool needs_resource = false;
 
        if (list_empty(list))
                return false;
@@ -1363,6 +1371,8 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
                        queued++;
                        break;
                case BLK_STS_RESOURCE:
+                       needs_resource = true;
+                       fallthrough;
                case BLK_STS_DEV_RESOURCE:
                        blk_mq_handle_dev_resource(rq, list);
                        goto out;
@@ -1373,6 +1383,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
                         * accept.
                         */
                        blk_mq_handle_zone_resource(rq, &zone_list);
+                       needs_resource = true;
                        break;
                default:
                        errors++;
@@ -1399,7 +1410,6 @@ out:
                /* For non-shared tags, the RESTART check will suffice */
                bool no_tag = prep == PREP_DISPATCH_NO_TAG &&
                        (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED);
-               bool no_budget_avail = prep == PREP_DISPATCH_NO_BUDGET;
 
                if (nr_budgets)
                        blk_mq_release_budgets(q, list);
@@ -1440,14 +1450,16 @@ out:
                 * If driver returns BLK_STS_RESOURCE and SCHED_RESTART
                 * bit is set, run queue after a delay to avoid IO stalls
                 * that could otherwise occur if the queue is idle.  We'll do
-                * similar if we couldn't get budget and SCHED_RESTART is set.
+                * similar if we couldn't get budget or couldn't lock a zone
+                * and SCHED_RESTART is set.
                 */
                needs_restart = blk_mq_sched_needs_restart(hctx);
+               if (prep == PREP_DISPATCH_NO_BUDGET)
+                       needs_resource = true;
                if (!needs_restart ||
                    (no_tag && list_empty_careful(&hctx->dispatch_wait.entry)))
                        blk_mq_run_hw_queue(hctx, true);
-               else if (needs_restart && (ret == BLK_STS_RESOURCE ||
-                                          no_budget_avail))
+               else if (needs_restart && needs_resource)
                        blk_mq_delay_run_hw_queue(hctx, BLK_MQ_RESOURCE_DELAY);
 
                blk_mq_update_dispatch_busy(hctx, true);