hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/block/bfq-wf2q.c
....@@ -1,19 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Hierarchical Budget Worst-case Fair Weighted Fair Queueing
34 * (B-WF2Q+): hierarchical scheduling algorithm by which the BFQ I/O
45 * scheduler schedules generic entities. The latter can represent
56 * either single bfq queues (associated with processes) or groups of
67 * bfq queues (associated with cgroups).
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License as
10
- * published by the Free Software Foundation; either version 2 of the
11
- * License, or (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
- * General Public License for more details.
178 */
189 #include "bfq-iosched.h"
1910
....@@ -44,6 +35,12 @@
4435 BFQ_DEFAULT_GRP_CLASS - 1;
4536 }
4637
38
+unsigned int bfq_tot_busy_queues(struct bfq_data *bfqd)
39
+{
40
+ return bfqd->busy_queues[0] + bfqd->busy_queues[1] +
41
+ bfqd->busy_queues[2];
42
+}
43
+
4744 static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
4845 bool expiration);
4946
....@@ -53,7 +50,7 @@
5350 * bfq_update_next_in_service - update sd->next_in_service
5451 * @sd: sched_data for which to perform the update.
5552 * @new_entity: if not NULL, pointer to the entity whose activation,
56
- * requeueing or repositionig triggered the invocation of
53
+ * requeueing or repositioning triggered the invocation of
5754 * this function.
5855 * @expiration: id true, this function is being invoked after the
5956 * expiration of the in-service entity
....@@ -84,7 +81,7 @@
8481
8582 /*
8683 * If this update is triggered by the activation, requeueing
87
- * or repositiong of an entity that does not coincide with
84
+ * or repositioning of an entity that does not coincide with
8885 * sd->next_in_service, then a full lookup in the active tree
8986 * can be avoided. In fact, it is enough to check whether the
9087 * just-modified entity has the same priority as
....@@ -280,10 +277,7 @@
280277 */
281278 static u64 bfq_delta(unsigned long service, unsigned long weight)
282279 {
283
- u64 d = (u64)service << WFQ_SERVICE_SHIFT;
284
-
285
- do_div(d, weight);
286
- return d;
280
+ return div64_ul((u64)service << WFQ_SERVICE_SHIFT, weight);
287281 }
288282
289283 /**
....@@ -651,7 +645,7 @@
651645 {
652646 struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
653647
654
- entity->on_st = false;
648
+ entity->on_st_or_in_serv = false;
655649 st->wsum -= entity->weight;
656650 if (bfqq && !is_in_service)
657651 bfq_put_queue(bfqq);
....@@ -731,7 +725,7 @@
731725 struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
732726 unsigned int prev_weight, new_weight;
733727 struct bfq_data *bfqd = NULL;
734
- struct rb_root *root;
728
+ struct rb_root_cached *root;
735729 #ifdef CONFIG_BFQ_GROUP_IOSCHED
736730 struct bfq_sched_data *sd;
737731 struct bfq_group *bfqg;
....@@ -747,6 +741,8 @@
747741 }
748742 #endif
749743
744
+ /* Matches the smp_wmb() in bfq_group_set_weight. */
745
+ smp_rmb();
750746 old_st->wsum -= entity->weight;
751747
752748 if (entity->new_weight != entity->orig_weight) {
....@@ -1003,10 +999,10 @@
1003999 */
10041000 bfq_get_entity(entity);
10051001
1006
- entity->on_st = true;
1002
+ entity->on_st_or_in_serv = true;
10071003 }
10081004
1009
-#ifdef BFQ_GROUP_IOSCHED_ENABLED
1005
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
10101006 if (!bfq_entity_to_bfqq(entity)) { /* bfq_group */
10111007 struct bfq_group *bfqg =
10121008 container_of(entity, struct bfq_group, entity);
....@@ -1154,15 +1150,14 @@
11541150 }
11551151
11561152 /**
1157
- * __bfq_deactivate_entity - deactivate an entity from its service tree.
1158
- * @entity: the entity to deactivate.
1153
+ * __bfq_deactivate_entity - update sched_data and service trees for
1154
+ * entity, so as to represent entity as inactive
1155
+ * @entity: the entity being deactivated.
11591156 * @ins_into_idle_tree: if false, the entity will not be put into the
11601157 * idle tree.
11611158 *
1162
- * Deactivates an entity, independently of its previous state. Must
1163
- * be invoked only if entity is on a service tree. Extracts the entity
1164
- * from that tree, and if necessary and allowed, puts it into the idle
1165
- * tree.
1159
+ * If necessary and allowed, puts entity into the idle tree. NOTE:
1160
+ * entity may be on no tree if in service.
11661161 */
11671162 bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
11681163 {
....@@ -1170,7 +1165,10 @@
11701165 struct bfq_service_tree *st;
11711166 bool is_in_service;
11721167
1173
- if (!entity->on_st) /* entity never activated, or already inactive */
1168
+ if (!entity->on_st_or_in_serv) /*
1169
+ * entity never activated, or
1170
+ * already inactive
1171
+ */
11741172 return false;
11751173
11761174 /*
....@@ -1391,7 +1389,7 @@
13911389 * In this first case, update the virtual time in @st too (see the
13921390 * comments on this update inside the function).
13931391 *
1394
- * In constrast, if there is an in-service entity, then return the
1392
+ * In contrast, if there is an in-service entity, then return the
13951393 * entity that would be set in service if not only the above
13961394 * conditions, but also the next one held true: the currently
13971395 * in-service entity, on expiration,
....@@ -1474,12 +1472,12 @@
14741472 * is being invoked as a part of the expiration path
14751473 * of the in-service queue. In this case, even if
14761474 * sd->in_service_entity is not NULL,
1477
- * sd->in_service_entiy at this point is actually not
1475
+ * sd->in_service_entity at this point is actually not
14781476 * in service any more, and, if needed, has already
14791477 * been properly queued or requeued into the right
14801478 * tree. The reason why sd->in_service_entity is still
14811479 * not NULL here, even if expiration is true, is that
1482
- * sd->in_service_entiy is reset as a last step in the
1480
+ * sd->in_service_entity is reset as a last step in the
14831481 * expiration path. So, if expiration is true, tell
14841482 * __bfq_lookup_next_entity that there is no
14851483 * sd->in_service_entity.
....@@ -1514,7 +1512,7 @@
15141512 struct bfq_sched_data *sd;
15151513 struct bfq_queue *bfqq;
15161514
1517
- if (bfqd->busy_queues == 0)
1515
+ if (bfq_tot_busy_queues(bfqd) == 0)
15181516 return NULL;
15191517
15201518 /*
....@@ -1625,7 +1623,7 @@
16251623 * service tree either, then release the service reference to
16261624 * the queue it represents (taken with bfq_get_entity).
16271625 */
1628
- if (!in_serv_entity->on_st) {
1626
+ if (!in_serv_entity->on_st_or_in_serv) {
16291627 /*
16301628 * If no process is referencing in_serv_bfqq any
16311629 * longer, then the service reference may be the only
....@@ -1679,7 +1677,7 @@
16791677
16801678 bfq_clear_bfqq_busy(bfqq);
16811679
1682
- bfqd->busy_queues--;
1680
+ bfqd->busy_queues[bfqq->ioprio_class - 1]--;
16831681
16841682 if (bfqq->wr_coeff > 1)
16851683 bfqd->wr_busy_queues--;
....@@ -1702,7 +1700,7 @@
17021700 bfq_activate_bfqq(bfqd, bfqq);
17031701
17041702 bfq_mark_bfqq_busy(bfqq);
1705
- bfqd->busy_queues++;
1703
+ bfqd->busy_queues[bfqq->ioprio_class - 1]++;
17061704
17071705 if (!bfqq->dispatched)
17081706 if (bfqq->wr_coeff == 1)