When using cfs_b and meeting with some throttled periods, users shall
use burst buffer to allow bursty workloads. Apart from configuring some
burst buffer and watch whether throttled periods disappears, some
statistics on burst buffer using are also helpful. Thus expose the
following statistics into cpu.stat file:

nr_burst:   number of periods bandwidth burst occurs
burst_time: cumulative wall-time that any cpus has
            used above quota in respective periods

Co-developed-by: Shanpei Chen <[email protected]>
Signed-off-by: Shanpei Chen <[email protected]>
Signed-off-by: Huaixin Chang <[email protected]>
---
 kernel/sched/core.c  | 14 +++++++++++---
 kernel/sched/fair.c  | 13 ++++++++++++-
 kernel/sched/sched.h |  3 +++
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 16e23a2499ef..f60232862300 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -9016,6 +9016,7 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, 
u64 period, u64 quota,
                cfs_b->buffer = min(max_cfs_runtime, quota + burst);
                cfs_b->max_overrun = DIV_ROUND_UP_ULL(max_cfs_runtime, quota);
                cfs_b->runtime = cfs_b->quota;
+               cfs_b->runtime_at_period_start = cfs_b->runtime;
 
                /* Restart the period timer (if active) to handle new period 
expiry: */
                start_cfs_bandwidth(cfs_b, 1);
@@ -9265,6 +9266,9 @@ static int cpu_cfs_stat_show(struct seq_file *sf, void *v)
                seq_printf(sf, "wait_sum %llu\n", ws);
        }
 
+       seq_printf(sf, "nr_burst %d\n", cfs_b->nr_burst);
+       seq_printf(sf, "burst_time %llu\n", cfs_b->burst_time);
+
        return 0;
 }
 #endif /* CONFIG_CFS_BANDWIDTH */
@@ -9361,16 +9365,20 @@ static int cpu_extra_stat_show(struct seq_file *sf,
        {
                struct task_group *tg = css_tg(css);
                struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
-               u64 throttled_usec;
+               u64 throttled_usec, burst_usec;
 
                throttled_usec = cfs_b->throttled_time;
                do_div(throttled_usec, NSEC_PER_USEC);
+               burst_usec = cfs_b->burst_time;
+               do_div(burst_usec, NSEC_PER_USEC);
 
                seq_printf(sf, "nr_periods %d\n"
                           "nr_throttled %d\n"
-                          "throttled_usec %llu\n",
+                          "throttled_usec %llu\n"
+                          "nr_burst %d\n"
+                          "burst_usec %llu\n",
                           cfs_b->nr_periods, cfs_b->nr_throttled,
-                          throttled_usec);
+                          throttled_usec, cfs_b->nr_burst, burst_usec);
        }
 #endif
        return 0;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c981d4845c96..e7574d8bc11a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4612,7 +4612,7 @@ static inline u64 sched_cfs_bandwidth_slice(void)
 static void __refill_cfs_bandwidth_runtime(struct cfs_bandwidth *cfs_b,
                                           u64 overrun)
 {
-       u64 refill;
+       u64 refill, runtime;
 
        if (cfs_b->quota != RUNTIME_INF) {
 
@@ -4621,10 +4621,21 @@ static void __refill_cfs_bandwidth_runtime(struct 
cfs_bandwidth *cfs_b,
                        return;
                }
 
+               if (cfs_b->runtime_at_period_start > cfs_b->runtime) {
+                       runtime = cfs_b->runtime_at_period_start
+                               - cfs_b->runtime;
+                       if (runtime > cfs_b->quota) {
+                               cfs_b->burst_time += runtime - cfs_b->quota;
+                               cfs_b->nr_burst++;
+                       }
+               }
+
                overrun = min(overrun, cfs_b->max_overrun);
                refill = cfs_b->quota * overrun;
                cfs_b->runtime += refill;
                cfs_b->runtime = min(cfs_b->runtime, cfs_b->buffer);
+
+               cfs_b->runtime_at_period_start = cfs_b->runtime;
        }
 }
 
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index efcbbfc31619..7ef8d4733791 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -360,6 +360,7 @@ struct cfs_bandwidth {
        u64                     burst;
        u64                     buffer;
        u64                     max_overrun;
+       u64                     runtime_at_period_start;
        s64                     hierarchical_quota;
 
        u8                      idle;
@@ -372,7 +373,9 @@ struct cfs_bandwidth {
        /* Statistics: */
        int                     nr_periods;
        int                     nr_throttled;
+       int                     nr_burst;
        u64                     throttled_time;
+       u64                     burst_time;
 #endif
 };
 
-- 
2.14.4.44.g2045bb6

Reply via email to