[RFC 7/7] mm: introduce mst low and min watermark

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Yulei Zhang <yuleixzhang@xxxxxxxxxxx>

Memory allocation speed throttle aims to avoid direct reclaim caused
by memory usage burst, which mostly happens under memory pressure.
As unconditional throttling could introduce unnecessary overhead, we add
two watermarks to control the throttling.

When mst low wmark reached, we start to throttle memory speed if it is
overspeed. And if mst min wmark reached, we do throttling directly everytime
charging without checking the memory allocation speed.

Signed-off-by: Jiang Biao <benbjiang@xxxxxxxxx>
Signed-off-by: Yulei Zhang <yuleixzhang@xxxxxxxxxxx>
---
 include/linux/memcontrol.h |  6 ++++++
 mm/memcontrol.c            | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 59e6cb78a07a..011d1426a924 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -241,6 +241,12 @@ struct mem_spd_ctl {
 	atomic_t updating;
 	atomic_long_t nr_throttled;
 };
+
+enum mst_wmark_stat {
+	WMARK_OK = 0,
+	WMARK_REACH_LOW,
+	WMARK_REACH_MIN,
+};
 #endif
 
 /*
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index ca39974403a3..b1111dc8e585 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1546,18 +1546,47 @@ static int mem_cgroup_mst_overspd_tree(struct mem_cgroup *memcg)
 	return ret;
 }
 
+static enum mst_wmark_stat mem_cgroup_mst_wmark_ok(struct mem_cgroup *memcg)
+{
+	int nid;
+
+	for_each_online_node(nid) {
+		unsigned long free, low, min;
+		struct zone *zone;
+
+		zone = &NODE_DATA(nid)->node_zones[ZONE_NORMAL];
+		free = zone_page_state(zone, NR_FREE_PAGES);
+		low = low_wmark_pages(zone);
+		min = min_wmark_pages(zone);
+		min += (low - min) >> 2;
+
+		if (free <= min)
+			return WMARK_REACH_MIN;
+
+		if (free <= low)
+			return WMARK_REACH_LOW;
+
+	}
+	return WMARK_OK;
+}
+
 static void mem_cgroup_mst_spd_throttle(struct mem_cgroup *memcg)
 {
 	struct mem_spd_ctl *msc = &memcg->msc;
 	long timeout;
 	int ret = 0;
+	enum mst_wmark_stat stat;
 
 	if (!memcg->msc.has_lmt || in_interrupt() || in_atomic() ||
 		irqs_disabled() || oops_in_progress)
 		return;
 
+	stat = mem_cgroup_mst_wmark_ok(memcg);
+	if (stat == WMARK_OK)
+		return;
+
 	ret = mem_cgroup_mst_overspd_tree(memcg);
-	if (!ret)
+	if (stat == WMARK_REACH_LOW && !ret)
 		return;
 
 	atomic_long_inc(&msc->nr_throttled);
-- 
2.28.0




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux