From: Yulei Zhang <yuleixzhang@xxxxxxxxxxx> We separate the statistical period into 10 slices, count the memory charge in each slice, and compare to the slice speed limit to determine to turn on the throttle or not. Signed-off-by: Jiang Biao <benbjiang@xxxxxxxxxxx> Signed-off-by: Yulei Zhang <yuleixzhang@xxxxxxxxxxx> --- include/linux/memcontrol.h | 4 ++++ mm/memcontrol.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 435515b1a709..230acdc635b5 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -231,8 +231,12 @@ struct obj_cgroup { }; #ifdef CONFIG_MEM_SPEED_THROTTLE +#define MST_SLICE (HZ/10) struct mem_spd_ctl { unsigned long mem_spd_lmt; + unsigned long slice_lmt; + unsigned long prev_thl_jifs; + unsigned long prev_chg; int has_lmt; }; #endif diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9d7a86f7f51c..05bf4ba0da15 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1403,6 +1403,9 @@ static void mem_cgroup_mst_msc_reset(struct mem_cgroup *memcg) msc = &memcg->msc; msc->has_lmt = 0; msc->mem_spd_lmt = 0; + msc->slice_lmt = 0; + msc->prev_chg = 0; + msc->prev_thl_jifs = 0; } static void mem_cgroup_mst_has_lmt_init(struct mem_cgroup *memcg) @@ -1440,6 +1443,7 @@ static int mem_cgroup_mem_spd_lmt_write(struct cgroup_subsys_state *css, lmt = val >> PAGE_SHIFT; memcg->msc.mem_spd_lmt = lmt; + memcg->msc.slice_lmt = lmt * MST_SLICE / HZ; /* Sync with mst_has_lmt_init*/ synchronize_rcu(); @@ -1452,6 +1456,27 @@ static int mem_cgroup_mem_spd_lmt_write(struct cgroup_subsys_state *css, return 0; } +/* + * Update the memory speed throttle slice window. + * Return 0 when we still in the previous slice window + * Return 1 when we start a new slice window + */ +static int mem_cgroup_update_mst_slice(struct mem_cgroup *memcg) +{ + unsigned long total_charge; + struct mem_spd_ctl *msc = &memcg->msc; + + if (msc->prev_thl_jifs && + time_before(jiffies, (msc->prev_thl_jifs + MST_SLICE))) + return 0; + + total_charge = atomic_long_read(&memcg->memory.total_chg); + msc->prev_chg = total_charge; + msc->prev_thl_jifs = jiffies; + + return 1; +} + static unsigned long mem_cgroup_mst_get_mem_spd_max(struct mem_cgroup *memcg) { struct page_counter *c = &memcg->memory; -- 2.28.0