blkcg_bio_issue_check() checks throtl for stat update, which isn't good
because the bio could be splitted into small bios, the samll bios go
into blkcg_bio_issue_check again and we update stat for the small bios,
so we the stat is double charged. To fix this, we only update stat if
the bio doesn't have BIO_THROTTLED flag. The fix will update stat ahead
of bio skips from blk-throttle, but eventually the stat is correct.

This patch is on top of patch:
https://marc.info/?l=linux-block&m=151060860608914&w=2

Cc: Tejun Heo <[email protected]>
Signed-off-by: Shaohua Li <[email protected]>
---
 include/linux/blk-cgroup.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 58f3d25..6fbd9ea 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -690,7 +690,8 @@ static inline bool blkcg_bio_issue_check(struct 
request_queue *q,
 {
        struct blkcg *blkcg;
        struct blkcg_gq *blkg;
-       bool throtl = false;
+       bool throtl;
+       bool charged;
 
        rcu_read_lock();
        blkcg = bio_blkcg(bio);
@@ -707,9 +708,10 @@ static inline bool blkcg_bio_issue_check(struct 
request_queue *q,
                spin_unlock_irq(q->queue_lock);
        }
 
+       charged = bio_flagged(bio, BIO_THROTTLED);
        throtl = blk_throtl_bio(q, blkg, bio);
 
-       if (!throtl) {
+       if (!charged) {
                blkg = blkg ?: q->root_blkg;
                blkg_rwstat_add(&blkg->stat_bytes, bio->bi_opf,
                                bio->bi_iter.bi_size);
-- 
2.9.5

Reply via email to