diff options
-rw-r--r-- | .SRCINFO | 6 | ||||
-rw-r--r-- | 0005-BFQ-update-to-v8r5.patch (renamed from 0005-BFQ-update-to-v8r6.patch) | 1868 | ||||
-rw-r--r-- | PKGBUILD | 6 |
3 files changed, 36 insertions, 1844 deletions
@@ -1,6 +1,6 @@ pkgbase = linux-rt-bfq pkgver = 4.8.14_rt9 - pkgrel = 3 + pkgrel = 4 url = http://algo.ing.unimo.it arch = i686 arch = x86_64 @@ -28,7 +28,7 @@ pkgbase = linux-rt-bfq source = linux.preset source = net_handle_no_dst_on_skb_in_icmp6_send.patch source = 0001-x86-fpu-Fix-invalid-FPU-ptrace-state-after-execve.patch - source = 0005-BFQ-update-to-v8r6.patch + source = 0005-BFQ-update-to-v8r5.patch validpgpkeys = ABAF11C65A2970B130ABE3C479BE3E4300411886 validpgpkeys = 647F28654894E3BD457199BE38DBBDC86092693E validpgpkeys = 64254695FFF0AA4466CC19E67B96E8162A8CF5D1 @@ -53,7 +53,7 @@ pkgbase = linux-rt-bfq sha512sums = 2dc6b0ba8f7dbf19d2446c5c5f1823587de89f4e28e9595937dd51a87755099656f2acec50e3e2546ea633ad1bfd1c722e0c2b91eef1d609103d8abdc0a7cbaf sha512sums = c53bd47527adbd2599a583e05a7d24f930dc4e86b1de017486588205ad6f262a51a4551593bc7a1218c96541ea073ea03b770278d947b1cd0d2801311fcc80e5 sha512sums = 002d5e0ccfa5824c1750912a6400ff722672d6587b74ba66b1127cf1228048f604bba107617cf4f4477884039af4d4d196cf1b74cefe43b0bddc82270f11940d - sha512sums = 6c9992e1ae39e81577af9399d583c8c04c2d8ff205eb58ed082016e310ed2b2f040689ae8f2a36bf131d3c58d40eaf94ba2bd4b9fc0006eeedb9569f8c0deef5 + sha512sums = 67d11b25179e2d46effa70a6a151626a0b6dff900d887497b173fe894b839104d370cfbabf531c3f3914a15c3ec3cac6297dbaa5f294e6fcb644e2b26d8579b7 pkgname = linux-rt-bfq pkgdesc = Linux Kernel and modules with the RT patch and the BFQ scheduler. diff --git a/0005-BFQ-update-to-v8r6.patch b/0005-BFQ-update-to-v8r5.patch index 69e33cb2fcc2..4283280db9c9 100644 --- a/0005-BFQ-update-to-v8r6.patch +++ b/0005-BFQ-update-to-v8r5.patch @@ -1,7 +1,7 @@ -From 1acff6b391cd626a495e42c9782bf2139b9f330f Mon Sep 17 00:00:00 2001 +From 3139305e535a2e8e5de3dc0b7182ddea148719eb Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Wed, 19 Oct 2016 20:11:42 +0200 -Subject: [PATCH 01/28] Documentation/block: add bfq-iosched.txt +Subject: [PATCH 01/15] Documentation/block: add bfq-iosched.txt Documentation of BFQ benefits, inner workings, interface and tunables. @@ -539,10 +539,10 @@ index 0000000..67e1269 + http://algogroup.unimore.it/people/paolo/disk_sched/bfq-v1-suite- + results.pdf -From 11f0d8caa035ff4fe6fe02ebc0f2f14dc5473479 Mon Sep 17 00:00:00 2001 +From d4003acc5f0632d2181a886e91c0d7f55410912f Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Sat, 22 Oct 2016 15:26:33 +0200 -Subject: [PATCH 02/28] BUGFIX: Replace max wrongly used for modulo numbers +Subject: [PATCH 02/15] BUGFIX: Replace max wrongly used for modulo numbers Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -571,10 +571,10 @@ index eef6ff4..c161ff0 100644 pr_crit( "BFQ WARNING:last %lu budget %lu jiffies %lu", -From eb59d4ac664f64372c440006b0cd27bf137a2025 Mon Sep 17 00:00:00 2001 +From 81a6c17c210641aa35a09cc84a6ed059a0c4d0c0 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Mon, 24 Oct 2016 17:08:32 +0200 -Subject: [PATCH 03/28] Improve bfq-iosched.txt +Subject: [PATCH 03/15] Improve bfq-iosched.txt Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -607,10 +607,10 @@ index 67e1269..8626b14 100644 1-2 Server systems ------------------ -From a53d556f54f33de6e71f909748c6994ff90fa243 Mon Sep 17 00:00:00 2001 +From 833bdc84b32325dc73e1f44e36e6e06613317ab9 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Mon, 24 Oct 2016 20:36:53 +0200 -Subject: [PATCH 04/28] Improve help message in Kconfig.iosched +Subject: [PATCH 04/15] Improve help message in Kconfig.iosched Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -640,10 +640,10 @@ index 6d92579..277b112 100644 config BFQ_GROUP_IOSCHED bool "BFQ hierarchical scheduling support" -From 710824a320c015b314abba3bc2982d0f3caa0acc Mon Sep 17 00:00:00 2001 +From ba6042a890957d2fd361d365716631ff4e001488 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Mon, 24 Oct 2016 20:37:59 +0200 -Subject: [PATCH 05/28] Remove stray disk word in first line +Subject: [PATCH 05/15] Remove stray disk word in first line SIgned-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -662,10 +662,10 @@ index c161ff0..b5fdd45 100644 * Based on ideas and code from CFQ: * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> -From a2f6ff7877e60f533cdf39e941fc45f7b5aafcee Mon Sep 17 00:00:00 2001 +From cc5a8e029ca9987f7dd41bdb7e318832a0050c57 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Mon, 24 Oct 2016 20:41:03 +0200 -Subject: [PATCH 06/28] BUGFIX: Remove wrong conversion in use of +Subject: [PATCH 06/15] BUGFIX: Remove wrong conversion in use of bfq_fifo_expire Signed-off-by: Paolo Valente <paolo.valente@linaro.org> @@ -688,10 +688,10 @@ index b5fdd45..a8c6887 100644 bfq_rq_enqueued(bfqd, bfqq, rq); -From c91736449d06052469c2c3abaf5d455b85e77417 Mon Sep 17 00:00:00 2001 +From fa9aeddfc1edf2ee61120d4b0df1083d48b8a678 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Tue, 25 Oct 2016 09:31:37 +0200 -Subject: [PATCH 07/28] bfq-iosched.txt: add description of preemption +Subject: [PATCH 07/15] bfq-iosched.txt: add description of preemption Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -716,10 +716,10 @@ index 8626b14..8979408 100644 lower-priority queues are not served as long as there are higher-priority queues. Among queues in the same class, the -From 2dc9393e7ff65d0e5340118402134cff03276b1c Mon Sep 17 00:00:00 2001 +From 7718ca2daa31bdad67259a895818eec806d07e8a Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Sat, 5 Nov 2016 18:09:07 +0100 -Subject: [PATCH 08/28] Add parentheses to complex macros +Subject: [PATCH 08/15] Add parentheses to complex macros Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -772,10 +772,10 @@ index a8c6887..88be34e 100644 #define BFQ_RATE_REF_INTERVAL NSEC_PER_SEC -From 882f0607d82efe44d98634ce1fdcc4b602ccf5ec Mon Sep 17 00:00:00 2001 +From 5a13dfaab17e2d3f5f443dc0cb0b8f8597043881 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Sat, 5 Nov 2016 18:32:20 +0100 -Subject: [PATCH 09/28] Fix type in bfq-iosched.txt +Subject: [PATCH 09/15] Fix type in bfq-iosched.txt Sigend-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -796,10 +796,10 @@ index 8979408..5ba67af 100644 values is that they coarsen the granularity of short-term bandwidth and latency guarantees. -From 99b1da54ca162abdc9e62915050154b35bd9bc27 Mon Sep 17 00:00:00 2001 +From 3fbfffc1771e0c63e4f814bf35922ad2287db55c Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Sat, 5 Nov 2016 18:34:58 +0100 -Subject: [PATCH 10/28] BFQ-v8r5 +Subject: [PATCH 10/15] BFQ-v8r5 Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -832,10 +832,10 @@ index ea1e7d8..b80abe0 100644 * Based on ideas and code from CFQ: * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> -From d825ef204aa934e1fd9ebd925276ca0e67783508 Mon Sep 17 00:00:00 2001 +From e1b346d1ae61ce3c2a80fff8a3a2774e3473fc32 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Wed, 7 Dec 2016 19:31:37 +0100 -Subject: [PATCH 11/28] Improve documentation +Subject: [PATCH 11/15] Improve documentation Signed-off-by: Paolo Valente <paolo.valente@linaro.org> @@ -926,10 +926,10 @@ index 277b112..f2cd945 100644 choice prompt "Default I/O scheduler" -From 880441682487350cd5b116c2cea830351f9c9478 Mon Sep 17 00:00:00 2001 +From 91f80c0f854dc1c8c858f3301650c11d8605b76e Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Wed, 7 Dec 2016 19:43:58 +0100 -Subject: [PATCH 12/28] Add and improve pointers in initial comments +Subject: [PATCH 12/15] Add and improve pointers in initial comments --- block/bfq-iosched.c | 14 ++++++++++---- @@ -968,10 +968,10 @@ index 0f3081d..b07d251 100644 * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf * -From 60dad3833c9afa52315508579cbb4bac7e55d3a3 Mon Sep 17 00:00:00 2001 +From 4c1597055dd1543187e72113bf00015ca60ea304 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Fri, 9 Dec 2016 07:05:29 +0100 -Subject: [PATCH 13/28] Fix typo in comments on bfq_lookup_next_entity +Subject: [PATCH 13/15] Fix typo in comments on bfq_lookup_next_entity Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -992,10 +992,10 @@ index 45d63d3..9afeaab 100644 */ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, -From 15f446f3bc189df88c64366930b5e237c8d9d5d5 Mon Sep 17 00:00:00 2001 +From ae5bb499492f318d6314ccccd3554d2e51563fa0 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Fri, 9 Dec 2016 09:46:41 +0100 -Subject: [PATCH 14/28] Fix false-positive warning for uninitialized var +Subject: [PATCH 14/15] Fix false-positive warning for uninitialized var Signed-off-by: Paolo Valente <paolo.valente@linaro.org> --- @@ -1016,10 +1016,10 @@ index b07d251..3043e5e 100644 if (__data < (MIN)) \ __data = (MIN); \ -From 1430feb8c7194f72be0a8066ad6b996d78bf3e09 Mon Sep 17 00:00:00 2001 +From dfcf3e0d48dddcfebe10d0f67243d780fedd28d4 Mon Sep 17 00:00:00 2001 From: Paolo Valente <paolo.valente@linaro.org> Date: Sun, 11 Dec 2016 11:46:13 +0100 -Subject: [PATCH 15/28] Improve and fix some bugs in hierarchical code +Subject: [PATCH 15/15] Improve and fix some bugs in hierarchical code This commit provides the following contributions. @@ -1873,1812 +1873,4 @@ index b80abe0..6b28030 100644 /* user-configured max budget value (0 for auto-tuning) */ int bfq_user_max_budget; - -From b5734696e18577dda6ef6571af7cb3718937d2f5 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Wed, 14 Dec 2016 17:56:25 +0100 -Subject: [PATCH 16/28] BFQ v8r6-rc1 - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 2 +- - block/bfq.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 2d00bd10..72443bd 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -5218,7 +5218,7 @@ static struct blkcg_policy blkcg_policy_bfq = { - static int __init bfq_init(void) - { - int ret; -- char msg[50] = "BFQ I/O-scheduler: v8r5"; -+ char msg[60] = "BFQ I/O-scheduler: v8r6-rc1"; - - #ifdef CONFIG_BFQ_GROUP_IOSCHED - ret = blkcg_policy_register(&blkcg_policy_bfq); -diff --git a/block/bfq.h b/block/bfq.h -index 6b28030..d4d784f 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -1,5 +1,5 @@ - /* -- * BFQ-v8r5 for 4.8.0: data structures and common functions prototypes. -+ * BFQ v8r6-rc1 for 4.9.0: data structures and common functions prototypes. - * - * Based on ideas and code from CFQ: - * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> - -From a7c98629904dcc103d676c2b8e2ceaff4ca19ca2 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Wed, 14 Dec 2016 18:07:41 +0100 -Subject: [PATCH 17/28] Port and improve CFQ commit 41647e7a - -BFQ currently used the same logic for detecting seeky queues for -for rotational disks and SSDs. This logic is appropriate for the -former, as it takes into account only inter-request distance, and -this is the dominant latency factor on a rotational device. Yet -things change with flash-based devices, where servign a large -requests still yields a high throughput, even the request is far -from the previous request served. This commits extends seeky -detection to take into accoutn also this fact with flash-based -devices. In particular, this commit is an improved port of the -original commit 41647e7a for CFQ. - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 72443bd..153292f 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -117,6 +117,7 @@ struct kmem_cache *bfq_pool; - #define BFQ_HW_QUEUE_SAMPLES 32 - - #define BFQQ_SEEK_THR (sector_t)(8 * 100) -+#define BFQQ_SECT_THR_NONROT (sector_t)(2 * 32) - #define BFQQ_CLOSE_THR (sector_t)(8 * 1024) - #define BFQQ_SEEKY(bfqq) (hweight32(bfqq->seek_history) > 32/8) - -@@ -4117,7 +4118,9 @@ bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq, - { - bfqq->seek_history <<= 1; - bfqq->seek_history |= -- get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR; -+ get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR && -+ (!blk_queue_nonrot(bfqd->queue) || -+ blk_rq_sectors(rq) < BFQQ_SECT_THR_NONROT); - } - - /* - -From 5cacb798d523b9fa7e394ca3a369a0c196e0b022 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Thu, 15 Dec 2016 15:57:22 +0100 -Subject: [PATCH 18/28] Provide more details in switching-off-wr message - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 153292f..a5853c7 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -656,7 +656,9 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) - time_is_before_jiffies(bfqq->last_wr_start_finish + - bfqq->wr_cur_max_time))) { - bfq_log_bfqq(bfqq->bfqd, bfqq, -- "resume state: switching off wr"); -+ "resume state: switching off wr (%u + %u < %u)", -+ bfqq->last_wr_start_finish, bfqq->wr_cur_max_time, -+ jiffies); - - bfqq->wr_coeff = 1; - } - -From 6f62391c914a25818f839b932a9e1b16ee28c1f1 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Thu, 15 Dec 2016 16:10:17 +0100 -Subject: [PATCH 19/28] Remove useless parameter from bfq_del_bfqq_busy - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 6 +++--- - block/bfq-sched.c | 5 ++--- - 2 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index a5853c7..0d54cc1 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -656,7 +656,7 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) - time_is_before_jiffies(bfqq->last_wr_start_finish + - bfqq->wr_cur_max_time))) { - bfq_log_bfqq(bfqq->bfqd, bfqq, -- "resume state: switching off wr (%u + %u < %u)", -+ "resume state: switching off wr (%lu + %lu < %lu)", - bfqq->last_wr_start_finish, bfqq->wr_cur_max_time, - jiffies); - -@@ -1525,7 +1525,7 @@ static void bfq_remove_request(struct request *rq) - BUG_ON(bfqq->entity.budget < 0); - - if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) { -- bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ bfq_del_bfqq_busy(bfqd, bfqq); - - /* bfqq emptied. In normal operation, when - * bfqq is empty, bfqq->entity.service and -@@ -2662,7 +2662,7 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) - */ - bfqq->budget_timeout = jiffies; - -- bfq_del_bfqq_busy(bfqd, bfqq, 1); -+ bfq_del_bfqq_busy(bfqd, bfqq); - } else { - bfq_activate_bfqq(bfqd, bfqq); - /* -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 2f54ac5..fae28ee 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -1635,8 +1635,7 @@ static void bfqg_stats_update_dequeue(struct bfq_group *bfqg); - * Called when the bfqq no longer has requests pending, remove it from - * the service tree. - */ --static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, -- int requeue) -+static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) - { - BUG_ON(!bfq_bfqq_busy(bfqq)); - BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -@@ -1660,7 +1659,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, - - BUG_ON(bfqq->entity.budget < 0); - -- bfq_deactivate_bfqq(bfqd, bfqq, requeue); -+ bfq_deactivate_bfqq(bfqd, bfqq, 1); - - BUG_ON(bfqq->entity.budget < 0); - } - -From 1469db5fec95e3bfad0fe60dc1a843b0c5de4efa Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Thu, 15 Dec 2016 16:40:09 +0100 -Subject: [PATCH 20/28] Further improve code and comments for hierarchical code - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-cgroup.c | 6 +++--- - block/bfq-iosched.c | 2 +- - block/bfq-sched.c | 45 ++++++++++++++++++++++++++++++--------------- - 3 files changed, 34 insertions(+), 19 deletions(-) - -diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -index a04bc40..bd31da5 100644 ---- a/block/bfq-cgroup.c -+++ b/block/bfq-cgroup.c -@@ -552,7 +552,7 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, - BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); - - if (bfq_bfqq_busy(bfqq)) -- bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ bfq_deactivate_bfqq(bfqd, bfqq, false); - else if (entity->on_st) { - BUG_ON(&bfq_entity_service_tree(entity)->idle != - entity->tree); -@@ -664,7 +664,7 @@ static void bfq_flush_idle_tree(struct bfq_service_tree *st) - struct bfq_entity *entity = st->first_idle; - - for (; entity ; entity = st->first_idle) -- __bfq_deactivate_entity(entity, 0); -+ __bfq_deactivate_entity(entity, false); - } - - /** -@@ -769,7 +769,7 @@ static void bfq_pd_offline(struct blkg_policy_data *pd) - BUG_ON(bfqg->sched_data.next_in_service); - BUG_ON(bfqg->sched_data.in_service_entity); - -- __bfq_deactivate_entity(entity, 0); -+ __bfq_deactivate_entity(entity, false); - bfq_put_async_queues(bfqd, bfqg); - BUG_ON(entity->tree); - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 0d54cc1..7a56603 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -4738,7 +4738,7 @@ static void bfq_exit_queue(struct elevator_queue *e) - - BUG_ON(bfqd->in_service_queue); - list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) -- bfq_deactivate_bfqq(bfqd, bfqq, 0); -+ bfq_deactivate_bfqq(bfqd, bfqq, false); - - spin_unlock_irq(q->queue_lock); - -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index fae28ee..52911cc 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -841,9 +841,9 @@ static void __bfq_activate_entity(struct bfq_entity *entity, - * We are requeueing the current in-service entity, - * because of the requeueing of a just-expired - * non-idle leaf entity in the path originating from -- * this entity. In fact, in this case, then all -- * entities in this path need to be requeued again for -- * next service. -+ * this entity. In fact, in this case, all entities in -+ * this path need to be requeued again for next -+ * service. - * - * Before requeueing, the start time of the entity - * must be moved forward to account for the service -@@ -882,7 +882,7 @@ static void __bfq_activate_entity(struct bfq_entity *entity, - * implies that the finish time of this entity must be - * updated. Such an update may cause the scheduling, - * i.e., the position in the active tree, of this -- * entity to change. We handle this fact by: 1) -+ * entity to change. We handle this change by: 1) - * dequeueing the entity here, 2) updating the finish - * time and requeueing the entity according to the new - * timestamps below. This is the same approach as the -@@ -1054,7 +1054,7 @@ static void bfq_activate_entity(struct bfq_entity *entity, - * if the entity was in service or if it was the next_in_service for - * its sched_data; return %false otherwise. - */ --static bool __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+static bool __bfq_deactivate_entity(struct bfq_entity *entity, bool requeue) - { - struct bfq_sched_data *sd = entity->sched_data; - struct bfq_service_tree *st; -@@ -1118,26 +1118,41 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) - if (sd->next_in_service) - /* - * The parent entity is still backlogged, -- * because next_in_service is not NULL, and -+ * because next_in_service is not NULL. So, no -+ * upwards deactivation is needed. Yet, - * next_in_service has been updated (see -- * comment on the body of the above if): -- * upwards update of the schedule is needed. -+ * comment on the body of the above if). Then -+ * the schedule nees to be updated upwards. - */ -- goto update; -+ goto update_schedule; - - /* -- * If we get here, then the parent is no more backlogged and -- * we want to propagate the deactivation upwards. -+ * If we get here, then the parent is no more -+ * backlogged and we need to propagate the -+ * deactivation upwards. Then let the loop go on. - */ -- requeue = 1; -+ -+ /* -+ * Also let parent be queued into the idle tree on -+ * deactivation, to preserve service guarantees, and -+ * assuming that who invoked this function does not -+ * need parent entities too to be removed by any tree. -+ */ -+ requeue = true; - } - - return; - --update: -+update_schedule: - entity = parent; - for_each_entity(entity) { - struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ /* -+ * Invoke __bfq_activate_entity on entity, even if -+ * already active, to update its position in the -+ * active tree (because sd->next_in_service has -+ * changed) -+ */ - __bfq_activate_entity(entity, false); - - sd = entity->sched_data; -@@ -1613,7 +1628,7 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) - } - - static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -- int requeue) -+ bool requeue) - { - struct bfq_entity *entity = &bfqq->entity; - -@@ -1659,7 +1674,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) - - BUG_ON(bfqq->entity.budget < 0); - -- bfq_deactivate_bfqq(bfqd, bfqq, 1); -+ bfq_deactivate_bfqq(bfqd, bfqq, true); - - BUG_ON(bfqq->entity.budget < 0); - } - -From d12d41bee45b988e1ae4f8dcece4bcecb5ad74a9 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Thu, 15 Dec 2016 22:11:39 +0100 -Subject: [PATCH 21/28] Optimize update of next_in_service entity - -If the update of the next_in_service candidate entity is triggered by -the activation of an entity, then it is not necessary to perform full -lookups in the active trees to update next_in_service. In fact, it is -enough to check whether the just-activated entity has a higher -priority of next_in_service, or, even if it has the same priority as -next_in_service, is eligible and has a lower virtual finish time than -next_in_service. If this compound condition holds, then the new entity -becomes the new next_in_service. Otherwise no change is needed. This -commit implements this optimization. - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-sched.c | 167 ++++++++++++++++++++++++++++++++++++++++-------------- - block/bfq.h | 11 +++- - 2 files changed, 134 insertions(+), 44 deletions(-) - -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 52911cc..09e494b 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -14,6 +14,18 @@ - - static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); - -+/** -+ * bfq_gt - compare two timestamps. -+ * @a: first ts. -+ * @b: second ts. -+ * -+ * Return @a > @b, dealing with wrapping correctly. -+ */ -+static int bfq_gt(u64 a, u64 b) -+{ -+ return (s64)(a - b) > 0; -+} -+ - #ifdef CONFIG_BFQ_GROUP_IOSCHED - /* both next loops stop at one of the child entities of the root group */ - #define for_each_entity(entity) \ -@@ -46,18 +58,99 @@ static void bfq_update_budget(struct bfq_entity *next_in_service) - bfqg_entity->budget = next_in_service->budget; - } - --/* -- * Incomplete version that always returns true. It will return also -- * false in its complete version, in case either next_in_service has -- * not changed, or next_in_service has changed but in a way that will -- * not influence upper levels. -+static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree) -+{ -+ struct rb_node *node = tree->rb_node; -+ -+ return rb_entry(node, struct bfq_entity, rb_node); -+} -+ -+/** -+ * bfq_update_next_in_service - update sd->next_in_service -+ * @sd: sched_data for which to perform the update. -+ * @new_entity: if not NULL, pointer to the entity whose activation -+ * triggered the invocation of this function. -+ * -+ * This function is called to update sd->next_in_service, which, in -+ * its turn, may change as a consequence of the insertion or -+ * extraction of an entity into/from one of the active trees of -+ * sd. These insertions/extractions occur as a consequence of -+ * activations/deactivations of entities, with some activations being -+ * 'true' activations, and other activations being requeueings (i.e., -+ * implementing the second, requeueing phase of the mechanism used to -+ * reposition an entity in its active tree; see comments on -+ * __bfq_activate_entity for details). In both the last two activation -+ * sub-cases, new_entity points to the just activated or requeued -+ * entity. -+ * -+ * This is a still incomplete version of this function, which always -+ * returns true. It will return also false in its complete version, in -+ * case either next_in_service has not changed, or next_in_service has -+ * changed but in a way that will not influence upper levels. - */ --static bool bfq_update_next_in_service(struct bfq_sched_data *sd) -+static bool bfq_update_next_in_service(struct bfq_sched_data *sd, -+ struct bfq_entity *new_entity) - { -- struct bfq_entity *next_in_service; -+ struct bfq_entity *next_in_service = sd->next_in_service; - struct bfq_queue *bfqq; - -- next_in_service = bfq_lookup_next_entity(sd); -+ /* -+ * If this update is triggered by the activation of a new -+ * entity, then a full lookup in the active tree can be -+ * avoided. In fact, it is enough to check whether the -+ * just-activated entity has a higher priority of -+ * sd->next_in_service, or, even if it has the same priority -+ * as sd->next_in_service, is eligible and has a lower virtual -+ * finish time than sd->next_in_service. If this compound -+ * condition holds, then the new entity becomes the new -+ * next_in_service. Otherwise no change is needed. -+ */ -+ if (new_entity) { -+ /* -+ * Flag used to decide whether to replace -+ * sd->next_in_service with new_entity. Tentatively -+ * set to true, and left as true if -+ * sd->next_in_service is NULL. -+ */ -+ bool replace_next = true; -+ -+ if (new_entity == sd->next_in_service) -+ return false; -+ -+ /* -+ * If there is already a next_in_service candidate -+ * entity, then compare class priorities or timestamps -+ * to decide whether to replace sd->service_tree with -+ * new_entity. -+ */ -+ if (next_in_service) { -+ unsigned int new_entity_class_idx = -+ bfq_class_idx(new_entity); -+ struct bfq_service_tree *st = -+ sd->service_tree + new_entity_class_idx; -+ -+ /* -+ * For efficiency, evaluate the most likely -+ * sub-condition first. -+ */ -+ replace_next = -+ (new_entity_class_idx == -+ bfq_class_idx(next_in_service) -+ && -+ !bfq_gt(new_entity->start, st->vtime) -+ && -+ bfq_gt(next_in_service->finish, -+ new_entity->finish)) -+ || -+ new_entity_class_idx < -+ bfq_class_idx(next_in_service); -+ } -+ -+ if (replace_next) -+ next_in_service = new_entity; -+ } else /* invoked because of a deactivation: lookup needed */ -+ next_in_service = bfq_lookup_next_entity(sd); -+ - sd->next_in_service = next_in_service; - - if (next_in_service) -@@ -109,18 +202,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service) - */ - #define WFQ_SERVICE_SHIFT 22 - --/** -- * bfq_gt - compare two timestamps. -- * @a: first ts. -- * @b: second ts. -- * -- * Return @a > @b, dealing with wrapping correctly. -- */ --static int bfq_gt(u64 a, u64 b) --{ -- return (s64)(a - b) > 0; --} -- - static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) - { - struct bfq_queue *bfqq = NULL; -@@ -816,15 +897,18 @@ static void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq, - } - - /** -- * __bfq_activate_entity - activate an entity. -- * @entity: the entity being activated. -- * @non_blocking_wait_rq: true if this entity was waiting for a request -+ * __bfq_activate_entity - handle activation or requeueing of an entity. -+ * @entity: the entity being activated or requeued. -+ * @non_blocking_wait_rq: true if entity was waiting for a request - * -- * Called whenever an entity is activated, i.e., it is not active and one -- * of its children receives a new request, or has to be reactivated due to -- * budget exhaustion. It uses the current budget of the entity (and the -- * service received if @entity is active) of the queue to calculate its -- * timestamps. -+ * Called whenever an entity is activated, which happens either if the -+ * entity is not active and one of its children receives a new request -+ * (true activation), or if the entity needs to be repositioned in its -+ * active tree (requeueing, as explained in detail in the comments -+ * inside the function). -+ * -+ * Basically, this function updates the timestamps of entity and -+ * (re)inserts entity into its active tree. - */ - static void __bfq_activate_entity(struct bfq_entity *entity, - bool non_blocking_wait_rq) -@@ -1027,7 +1111,7 @@ static void bfq_activate_entity(struct bfq_entity *entity, - RB_EMPTY_ROOT(&(sd->service_tree+1)->active) && - RB_EMPTY_ROOT(&(sd->service_tree+2)->active)); - -- if (!bfq_update_next_in_service(sd)) { -+ if (!bfq_update_next_in_service(sd, entity)) { - BUG_ON(!sd->next_in_service); - /* - * No need to propagate the activation to the -@@ -1081,8 +1165,8 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity, bool requeue) - else if (entity->tree) - BUG(); - -- if (was_in_service || sd->next_in_service == entity) -- ret = bfq_update_next_in_service(sd); -+ if (sd->next_in_service == entity) -+ ret = bfq_update_next_in_service(sd, NULL); - - if (!requeue || !bfq_gt(entity->finish, st->vtime)) - bfq_forget_entity(st, entity); -@@ -1169,7 +1253,7 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) - "invoking udpdate_next for this entity"); - } - #endif -- if (!bfq_update_next_in_service(sd)) -+ if (!bfq_update_next_in_service(sd, entity)) - break; - } - } -@@ -1183,28 +1267,27 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) - */ - static u64 bfq_calc_vtime_jump(struct bfq_service_tree *st) - { -- struct bfq_entity *entry; -- struct rb_node *node = st->active.rb_node; -+ struct bfq_entity *root_entity = bfq_root_active_entity(&st->active); - -- entry = rb_entry(node, struct bfq_entity, rb_node); -- if (bfq_gt(entry->min_start, st->vtime)) { -- struct bfq_queue *bfqq = bfq_entity_to_bfqq(entry); -+ if (bfq_gt(root_entity->min_start, st->vtime)) { -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity); - - if (bfqq) - bfq_log_bfqq(bfqq->bfqd, bfqq, - "calc_vtime_jump: new value %llu", -- entry->min_start); -+ root_entity->min_start); - #ifdef CONFIG_BFQ_GROUP_IOSCHED - else { - struct bfq_group *bfqg = -- container_of(entry, struct bfq_group, entity); -+ container_of(root_entity, struct bfq_group, -+ entity); - - bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg, - "calc_vtime_jump: new value %llu", -- entry->min_start); -+ root_entity->min_start); - } - #endif -- return entry->min_start; -+ return root_entity->min_start; - } - return st->vtime; - } -@@ -1608,7 +1691,7 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) - for_each_entity(entity) { - struct bfq_sched_data *sd = entity->sched_data; - -- if(!bfq_update_next_in_service(sd)) -+ if(!bfq_update_next_in_service(sd, NULL)) - break; - } - -diff --git a/block/bfq.h b/block/bfq.h -index d4d784f..9c68d8b 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -806,13 +806,20 @@ struct bfq_group { - - static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity); - -+static unsigned int bfq_class_idx(struct bfq_entity *entity) -+{ -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ -+ return bfqq ? bfqq->ioprio_class - 1 : -+ BFQ_DEFAULT_GRP_CLASS - 1; -+} -+ - static struct bfq_service_tree * - bfq_entity_service_tree(struct bfq_entity *entity) - { - struct bfq_sched_data *sched_data = entity->sched_data; - struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -- unsigned int idx = bfqq ? bfqq->ioprio_class - 1 : -- BFQ_DEFAULT_GRP_CLASS - 1; -+ unsigned int idx = bfq_class_idx(entity); - - BUG_ON(idx >= BFQ_IOPRIO_CLASSES); - BUG_ON(sched_data == NULL); - -From 634414378918d47830a12f2c0e0a6c526d227502 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Thu, 15 Dec 2016 22:15:42 +0100 -Subject: [PATCH 22/28] Fix bug causing occasional loss of weight raising - -When a bfq_queue, say bfqq, is split after a merging with another -bfq_queue, BFQ checks whether it has to restore for bfqq the -weight-raising state that bfqq had before being merged. In -particular, the weight-raising is restored only if, according to the -weight-raising duration decided for bfqq when it started to be -weight-raised (before being merged), bfqq would not have already -finished its weight-raising period. - -Yet, by mistake, such a duration is not saved when bfqq is merged. So, -if bfqq is freed and reallocated when it is split, then this duration -is wrongly set to zero on the split. As a consequence, the -weight-raising state of bfqq is wrongly not restored, which causes BFQ -to fail in guaranteeing a low latency to bfqq. - -This commit fixes this bug by saving weight-raising duration when bfqq -is merged, and correctly restoring it when bfqq is split. - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 2 ++ - block/bfq.h | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 7a56603..7aa3d55 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -650,6 +650,7 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) - bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt; - BUG_ON(time_is_after_jiffies(bfqq->wr_start_at_switch_to_srt)); - bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish; -+ bfqq->wr_cur_max_time = bic->saved_wr_cur_max_time; - BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); - - if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) || -@@ -1988,6 +1989,7 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq) - bic->saved_wr_coeff = bfqq->wr_coeff; - bic->saved_wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt; - bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish; -+ bic->saved_wr_cur_max_time = bfqq->wr_cur_max_time; - BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish)); - } - -diff --git a/block/bfq.h b/block/bfq.h -index 9c68d8b..1a03521 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -366,6 +366,7 @@ struct bfq_io_cq { - unsigned long saved_wr_coeff; - unsigned long saved_last_wr_start_finish; - unsigned long saved_wr_start_at_switch_to_srt; -+ unsigned int saved_wr_cur_max_time; - }; - - enum bfq_device_speed { - -From a63703d1fcce41e4d0b36e366c333b56fdd04fe3 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Fri, 16 Dec 2016 17:57:00 +0100 -Subject: [PATCH 23/28] Fix wrong reset of in-service entities - -In-service entities were reset with an indirect logic, which -happened to be even buggy for some cases. This commit fixes -this bug in two important steps. First, by replacing this -indirect logic with a direct logic, in which all involved -entities are immediately reset, with a bubble-up loop, when -the in-service queue is reset. Second, by restructuring the -code related to this change, so as to become not only correct -with respect to this change, but also cleaner and hopefully -clearer. - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-cgroup.c | 2 +- - block/bfq-iosched.c | 20 ++- - block/bfq-sched.c | 499 +++++++++++++++++++++++++++++++++------------------- - block/bfq.h | 6 +- - 4 files changed, 332 insertions(+), 195 deletions(-) - -diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c -index bd31da5..bbaecd0 100644 ---- a/block/bfq-cgroup.c -+++ b/block/bfq-cgroup.c -@@ -552,7 +552,7 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, - BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq)); - - if (bfq_bfqq_busy(bfqq)) -- bfq_deactivate_bfqq(bfqd, bfqq, false); -+ bfq_deactivate_bfqq(bfqd, bfqq, false, false); - else if (entity->on_st) { - BUG_ON(&bfq_entity_service_tree(entity)->idle != - entity->tree); -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 7aa3d55..23e4c94 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -600,7 +600,7 @@ static void bfq_updated_next_req(struct bfq_data *bfqd, - entity->budget = new_budget; - bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", - new_budget); -- bfq_activate_bfqq(bfqd, bfqq); -+ bfq_requeue_bfqq(bfqd, bfqq); - } - } - -@@ -1526,7 +1526,7 @@ static void bfq_remove_request(struct request *rq) - BUG_ON(bfqq->entity.budget < 0); - - if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) { -- bfq_del_bfqq_busy(bfqd, bfqq); -+ bfq_del_bfqq_busy(bfqd, bfqq, false); - - /* bfqq emptied. In normal operation, when - * bfqq is empty, bfqq->entity.service and -@@ -2643,8 +2643,6 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) - { - BUG_ON(bfqq != bfqd->in_service_queue); - -- __bfq_bfqd_reset_in_service(bfqd); -- - /* - * If this bfqq is shared between multiple processes, check - * to make sure that those processes are still issuing I/Os -@@ -2664,14 +2662,21 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) - */ - bfqq->budget_timeout = jiffies; - -- bfq_del_bfqq_busy(bfqd, bfqq); -+ bfq_del_bfqq_busy(bfqd, bfqq, true); - } else { -- bfq_activate_bfqq(bfqd, bfqq); -+ bfq_requeue_bfqq(bfqd, bfqq); - /* - * Resort priority tree of potential close cooperators. - */ - bfq_pos_tree_add_move(bfqd, bfqq); - } -+ -+ /* -+ * All in-service entities must have been properly deactivated -+ * or requeued before executing the next function, which -+ * resets all in-service entites as no more in service. -+ */ -+ __bfq_bfqd_reset_in_service(bfqd); - } - - /** -@@ -3819,7 +3824,6 @@ static void bfq_put_queue(struct bfq_queue *bfqq) - BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); - BUG_ON(bfqq->entity.tree); - BUG_ON(bfq_bfqq_busy(bfqq)); -- BUG_ON(bfqq->bfqd->in_service_queue == bfqq); - - if (bfq_bfqq_sync(bfqq)) - /* -@@ -4740,7 +4744,7 @@ static void bfq_exit_queue(struct elevator_queue *e) - - BUG_ON(bfqd->in_service_queue); - list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) -- bfq_deactivate_bfqq(bfqd, bfqq, false); -+ bfq_deactivate_bfqq(bfqd, bfqq, false, false); - - spin_unlock_irq(q->queue_lock); - -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 09e494b..3b8e05b 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -79,9 +79,9 @@ static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree) - * 'true' activations, and other activations being requeueings (i.e., - * implementing the second, requeueing phase of the mechanism used to - * reposition an entity in its active tree; see comments on -- * __bfq_activate_entity for details). In both the last two activation -- * sub-cases, new_entity points to the just activated or requeued -- * entity. -+ * __bfq_activate_entity and __bfq_requeue_entity for details). In -+ * both the last two activation sub-cases, new_entity points to the -+ * just activated or requeued entity. - * - * This is a still incomplete version of this function, which always - * returns true. It will return also false in its complete version, in -@@ -658,7 +658,7 @@ static void bfq_forget_entity(struct bfq_service_tree *st, - - BUG_ON(!entity->on_st); - -- entity->on_st = 0; -+ entity->on_st = false; - st->wsum -= entity->weight; - if (bfqq) { - sd = entity->sched_data; -@@ -896,115 +896,12 @@ static void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq, - max_t(int, 0, tot_serv_to_charge - entity->service)); - } - --/** -- * __bfq_activate_entity - handle activation or requeueing of an entity. -- * @entity: the entity being activated or requeued. -- * @non_blocking_wait_rq: true if entity was waiting for a request -- * -- * Called whenever an entity is activated, which happens either if the -- * entity is not active and one of its children receives a new request -- * (true activation), or if the entity needs to be repositioned in its -- * active tree (requeueing, as explained in detail in the comments -- * inside the function). -- * -- * Basically, this function updates the timestamps of entity and -- * (re)inserts entity into its active tree. -- */ --static void __bfq_activate_entity(struct bfq_entity *entity, -- bool non_blocking_wait_rq) -+static void bfq_update_fin_time_enqueue(struct bfq_entity *entity, -+ struct bfq_service_tree *st, -+ bool backshifted) - { -- struct bfq_sched_data *sd = entity->sched_data; -- struct bfq_service_tree *st = bfq_entity_service_tree(entity); - struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -- bool backshifted = false; -- -- BUG_ON(!sd); -- BUG_ON(!st); -- if (entity == sd->in_service_entity) { -- /* -- * We are requeueing the current in-service entity, -- * because of the requeueing of a just-expired -- * non-idle leaf entity in the path originating from -- * this entity. In fact, in this case, all entities in -- * this path need to be requeued again for next -- * service. -- * -- * Before requeueing, the start time of the entity -- * must be moved forward to account for the service -- * that the entity has received while in service. The -- * finish time will then be updated according to this -- * new value of the start time, and to the budget of -- * the entity. -- */ -- bfq_calc_finish(entity, entity->service); -- entity->start = entity->finish; -- sd->in_service_entity = NULL; -- BUG_ON(entity->tree && entity->tree != &st->active); -- /* -- * In addition, if the entity had more than one child -- * when set in service, then was not extracted from -- * the active tree. This implies that the position of -- * the entity in the active tree may need to be -- * changed now, because we have just updated the start -- * time of the entity, and we will update its finish -- * time in a moment (the requeueing is then, more -- * precisely, a repositioning in this case). To -- * implement this repositioning, we: 1) dequeue the -- * entity here, 2) update the finish time and -- * requeue the entity according to the new -- * timestamps below. -- */ -- if (entity->tree) -- bfq_active_extract(st, entity); -- } else if (entity->tree == &st->active) { -- /* -- * The entity is already active, and not in -- * service. In this case, this function gets called -- * only if the next_in_service entity below this -- * entity has changed, and this change has caused the -- * budget of this entity to change, which, finally -- * implies that the finish time of this entity must be -- * updated. Such an update may cause the scheduling, -- * i.e., the position in the active tree, of this -- * entity to change. We handle this change by: 1) -- * dequeueing the entity here, 2) updating the finish -- * time and requeueing the entity according to the new -- * timestamps below. This is the same approach as the -- * non-extracted-entity sub-case above. -- */ -- bfq_active_extract(st, entity); -- } else { /* This is a 'true' activation, not a requeueing. */ -- unsigned long long min_vstart; -- -- /* See comments on bfq_fqq_update_budg_for_activation */ -- if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) { -- backshifted = true; -- min_vstart = entity->finish; -- } else -- min_vstart = st->vtime; -- -- if (entity->tree == &st->idle) { -- /* -- * Must be on the idle tree, bfq_idle_extract() will -- * check for that. -- */ -- bfq_idle_extract(st, entity); -- entity->start = bfq_gt(min_vstart, entity->finish) ? -- min_vstart : entity->finish; -- } else { -- /* -- * The finish time of the entity may be invalid, and -- * it is in the past for sure, otherwise the queue -- * would have been on the idle tree. -- */ -- entity->start = min_vstart; -- st->wsum += entity->weight; -- bfq_get_entity(entity); -- -- BUG_ON(entity->on_st); -- entity->on_st = 1; -- } -- } -+ struct bfq_sched_data *sd = entity->sched_data; - - st = __bfq_entity_update_weight_prio(st, entity); - bfq_calc_finish(entity, entity->budget); -@@ -1087,37 +984,215 @@ static void __bfq_activate_entity(struct bfq_entity *entity, - BUG_ON(&st->active != &sd->service_tree->active && - &st->active != &(sd->service_tree+1)->active && - &st->active != &(sd->service_tree+2)->active); -+} -+ -+/** -+ * __bfq_activate_entity - handle activation of entity. -+ * @entity: the entity being activated. -+ * @non_blocking_wait_rq: true if entity was waiting for a request -+ * -+ * Called for a 'true' activation, i.e., if entity is not active and -+ * one of its children receives a new request. -+ * -+ * Basically, this function updates the timestamps of entity and -+ * inserts entity into its active tree, ater possible extracting it -+ * from its idle tree. -+ */ -+static void __bfq_activate_entity(struct bfq_entity *entity, -+ bool non_blocking_wait_rq) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ bool backshifted = false; -+ unsigned long long min_vstart; -+ -+ BUG_ON(!sd); -+ BUG_ON(!st); -+ -+ /* See comments on bfq_fqq_update_budg_for_activation */ -+ if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) { -+ backshifted = true; -+ min_vstart = entity->finish; -+ } else -+ min_vstart = st->vtime; -+ -+ if (entity->tree == &st->idle) { -+ /* -+ * Must be on the idle tree, bfq_idle_extract() will -+ * check for that. -+ */ -+ bfq_idle_extract(st, entity); -+ entity->start = bfq_gt(min_vstart, entity->finish) ? -+ min_vstart : entity->finish; -+ } else { -+ /* -+ * The finish time of the entity may be invalid, and -+ * it is in the past for sure, otherwise the queue -+ * would have been on the idle tree. -+ */ -+ entity->start = min_vstart; -+ st->wsum += entity->weight; -+ bfq_get_entity(entity); -+ -+ BUG_ON(entity->on_st && bfqq); -+ -+#ifdef CONFIG_BFQ_GROUP_IOSCHED -+ if (entity->on_st && !bfqq) { -+ struct bfq_group *bfqg = -+ container_of(entity, struct bfq_group, -+ entity); -+ -+ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, -+ bfqg, -+ "activate bug, class %d in_service %p", -+ bfq_class_idx(entity), sd->in_service_entity); -+ } -+#endif -+ BUG_ON(entity->on_st && !bfqq); -+ entity->on_st = true; -+ } -+ -+ bfq_update_fin_time_enqueue(entity, st, backshifted); -+} -+ -+/** -+ * __bfq_requeue_entity - handle requeueing or repositioning of an entity. -+ * @entity: the entity being requeued or repositioned. -+ * -+ * Requeueing is needed if this entity stops being served, which -+ * happens if a leaf descendant entity has expired. On the other hand, -+ * repositioning is needed if the next_inservice_entity for the child -+ * entity has changed. See the comments inside the function for -+ * details. -+ * -+ * Basically, this function: 1) removes entity from its active tree if -+ * present there, 2) updates the timestamps of entity and 3) inserts -+ * entity back into its active tree (in the new, right position for -+ * the new values of the timestamps). -+ */ -+static void __bfq_requeue_entity(struct bfq_entity *entity) -+{ -+ struct bfq_sched_data *sd = entity->sched_data; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ -+ BUG_ON(!sd); -+ BUG_ON(!st); -+ -+ BUG_ON(entity != sd->in_service_entity && -+ entity->tree != &st->active); -+ -+ if (entity == sd->in_service_entity) { -+ /* -+ * We are requeueing the current in-service entity, -+ * which may have to be done for one of the following -+ * reasons: -+ * - entity represents the in-service queue, and the -+ * in-service queue is being requeued after an -+ * expiration; -+ * - entity represents a group, and its budget has -+ * changed because one of its child entities has -+ * just been either activated or requeued for some -+ * reason; the timestamps of the entity need then to -+ * be updated, and the entity needs to be enqueued -+ * or repositioned accordingly. -+ * -+ * In particular, before requeueing, the start time of -+ * the entity must be moved forward to account for the -+ * service that the entity has received while in -+ * service. This is done by the next instructions. The -+ * finish time will then be updated according to this -+ * new value of the start time, and to the budget of -+ * the entity. -+ */ -+ bfq_calc_finish(entity, entity->service); -+ entity->start = entity->finish; -+ BUG_ON(entity->tree && entity->tree != &st->active); -+ /* -+ * In addition, if the entity had more than one child -+ * when set in service, then was not extracted from -+ * the active tree. This implies that the position of -+ * the entity in the active tree may need to be -+ * changed now, because we have just updated the start -+ * time of the entity, and we will update its finish -+ * time in a moment (the requeueing is then, more -+ * precisely, a repositioning in this case). To -+ * implement this repositioning, we: 1) dequeue the -+ * entity here, 2) update the finish time and -+ * requeue the entity according to the new -+ * timestamps below. -+ */ -+ if (entity->tree) -+ bfq_active_extract(st, entity); -+ } else { /* The entity is already active, and not in service */ -+ /* -+ * In this case, this function gets called only if the -+ * next_in_service entity below this entity has -+ * changed, and this change has caused the budget of -+ * this entity to change, which, finally implies that -+ * the finish time of this entity must be -+ * updated. Such an update may cause the scheduling, -+ * i.e., the position in the active tree, of this -+ * entity to change. We handle this change by: 1) -+ * dequeueing the entity here, 2) updating the finish -+ * time and requeueing the entity according to the new -+ * timestamps below. This is the same approach as the -+ * non-extracted-entity sub-case above. -+ */ -+ bfq_active_extract(st, entity); -+ } - -+ bfq_update_fin_time_enqueue(entity, st, false); - } - -+static void __bfq_activate_requeue_entity(struct bfq_entity *entity, -+ struct bfq_sched_data *sd, -+ bool non_blocking_wait_rq) -+{ -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ -+ if (sd->in_service_entity == entity || entity->tree == &st->active) -+ /* -+ * in service or already queued on the active tree, -+ * requeue or reposition -+ */ -+ __bfq_requeue_entity(entity); -+ else -+ /* -+ * Not in service and not queued on its active tree: -+ * the activity is idle and this is a true activation. -+ */ -+ __bfq_activate_entity(entity, non_blocking_wait_rq); -+} -+ -+ - /** -- * bfq_activate_entity - activate an entity and its ancestors if necessary. -+ * bfq_activate_entity - activate or requeue an entity representing a bfq_queue, -+ * and activate, requeue or reposition all ancestors -+ * for which such an update becomes necessary. - * @entity: the entity to activate. - * @non_blocking_wait_rq: true if this entity was waiting for a request -- * -- * Activate @entity and all the entities on the path from it to the root. -+ * @requeue: true if this is a requeue, which implies that bfqq is -+ * being expired; thus ALL its ancestors stop being served and must -+ * therefore be requeued - */ --static void bfq_activate_entity(struct bfq_entity *entity, -- bool non_blocking_wait_rq) -+static void bfq_activate_requeue_entity(struct bfq_entity *entity, -+ bool non_blocking_wait_rq, -+ bool requeue) - { - struct bfq_sched_data *sd; - - for_each_entity(entity) { - BUG_ON(!entity); -- __bfq_activate_entity(entity, non_blocking_wait_rq); -- - sd = entity->sched_data; -+ __bfq_activate_requeue_entity(entity, sd, non_blocking_wait_rq); -+ - BUG_ON(RB_EMPTY_ROOT(&sd->service_tree->active) && - RB_EMPTY_ROOT(&(sd->service_tree+1)->active) && - RB_EMPTY_ROOT(&(sd->service_tree+2)->active)); - -- if (!bfq_update_next_in_service(sd, entity)) { -+ if (!bfq_update_next_in_service(sd, entity) && !requeue) { - BUG_ON(!sd->next_in_service); -- /* -- * No need to propagate the activation to the -- * upper entities, as they will be updated when -- * the in-service entity is rescheduled. -- */ - break; - } - BUG_ON(!sd->next_in_service); -@@ -1127,36 +1202,30 @@ static void bfq_activate_entity(struct bfq_entity *entity, - /** - * __bfq_deactivate_entity - deactivate an entity from its service tree. - * @entity: the entity to deactivate. -- * @requeue: if false, the entity will not be put into the idle tree. -- * -- * Deactivate an entity, independently from its previous state. If the -- * entity was not on a service tree just return, otherwise if it is on -- * any scheduler tree, extract it from that tree, and if necessary -- * and if the caller did not specify @requeue, put it on the idle tree. -+ * @ins_into_idle_tree: if false, the entity will not be put into the -+ * idle tree. - * -- * Return %true if the caller should update the entity hierarchy, i.e., -- * if the entity was in service or if it was the next_in_service for -- * its sched_data; return %false otherwise. -+ * Deactivates an entity, independently from its previous state. Must -+ * be invoked only if entity is on a service tree. Extracts the entity -+ * from that tree, and if necessary and allowed, puts it on the idle -+ * tree. - */ --static bool __bfq_deactivate_entity(struct bfq_entity *entity, bool requeue) -+static bool __bfq_deactivate_entity(struct bfq_entity *entity, -+ bool ins_into_idle_tree) - { - struct bfq_sched_data *sd = entity->sched_data; -- struct bfq_service_tree *st; -- int was_in_service; -- bool ret = false; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ bool was_in_service = entity == sd->in_service_entity; - -- if (sd == NULL || !entity->on_st) /* never activated, or inactive */ -+ if (!entity->on_st) { /* entity never activated, or already inactive */ -+ BUG_ON(entity == entity->sched_data->in_service_entity); - return false; -- -- st = bfq_entity_service_tree(entity); -- was_in_service = entity == sd->in_service_entity; -+ } - - BUG_ON(was_in_service && entity->tree && entity->tree != &st->active); - -- if (was_in_service) { -+ if (was_in_service) - bfq_calc_finish(entity, entity->service); -- sd->in_service_entity = NULL; -- } - - if (entity->tree == &st->active) - bfq_active_extract(st, entity); -@@ -1165,26 +1234,22 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity, bool requeue) - else if (entity->tree) - BUG(); - -- if (sd->next_in_service == entity) -- ret = bfq_update_next_in_service(sd, NULL); -- -- if (!requeue || !bfq_gt(entity->finish, st->vtime)) -+ if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime)) - bfq_forget_entity(st, entity); - else - bfq_idle_insert(st, entity); - -- BUG_ON(sd->in_service_entity == entity); -- BUG_ON(sd->next_in_service == entity); -- -- return ret; -+ return true; - } - - /** -- * bfq_deactivate_entity - deactivate an entity. -+ * bfq_deactivate_entity - deactivate an entity representing a bfq_queue. - * @entity: the entity to deactivate. -- * @requeue: true if the entity can be put on the idle tree -+ * @ins_into_idle_tree: true if the entity can be put on the idle tree - */ --static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) -+static void bfq_deactivate_entity(struct bfq_entity *entity, -+ bool ins_into_idle_tree, -+ bool expiration) - { - struct bfq_sched_data *sd; - struct bfq_entity *parent; -@@ -1192,54 +1257,91 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) - for_each_entity_safe(entity, parent) { - sd = entity->sched_data; - -- if (!__bfq_deactivate_entity(entity, requeue)) -+ BUG_ON(sd == NULL); /* -+ * It would mean that this is the -+ * root group. -+ */ -+ -+ BUG_ON(expiration && entity != sd->in_service_entity); -+ -+ BUG_ON(entity != sd->in_service_entity && -+ entity->tree == -+ &bfq_entity_service_tree(entity)->active && -+ !sd->next_in_service); -+ -+ if (!__bfq_deactivate_entity(entity, ins_into_idle_tree)) { - /* -- * next_in_service has not been changed, so -- * no upwards update is needed -+ * Entity is not any tree any more, so, this -+ * deactivation is a no-op, and there is -+ * nothing to change for upper-level entities -+ * (in case of expiration, this can never -+ * happen). - */ -- break; -+ BUG_ON(expiration); /* -+ * entity cannot be already out of -+ * any tree -+ */ -+ return; -+ } - -- if (sd->next_in_service) -+ if (sd->next_in_service == entity) -+ /* -+ * entity was the next_in_service entity, -+ * then, since entity has just been -+ * deactivated, a new one must be found. -+ */ -+ bfq_update_next_in_service(sd, NULL); -+ -+ if (sd->next_in_service) { - /* - * The parent entity is still backlogged, - * because next_in_service is not NULL. So, no -- * upwards deactivation is needed. Yet, -- * next_in_service has been updated (see -- * comment on the body of the above if). Then -- * the schedule nees to be updated upwards. -+ * further upwards deactivation must be -+ * performed. Yet, next_in_service has -+ * changed. Then the schedule does need to be -+ * updated upwards. - */ -- goto update_schedule; -+ BUG_ON(sd->next_in_service == entity); -+ break; -+ } - - /* - * If we get here, then the parent is no more - * backlogged and we need to propagate the -- * deactivation upwards. Then let the loop go on. -+ * deactivation upwards. Thus let the loop go on. - */ - - /* - * Also let parent be queued into the idle tree on - * deactivation, to preserve service guarantees, and - * assuming that who invoked this function does not -- * need parent entities too to be removed by any tree. -+ * need parent entities too to be removed completely. - */ -- requeue = true; -+ ins_into_idle_tree = true; - } - -- return; -- --update_schedule: -+ /* -+ * If the deactivation loop is fully executed, then there are -+ * no more entities to touch and next loop is not executed at -+ * all. Otherwise, requeue remaining entities if they are -+ * about to stop receiving service, or reposition them if this -+ * is not the case. -+ */ - entity = parent; - for_each_entity(entity) { - struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); -+ - /* -- * Invoke __bfq_activate_entity on entity, even if -- * already active, to update its position in the -+ * Invoke __bfq_requeue_entity on entity, even if -+ * already active, to requeue/reposition it in the - * active tree (because sd->next_in_service has - * changed) - */ -- __bfq_activate_entity(entity, false); -+ __bfq_requeue_entity(entity); - - sd = entity->sched_data; -+ BUG_ON(expiration && sd->in_service_entity != entity); -+ - if (bfqq) - bfq_log_bfqq(bfqq->bfqd, bfqq, - "invoking udpdate_next for this queue"); -@@ -1253,7 +1355,13 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) - "invoking udpdate_next for this entity"); - } - #endif -- if (!bfq_update_next_in_service(sd, entity)) -+ if (!bfq_update_next_in_service(sd, entity) && -+ !expiration) -+ /* -+ * next_in_service unchanged, and no -+ * requeueing needed for expiration: stop -+ * here. -+ */ - break; - } - } -@@ -1700,6 +1808,8 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) - - static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) - { -+ struct bfq_entity *entity = &bfqd->in_service_queue->entity; -+ - if (bfqd->in_service_bic) { - put_io_context(bfqd->in_service_bic->icq.ioc); - bfqd->in_service_bic = NULL; -@@ -1708,36 +1818,59 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) - bfq_clear_bfqq_wait_request(bfqd->in_service_queue); - hrtimer_try_to_cancel(&bfqd->idle_slice_timer); - bfqd->in_service_queue = NULL; -+ -+ /* -+ * When this function is called, all in-service entities have -+ * been properly deactivated or requeued, so we can safely -+ * execute the final step: reset in_service_entity along the -+ * path from entity to the root. -+ */ -+ for_each_entity(entity) -+ entity->sched_data->in_service_entity = NULL; - } - - static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, -- bool requeue) -+ bool ins_into_idle_tree, bool expiration) - { - struct bfq_entity *entity = &bfqq->entity; - -- BUG_ON(bfqq == bfqd->in_service_queue); -- bfq_deactivate_entity(entity, requeue); -+ bfq_deactivate_entity(entity, ins_into_idle_tree, expiration); - } - - static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) - { - struct bfq_entity *entity = &bfqq->entity; -+ struct bfq_service_tree *st = bfq_entity_service_tree(entity); -+ -+ BUG_ON(bfqq == bfqd->in_service_queue); -+ BUG_ON(entity->tree != &st->active && entity->tree != &st->idle && -+ entity->on_st); - -- bfq_activate_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq)); -+ bfq_activate_requeue_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq), -+ false); - bfq_clear_bfqq_non_blocking_wait_rq(bfqq); - } - -+static void bfq_requeue_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+{ -+ struct bfq_entity *entity = &bfqq->entity; -+ -+ bfq_activate_requeue_entity(entity, false, -+ bfqq == bfqd->in_service_queue); -+} -+ - static void bfqg_stats_update_dequeue(struct bfq_group *bfqg); - - /* - * Called when the bfqq no longer has requests pending, remove it from -- * the service tree. -+ * the service tree. As a special case, it can be invoked during an -+ * expiration. - */ --static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) -+static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, -+ bool expiration) - { - BUG_ON(!bfq_bfqq_busy(bfqq)); - BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); -- BUG_ON(bfqq == bfqd->in_service_queue); - - bfq_log_bfqq(bfqd, bfqq, "del from busy"); - -@@ -1757,7 +1890,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) - - BUG_ON(bfqq->entity.budget < 0); - -- bfq_deactivate_bfqq(bfqd, bfqq, true); -+ bfq_deactivate_bfqq(bfqd, bfqq, true, expiration); - - BUG_ON(bfqq->entity.budget < 0); - } -diff --git a/block/bfq.h b/block/bfq.h -index 1a03521..f90d534 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -140,10 +140,10 @@ struct bfq_entity { - struct bfq_weight_counter *weight_counter; - - /* -- * flag, true if the entity is on a tree (either the active or -- * the idle one of its service_tree). -+ * Flag, true if the entity is on a tree (either the active or -+ * the idle one of its service_tree) or is in service. - */ -- int on_st; -+ bool on_st; - - u64 finish; /* B-WF2Q+ finish timestamp (aka F_i) */ - u64 start; /* B-WF2Q+ start timestamp (aka S_i) */ - -From 6ef4dcd808aa50f7ba49bc0fde68b72a8a68028c Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Fri, 16 Dec 2016 18:01:52 +0100 -Subject: [PATCH 24/28] Add code to redirect trace log to console - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq.h | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/block/bfq.h b/block/bfq.h -index f90d534..d98403e 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -648,6 +648,43 @@ BFQ_BFQQ_FNS(softrt_update); - #undef BFQ_BFQQ_FNS - - /* Logging facilities. */ -+#ifdef CONFIG_BFQ_REDIRECT_TO_CONSOLE -+#ifdef CONFIG_BFQ_GROUP_IOSCHED -+static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); -+static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); -+ -+#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) do { \ -+ char __pbuf[128]; \ -+ \ -+ assert_spin_locked((bfqd)->queue->queue_lock); \ -+ blkg_path(bfqg_to_blkg(bfqq_group(bfqq)), __pbuf, sizeof(__pbuf)); \ -+ pr_crit("bfq%d%c %s " fmt "\n", \ -+ (bfqq)->pid, \ -+ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ -+ __pbuf, ##args); \ -+} while (0) -+ -+#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do { \ -+ char __pbuf[128]; \ -+ \ -+ blkg_path(bfqg_to_blkg(bfqg), __pbuf, sizeof(__pbuf)); \ -+ pr_crit("%s " fmt "\n", __pbuf, ##args); \ -+} while (0) -+ -+#else /* CONFIG_BFQ_GROUP_IOSCHED */ -+ -+#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ -+ pr_crit("bfq%d%c " fmt "\n", (bfqq)->pid, \ -+ bfq_bfqq_sync((bfqq)) ? 'S' : 'A', \ -+ ##args) -+#define bfq_log_bfqg(bfqd, bfqg, fmt, args...) do {} while (0) -+ -+#endif /* CONFIG_BFQ_GROUP_IOSCHED */ -+ -+#define bfq_log(bfqd, fmt, args...) \ -+ pr_crit("bfq " fmt "\n", ##args) -+ -+#else /* CONFIG_BFQ_REDIRECT_TO_CONSOLE */ - #ifdef CONFIG_BFQ_GROUP_IOSCHED - static struct bfq_group *bfqq_group(struct bfq_queue *bfqq); - static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); -@@ -682,6 +719,7 @@ static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); - - #define bfq_log(bfqd, fmt, args...) \ - blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) -+#endif /* CONFIG_BFQ_REDIRECT_TO_CONSOLE */ - - /* Expiration reasons. */ - enum bfqq_expiration { - -From f7e139123c8becd5ac6de6b62d395f5d8e94e498 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Sun, 18 Dec 2016 22:45:07 +0100 -Subject: [PATCH 25/28] BFQ v8r6-rc2 - ---- - block/bfq-iosched.c | 2 +- - block/bfq.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 23e4c94..7036f0b 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -5229,7 +5229,7 @@ static struct blkcg_policy blkcg_policy_bfq = { - static int __init bfq_init(void) - { - int ret; -- char msg[60] = "BFQ I/O-scheduler: v8r6-rc1"; -+ char msg[60] = "BFQ I/O-scheduler: v8r6-rc2"; - - #ifdef CONFIG_BFQ_GROUP_IOSCHED - ret = blkcg_policy_register(&blkcg_policy_bfq); -diff --git a/block/bfq.h b/block/bfq.h -index d98403e..4dd4931 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -1,5 +1,5 @@ - /* -- * BFQ v8r6-rc1 for 4.9.0: data structures and common functions prototypes. -+ * BFQ v8r6-rc2 for 4.9.0: data structures and common functions prototypes. - * - * Based on ideas and code from CFQ: - * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> - -From 2d790c793eab404abd5aadce0981b97c498c996b Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Mon, 19 Dec 2016 08:12:26 +0100 -Subject: [PATCH 26/28] Fix bug in optimized update of next_in_service entity - -There was a case where bfq_update_next_in_service did not update -next_in_service, even if it might need to be changed: in case of -requeueing or repositioning of the entity that happened to be -pointed exactly by next_in_service. This could result in violation -of service guarantees, because, after a change of timestamps for -such an entity, it might be the case that next_in_service had to -point to a different entity. This commit fixes this bug. - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-sched.c | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 3b8e05b..41fd5c9 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -68,8 +68,9 @@ static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree) - /** - * bfq_update_next_in_service - update sd->next_in_service - * @sd: sched_data for which to perform the update. -- * @new_entity: if not NULL, pointer to the entity whose activation -- * triggered the invocation of this function. -+ * @new_entity: if not NULL, pointer to the entity whose activation, -+ * requeueing or repositionig triggered the invocation of -+ * this function. - * - * This function is called to update sd->next_in_service, which, in - * its turn, may change as a consequence of the insertion or -@@ -95,17 +96,18 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd, - struct bfq_queue *bfqq; - - /* -- * If this update is triggered by the activation of a new -- * entity, then a full lookup in the active tree can be -- * avoided. In fact, it is enough to check whether the -- * just-activated entity has a higher priority of -+ * If this update is triggered by the activation, requeueing -+ * or repositiong of an entity that does not coincide with -+ * sd->next_in_service, then a full lookup in the active tree -+ * can be avoided. In fact, it is enough to check whether the -+ * just-modified entity has a higher priority than - * sd->next_in_service, or, even if it has the same priority - * as sd->next_in_service, is eligible and has a lower virtual - * finish time than sd->next_in_service. If this compound - * condition holds, then the new entity becomes the new - * next_in_service. Otherwise no change is needed. - */ -- if (new_entity) { -+ if (new_entity && new_entity != sd->next_in_service) { - /* - * Flag used to decide whether to replace - * sd->next_in_service with new_entity. Tentatively -@@ -114,9 +116,6 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd, - */ - bool replace_next = true; - -- if (new_entity == sd->next_in_service) -- return false; -- - /* - * If there is already a next_in_service candidate - * entity, then compare class priorities or timestamps - -From 86fed232c6e9c6c54bb4e0035c5641977d734cc6 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Mon, 19 Dec 2016 09:11:50 +0100 -Subject: [PATCH 27/28] Stop bubble-up of next_in_service update if possible - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-sched.c | 38 +++++++++++++++++++++++++------------- - 1 file changed, 25 insertions(+), 13 deletions(-) - -diff --git a/block/bfq-sched.c b/block/bfq-sched.c -index 41fd5c9..4af77f4 100644 ---- a/block/bfq-sched.c -+++ b/block/bfq-sched.c -@@ -37,11 +37,16 @@ static int bfq_gt(u64 a, u64 b) - - static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd); - --static void bfq_update_budget(struct bfq_entity *next_in_service) -+/* -+ * Returns true if this budget changes may let next_in_service->parent -+ * become the next_in_service entity for its parent entity. -+ */ -+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service) - { - struct bfq_entity *bfqg_entity; - struct bfq_group *bfqg; - struct bfq_sched_data *group_sd; -+ bool ret = false; - - BUG_ON(!next_in_service); - -@@ -54,8 +59,13 @@ static void bfq_update_budget(struct bfq_entity *next_in_service) - * as it must never become an in-service entity. - */ - bfqg_entity = bfqg->my_entity; -- if (bfqg_entity) -+ if (bfqg_entity) { -+ if (bfqg_entity->budget > next_in_service->budget) -+ ret = true; - bfqg_entity->budget = next_in_service->budget; -+ } -+ -+ return ret; - } - - static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree) -@@ -84,16 +94,16 @@ static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree) - * both the last two activation sub-cases, new_entity points to the - * just activated or requeued entity. - * -- * This is a still incomplete version of this function, which always -- * returns true. It will return also false in its complete version, in -- * case either next_in_service has not changed, or next_in_service has -- * changed but in a way that will not influence upper levels. -+ * Returns true if sd->next_in_service changes in such a way that -+ * entity->parent may become the next_in_service for its parent -+ * entity. - */ - static bool bfq_update_next_in_service(struct bfq_sched_data *sd, - struct bfq_entity *new_entity) - { - struct bfq_entity *next_in_service = sd->next_in_service; - struct bfq_queue *bfqq; -+ bool parent_sched_may_change = false; - - /* - * If this update is triggered by the activation, requeueing -@@ -150,12 +160,15 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd, - } else /* invoked because of a deactivation: lookup needed */ - next_in_service = bfq_lookup_next_entity(sd); - -+ if (next_in_service) { -+ parent_sched_may_change = !sd->next_in_service || -+ bfq_update_parent_budget(next_in_service); -+ } -+ - sd->next_in_service = next_in_service; - -- if (next_in_service) -- bfq_update_budget(next_in_service); -- else -- goto exit; -+ if (!next_in_service) -+ return parent_sched_may_change; - - bfqq = bfq_entity_to_bfqq(next_in_service); - if (bfqq) -@@ -171,8 +184,7 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd, - "update_next_in_service: chosen this entity"); - } - #endif --exit: -- return true; -+ return parent_sched_may_change; - } - - #else -@@ -187,7 +199,7 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd) - return 0; - } - --static void bfq_update_budget(struct bfq_entity *next_in_service) -+static void bfq_update_parent_budget(struct bfq_entity *next_in_service) - { - } - #endif - -From eb70b7cbd454b508d3d81cac89f4c4655f8ff7a1 Mon Sep 17 00:00:00 2001 -From: Paolo Valente <paolo.valente@linaro.org> -Date: Mon, 19 Dec 2016 11:15:38 +0100 -Subject: [PATCH 28/28] BFQ v8r6-rc3 - -Signed-off-by: Paolo Valente <paolo.valente@linaro.org> ---- - block/bfq-iosched.c | 2 +- - block/bfq.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c -index 7036f0b..be8aa7f 100644 ---- a/block/bfq-iosched.c -+++ b/block/bfq-iosched.c -@@ -5229,7 +5229,7 @@ static struct blkcg_policy blkcg_policy_bfq = { - static int __init bfq_init(void) - { - int ret; -- char msg[60] = "BFQ I/O-scheduler: v8r6-rc2"; -+ char msg[60] = "BFQ I/O-scheduler: v8r6-rc3"; - - #ifdef CONFIG_BFQ_GROUP_IOSCHED - ret = blkcg_policy_register(&blkcg_policy_bfq); -diff --git a/block/bfq.h b/block/bfq.h -index 4dd4931..b285bc4 100644 ---- a/block/bfq.h -+++ b/block/bfq.h -@@ -1,5 +1,5 @@ - /* -- * BFQ v8r6-rc2 for 4.9.0: data structures and common functions prototypes. -+ * BFQ v8r6-rc3 for 4.9.0: data structures and common functions prototypes. - * - * Based on ideas and code from CFQ: - * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> 0 @@ -54,7 +54,7 @@ _srcname=linux-4.8 _pkgver=4.8.14 _rtpatchver=rt9 pkgver=${_pkgver}_${_rtpatchver} -pkgrel=3 +pkgrel=4 arch=('i686' 'x86_64') url="http://algo.ing.unimo.it" license=('GPL2') @@ -88,7 +88,7 @@ source=("http://www.kernel.org/pub/linux/kernel/v4.x/${_srcname}.tar.xz" 'net_handle_no_dst_on_skb_in_icmp6_send.patch' '0001-x86-fpu-Fix-invalid-FPU-ptrace-state-after-execve.patch' # patches from https://github.com/linusw/linux-bfq/commits/bfq-v8 - '0005-BFQ-update-to-v8r6.patch') + '0005-BFQ-update-to-v8r5.patch') _kernelname=${pkgbase#linux} @@ -486,7 +486,7 @@ sha512sums=('a48a065f21e1c7c4de4cf8ca47b8b8d9a70f86b64e7cfa6e01be490f78895745b9c '2dc6b0ba8f7dbf19d2446c5c5f1823587de89f4e28e9595937dd51a87755099656f2acec50e3e2546ea633ad1bfd1c722e0c2b91eef1d609103d8abdc0a7cbaf' 'c53bd47527adbd2599a583e05a7d24f930dc4e86b1de017486588205ad6f262a51a4551593bc7a1218c96541ea073ea03b770278d947b1cd0d2801311fcc80e5' '002d5e0ccfa5824c1750912a6400ff722672d6587b74ba66b1127cf1228048f604bba107617cf4f4477884039af4d4d196cf1b74cefe43b0bddc82270f11940d' - '6c9992e1ae39e81577af9399d583c8c04c2d8ff205eb58ed082016e310ed2b2f040689ae8f2a36bf131d3c58d40eaf94ba2bd4b9fc0006eeedb9569f8c0deef5') + '67d11b25179e2d46effa70a6a151626a0b6dff900d887497b173fe894b839104d370cfbabf531c3f3914a15c3ec3cac6297dbaa5f294e6fcb644e2b26d8579b7') validpgpkeys=( 'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds |