Thread (24 messages) 24 messages, 5 authors, 2008-02-15

[RFC] [PATCH 1/4] Modify resource counters to add soft limit support

From: Balbir Singh <hidden>
Date: 2008-02-13 15:15:20

The resource counter member limit is split into soft and hard limits.
The same locking rule apply for both limits.

Signed-off-by: Balbir Singh <redacted>
---

 include/linux/res_counter.h |   34 ++++++++++++++++++++++++++--------
 kernel/res_counter.c        |   11 +++++++----
 mm/memcontrol.c             |   10 +++++-----
 3 files changed, 38 insertions(+), 17 deletions(-)

diff -puN mm/vmscan.c~memory-controller-res_counters-soft-limit-setup mm/vmscan.c
diff -puN mm/memcontrol.c~memory-controller-res_counters-soft-limit-setup mm/memcontrol.c
--- linux-2.6.24/mm/memcontrol.c~memory-controller-res_counters-soft-limit-setup	2008-02-13 19:50:24.000000000 +0530
+++ linux-2.6.24-balbir/mm/memcontrol.c	2008-02-13 19:50:24.000000000 +0530
@@ -568,7 +568,7 @@ unsigned long mem_cgroup_isolate_pages(u
  * Charge the memory controller for page usage.
  * Return
  * 0 if the charge was successful
- * < 0 if the cgroup is over its limit
+ * < 0 if the cgroup is over its hard limit
  */
 static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
 				gfp_t gfp_mask, enum charge_type ctype)
@@ -632,7 +632,7 @@ retry:
 
 	/*
 	 * If we created the page_cgroup, we should free it on exceeding
-	 * the cgroup limit.
+	 * the cgroup hard limit.
 	 */
 	while (res_counter_charge(&mem->res, PAGE_SIZE)) {
 		if (!(gfp_mask & __GFP_WAIT))
@@ -645,10 +645,10 @@ retry:
  		 * try_to_free_mem_cgroup_pages() might not give us a full
  		 * picture of reclaim. Some pages are reclaimed and might be
  		 * moved to swap cache or just unmapped from the cgroup.
- 		 * Check the limit again to see if the reclaim reduced the
+ 		 * Check the hard limit again to see if the reclaim reduced the
  		 * current usage of the cgroup before giving up
  		 */
-		if (res_counter_check_under_limit(&mem->res))
+		if (res_counter_check_under_limit(&mem->res, RES_HARD_LIMIT))
 			continue;
 
 		if (!nr_retries--) {
@@ -1028,7 +1028,7 @@ static struct cftype mem_cgroup_files[] 
 	},
 	{
 		.name = "limit_in_bytes",
-		.private = RES_LIMIT,
+		.private = RES_HARD_LIMIT,
 		.write = mem_cgroup_write,
 		.read = mem_cgroup_read,
 	},
diff -puN kernel/res_counter.c~memory-controller-res_counters-soft-limit-setup kernel/res_counter.c
--- linux-2.6.24/kernel/res_counter.c~memory-controller-res_counters-soft-limit-setup	2008-02-13 19:50:24.000000000 +0530
+++ linux-2.6.24-balbir/kernel/res_counter.c	2008-02-13 19:50:24.000000000 +0530
@@ -16,12 +16,13 @@
 void res_counter_init(struct res_counter *counter)
 {
 	spin_lock_init(&counter->lock);
-	counter->limit = (unsigned long long)LLONG_MAX;
+	counter->soft_limit = (unsigned long long)LLONG_MAX;
+	counter->hard_limit = (unsigned long long)LLONG_MAX;
 }
 
 int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
 {
-	if (counter->usage + val > counter->limit) {
+	if (counter->usage + val > counter->hard_limit) {
 		counter->failcnt++;
 		return -ENOMEM;
 	}
@@ -65,8 +66,10 @@ res_counter_member(struct res_counter *c
 	switch (member) {
 	case RES_USAGE:
 		return &counter->usage;
-	case RES_LIMIT:
-		return &counter->limit;
+	case RES_SOFT_LIMIT:
+		return &counter->soft_limit;
+	case RES_HARD_LIMIT:
+		return &counter->hard_limit;
 	case RES_FAILCNT:
 		return &counter->failcnt;
 	};
diff -puN include/linux/res_counter.h~memory-controller-res_counters-soft-limit-setup include/linux/res_counter.h
--- linux-2.6.24/include/linux/res_counter.h~memory-controller-res_counters-soft-limit-setup	2008-02-13 19:50:24.000000000 +0530
+++ linux-2.6.24-balbir/include/linux/res_counter.h	2008-02-13 19:50:24.000000000 +0530
@@ -27,7 +27,13 @@ struct res_counter {
 	/*
 	 * the limit that usage cannot exceed
 	 */
-	unsigned long long limit;
+	unsigned long long hard_limit;
+	/*
+	 * the limit that usage can exceed, but under memory
+	 * pressure, we will reclaim back memory above the
+	 * soft limit mark
+	 */
+	unsigned long long soft_limit;
 	/*
 	 * the number of unsuccessful attempts to consume the resource
 	 */
@@ -64,7 +70,8 @@ ssize_t res_counter_write(struct res_cou
 
 enum {
 	RES_USAGE,
-	RES_LIMIT,
+	RES_SOFT_LIMIT,
+	RES_HARD_LIMIT,
 	RES_FAILCNT,
 };
 
@@ -101,11 +108,21 @@ int res_counter_charge(struct res_counte
 void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
 void res_counter_uncharge(struct res_counter *counter, unsigned long val);
 
-static inline bool res_counter_limit_check_locked(struct res_counter *cnt)
+static inline bool res_counter_limit_check_locked(struct res_counter *cnt,
+							int member)
 {
-	if (cnt->usage < cnt->limit)
-		return true;
-
+	switch (member) {
+	case RES_HARD_LIMIT:
+		if (cnt->usage < cnt->hard_limit)
+			return true;
+		break;
+	case RES_SOFT_LIMIT:
+		if (cnt->usage < cnt->soft_limit)
+			return true;
+		break;
+	default:
+		BUG_ON(1);
+	}
 	return false;
 }
 
@@ -113,13 +130,14 @@ static inline bool res_counter_limit_che
  * Helper function to detect if the cgroup is within it's limit or
  * not. It's currently called from cgroup_rss_prepare()
  */
-static inline bool res_counter_check_under_limit(struct res_counter *cnt)
+static inline bool res_counter_check_under_limit(struct res_counter *cnt,
+							int member)
 {
 	bool ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&cnt->lock, flags);
-	ret = res_counter_limit_check_locked(cnt);
+	ret = res_counter_limit_check_locked(cnt, member);
 	spin_unlock_irqrestore(&cnt->lock, flags);
 	return ret;
 }
diff -puN include/linux/memcontrol.h~memory-controller-res_counters-soft-limit-setup include/linux/memcontrol.h
_

-- 
	Warm Regards,
	Balbir Singh
	Linux Technology Center
	IBM, ISTL

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help