OpenVZ Forum


Home » Mailing lists » Devel » [RFC][ only for review ] memory controller bacground reclaim [0/5]
[RFC][ only for review ] memory controller bacground reclaim [3/5] high/low watermark support in res [message #23864 is a reply to message #23861] Wed, 28 November 2007 08:54 Go to previous messageGo to previous message
KAMEZAWA Hiroyuki is currently offline  KAMEZAWA Hiroyuki
Messages: 463
Registered: September 2006
Senior Member
This patch adds high/low watermark parameter to res_counter.
splitted out from YAMAMOTO's background page reclaim for memory cgroup set.

Changes:
 * added param watermark_state this allows status check without lock.


Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
From: YAMAMOTO Takashi <yamamoto@valinux.co.jp>

 include/linux/res_counter.h |   27 +++++++++++++++++++++++++
 kernel/res_counter.c        |   46 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 1 deletion(-)

Index: linux-2.6.24-rc3-mm1/include/linux/res_counter.h
===================================================================
--- linux-2.6.24-rc3-mm1.orig/include/linux/res_counter.h	2007-11-28 14:33:19.000000000 +0900
+++ linux-2.6.24-rc3-mm1/include/linux/res_counter.h	2007-11-28 16:37:32.000000000 +0900
@@ -19,6 +19,12 @@
  * the helpers described beyond
  */
 
+enum watermark_state {
+	RES_WATERMARK_BELOW_LOW,
+	RES_WATERMARK_ABOVE_LOW,
+	RES_WATERMARK_ABOVE_HIGH,
+};
+
 struct res_counter {
 	/*
 	 * the current resource consumption level
@@ -33,10 +39,19 @@
 	 */
 	unsigned long long failcnt;
 	/*
+	 * Watermarks
+	 * Should be changed automatically when the limit is changed and
+	 * keep low < high < limit.
+	 */
+	unsigned long long high_watermark;
+	unsigned long long low_watermark;
+	/*
 	 * the lock to protect all of the above.
 	 * the routines below consider this to be IRQ-safe
 	 */
 	spinlock_t lock;
+	/* can be read without lock */
+	enum watermark_state watermark_state;
 };
 
 /*
@@ -73,6 +88,8 @@
 	RES_USAGE,
 	RES_LIMIT,
 	RES_FAILCNT,
+	RES_HIGH_WATERMARK,
+	RES_LOW_WATERMARK,
 };
 
 /*
@@ -131,4 +148,17 @@
 	return ret;
 }
 
+/*
+ * Helper function for implementing high/low watermark to resource controller.
+ */
+static inline bool res_counter_below_low_watermark(struct res_counter *cnt)
+{
+	return (cnt->watermark_state == RES_WATERMARK_BELOW_LOW);
+}
+
+static inline bool res_counter_above_high_watermark(struct res_counter *cnt)
+{
+	return (cnt->watermark_state == RES_WATERMARK_ABOVE_HIGH);
+}
+
 #endif
Index: linux-2.6.24-rc3-mm1/kernel/res_counter.c
===================================================================
--- linux-2.6.24-rc3-mm1.orig/kernel/res_counter.c	2007-11-28 14:33:19.000000000 +0900
+++ linux-2.6.24-rc3-mm1/kernel/res_counter.c	2007-11-28 16:33:20.000000000 +0900
@@ -17,6 +17,9 @@
 {
 	spin_lock_init(&counter->lock);
 	counter->limit = (unsigned long long)LLONG_MAX;
+	counter->low_watermark = (unsigned long long)LLONG_MAX;
+	counter->high_watermark = (unsigned long long)LLONG_MAX;
+	counter->watermark_state = RES_WATERMARK_BELOW_LOW;
 }
 
 int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
@@ -27,6 +30,15 @@
 	}
 
 	counter->usage += val;
+
+	if (counter->usage > counter->high_watermark) {
+		counter->watermark_state = RES_WATERMARK_ABOVE_HIGH;
+		return 0;
+	}
+
+	if (counter->usage > counter->low_watermark)
+		counter->watermark_state = RES_WATERMARK_ABOVE_LOW;
+
 	return 0;
 }
 
@@ -47,6 +59,13 @@
 		val = counter->usage;
 
 	counter->usage -= val;
+
+	if (counter->usage < counter->low_watermark) {
+		counter->watermark_state = RES_WATERMARK_BELOW_LOW;
+		return;
+	}
+	if (counter->usage < counter->high_watermark)
+		counter->watermark_state = RES_WATERMARK_ABOVE_LOW;
 }
 
 void res_counter_uncharge(struct res_counter *counter, unsigned long val)
@@ -69,6 +88,10 @@
 		return &counter->limit;
 	case RES_FAILCNT:
 		return &counter->failcnt;
+	case RES_HIGH_WATERMARK:
+		return &counter->high_watermark;
+	case RES_LOW_WATERMARK:
+		return &counter->low_watermark;
 	};
 
 	BUG();
@@ -117,7 +140,7 @@
 {
 	int ret;
 	char *buf, *end;
-	unsigned long long flags, tmp, *val;
+	unsigned long long flags, tmp, *val, limit, low, high;
 
 	buf = kmalloc(nbytes + 1, GFP_KERNEL);
 	ret = -ENOMEM;
@@ -141,6 +164,26 @@
 			goto out_free;
 	}
 	spin_lock_irqsave(&counter->lock, flags);
+	/*
+	 * High/Low watermark should be changed automatically AMAP.
+	 */
+	switch (member) {
+		case RES_HIGH_WATERMARK:
+			limit = res_counter_get(counter, RES_LIMIT);
+			if (tmp > limit)
+				goto out_free;
+			low = res_counter_get(counter, RES_LOW_WATERMARK);
+			if (tmp <= low)
+				goto out_free;
+			break;
+		case RES_LOW_WATERMARK:
+			high= res_counter_get(counter, RES_HIGH_WATERMARK);
+			if (tmp >= high)
+				goto out_free;
+			break;
+		default:
+			break;
+	}
 	val = res_counter_member(counter, member);
 	*val = tmp;
 	spin_unlock_irqrestore(&counter->lock, flags);
@@ -150,3 +193,4 @@
 out:
 	return ret;
 }
+

_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: [PATCH net-2.6.25 2/3][IPV6] Unify and cleanup calls to addrconf_sysctl_register
Next Topic: [PATCH 0/4 net-2.6.15][UNIX] Make unix sysctls per-namespace
Goto Forum:
  


Current Time: Sun Aug 10 08:56:15 GMT 2025

Total time taken to generate the page: 0.21623 seconds