]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - block/bfq-wf2q.c
genirq: Introduce irq_chip_{request,release}_resource_parent() apis
[mirror_ubuntu-hirsute-kernel.git] / block / bfq-wf2q.c
index 72adbbe975d5c7b281558870af6e212b27cd479d..ae4d000ac0af1c38a49c28e824ca843bfb3c531d 100644 (file)
@@ -44,6 +44,12 @@ static unsigned int bfq_class_idx(struct bfq_entity *entity)
                BFQ_DEFAULT_GRP_CLASS - 1;
 }
 
+unsigned int bfq_tot_busy_queues(struct bfq_data *bfqd)
+{
+       return bfqd->busy_queues[0] + bfqd->busy_queues[1] +
+               bfqd->busy_queues[2];
+}
+
 static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
                                                 bool expiration);
 
@@ -1006,7 +1012,7 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
                entity->on_st = true;
        }
 
-#ifdef BFQ_GROUP_IOSCHED_ENABLED
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
        if (!bfq_entity_to_bfqq(entity)) { /* bfq_group */
                struct bfq_group *bfqg =
                        container_of(entity, struct bfq_group, entity);
@@ -1513,7 +1519,7 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
        struct bfq_sched_data *sd;
        struct bfq_queue *bfqq;
 
-       if (bfqd->busy_queues == 0)
+       if (bfq_tot_busy_queues(bfqd) == 0)
                return NULL;
 
        /*
@@ -1599,7 +1605,8 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
        return bfqq;
 }
 
-void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
+/* returns true if the in-service queue gets freed */
+bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
 {
        struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
        struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
@@ -1623,8 +1630,20 @@ void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
         * service tree either, then release the service reference to
         * the queue it represents (taken with bfq_get_entity).
         */
-       if (!in_serv_entity->on_st)
+       if (!in_serv_entity->on_st) {
+               /*
+                * If no process is referencing in_serv_bfqq any
+                * longer, then the service reference may be the only
+                * reference to the queue. If this is the case, then
+                * bfqq gets freed here.
+                */
+               int ref = in_serv_bfqq->ref;
                bfq_put_queue(in_serv_bfqq);
+               if (ref == 1)
+                       return true;
+       }
+
+       return false;
 }
 
 void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
@@ -1665,10 +1684,7 @@ void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 
        bfq_clear_bfqq_busy(bfqq);
 
-       bfqd->busy_queues--;
-
-       if (!bfqq->dispatched)
-               bfq_weights_tree_remove(bfqd, bfqq);
+       bfqd->busy_queues[bfqq->ioprio_class - 1]--;
 
        if (bfqq->wr_coeff > 1)
                bfqd->wr_busy_queues--;
@@ -1676,6 +1692,9 @@ void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
        bfqg_stats_update_dequeue(bfqq_group(bfqq));
 
        bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
+
+       if (!bfqq->dispatched)
+               bfq_weights_tree_remove(bfqd, bfqq);
 }
 
 /*
@@ -1688,7 +1707,7 @@ void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
        bfq_activate_bfqq(bfqd, bfqq);
 
        bfq_mark_bfqq_busy(bfqq);
-       bfqd->busy_queues++;
+       bfqd->busy_queues[bfqq->ioprio_class - 1]++;
 
        if (!bfqq->dispatched)
                if (bfqq->wr_coeff == 1)