[RFC][PATCH 4/4] Aggregated beancounters syscall support

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

 




Add support for charging aggregated beancounters along with the beancounters
they contain. Limit checks are also done at the aggregated beancounter level.

Signed-off-by: Balbir Singh <[email protected]>
---

 include/bc/beancounter.h |    4 +++
 kernel/bc/beancounter.c  |   51 +++++++++++++++++++++++++++++++++++++++++++----
 kernel/bc/vmpages.c      |   23 +++++++++++++++++++--
 kernel/bc/vmrss.c        |   13 +++++++++++
 4 files changed, 84 insertions(+), 7 deletions(-)

diff -puN kernel/bc/beancounter.c~aggr-bc-charging-support kernel/bc/beancounter.c
--- linux-2.6.18-rc5/kernel/bc/beancounter.c~aggr-bc-charging-support	2006-09-17 20:34:48.000000000 +0530
+++ linux-2.6.18-rc5-balbir/kernel/bc/beancounter.c	2006-09-17 20:34:48.000000000 +0530
@@ -199,6 +199,7 @@ struct beancounter *beancounter_relocate
 	unsigned long flags;
 	struct beancounter *bc = NULL, *new_bc;
 	struct hlist_head *slot;
+	int i;
 
 	double_ab_lock(dst_ab, src_ab, &flags);
 	bc = beancounter_find_locked(src_ab, id);
@@ -217,10 +218,26 @@ struct beancounter *beancounter_relocate
 	}
 
 	spin_lock(&bc->bc_lock);
+
+	/*
+	 * TODO: Support limit checking before relocation
+	 */
+	for (i = 0; i < BC_RESOURCES; i++)
+		src_ab->ab_parms[i].held -= bc->bc_parms[i].held;
+	src_ab->unused_privvmpages -= bc->unused_privvmpages;
+	src_ab->rss_pages -= bc->rss_pages;
+
 	hlist_del(&bc->hash);
 	slot = &dst_ab->ab_bucket[bc_hash_fn(id)];
 	hlist_add_head(&bc->hash, slot);
 	bc->ab = dst_ab;
+
+	for (i = 0; i < BC_RESOURCES; i++)
+		dst_ab->ab_parms[i].held += bc->bc_parms[i].held;
+
+	dst_ab->unused_privvmpages += bc->unused_privvmpages;
+	dst_ab->rss_pages += bc->rss_pages;
+
 	spin_unlock(&bc->bc_lock);
 
 out:
@@ -243,6 +260,14 @@ void put_aggr_beancounter(struct aggr_be
 			printk("AB: %d has %lu of %s held on put", ab->ab_id,
 				ab->ab_parms[i].held, bc_rnames[i]);
 
+	if (ab->unused_privvmpages != 0)
+		printk("AB: %d has %lu of unused pages held on put", ab->ab_id,
+			ab->unused_privvmpages);
+#ifdef CONFIG_BEANCOUNTERS_RSS
+	if (ab->rss_pages != 0)
+		printk("AB: %d hash %llu of rss pages held on put", ab->ab_id,
+			ab->rss_pages);
+#endif
 	hlist_del(&ab->hash);
 	nr_beancounters--;
 	spin_unlock_irqrestore(&ab_hash_lock, flags);
@@ -294,6 +319,7 @@ int bc_charge_locked(struct beancounter 
 		enum bc_severity strict)
 {
 	unsigned long new_held;
+	struct aggr_beancounter *ab = bc->ab;
 
 	/*
 	 * bc_value <= BC_MAXVALUE, value <= BC_MAXVALUE, and only one addition
@@ -303,17 +329,18 @@ int bc_charge_locked(struct beancounter 
 
 	switch (strict) {
 	case BC_BARRIER:
-		if (bc->bc_parms[resource].held >
-				bc->bc_parms[resource].barrier)
+		if (ab->ab_parms[resource].held >
+				ab->ab_parms[resource].barrier)
 			break;
 		/* fallthrough */
 	case BC_LIMIT:
-		if (bc->bc_parms[resource].held >
-				bc->bc_parms[resource].limit)
+		if (ab->ab_parms[resource].held >
+				ab->ab_parms[resource].limit)
 			break;
 		/* fallthrough */
 	case BC_FORCE:
 		bc->bc_parms[resource].held = new_held;
+		ab->ab_parms[resource].held += val;
 		bc_adjust_maxheld(bc, resource);
 		return 0;
 
@@ -344,6 +371,19 @@ EXPORT_SYMBOL_GPL(bc_charge);
 /* called with bc->bc_lock held and interrupts disabled */
 void bc_uncharge_locked(struct beancounter *bc, int resource, unsigned long val)
 {
+	struct aggr_beancounter *ab = bc->ab;
+	unsigned long val2 = val;
+
+	if (unlikely(ab->ab_parms[resource].held < val)) {
+		if (printk_ratelimit()) {
+			printk("AB: overuncharging ab %d %s: val %lu, holds "
+				"%lu\n", ab->ab_id, bc_rnames[resource], val,
+				ab->ab_parms[resource].held);
+			dump_stack();
+		}
+		val2 = ab->ab_parms[resource].held;
+	}
+
 	if (unlikely(bc->bc_parms[resource].held < val)) {
 		if (printk_ratelimit()) {
 			printk("BC: overuncharging bc %d %s: val %lu, holds "
@@ -355,6 +395,7 @@ void bc_uncharge_locked(struct beancount
 	}
 
 	bc->bc_parms[resource].held -= val;
+	ab->ab_parms[resource].held -= val2;
 	bc_adjust_minheld(bc, resource);
 }
 EXPORT_SYMBOL_GPL(bc_uncharge_locked);
@@ -404,6 +445,8 @@ static void init_aggr_beancounter_struct
 	for (i = 0; i < AB_HASH_SIZE; i++)
 		INIT_HLIST_HEAD(&ab->ab_bucket[i]);
 	INIT_HLIST_NODE(&ab->hash);
+	ab->unused_privvmpages = 0;
+	ab->rss_pages = 0;
 }
 
 static void init_aggr_beancounter_parm_nolimits(struct aggr_beancounter *ab)
diff -puN kernel/bc/vmpages.c~aggr-bc-charging-support kernel/bc/vmpages.c
--- linux-2.6.18-rc5/kernel/bc/vmpages.c~aggr-bc-charging-support	2006-09-17 20:34:48.000000000 +0530
+++ linux-2.6.18-rc5-balbir/kernel/bc/vmpages.c	2006-09-17 20:34:48.000000000 +0530
@@ -17,6 +17,13 @@
 
 void bc_update_privvmpages(struct beancounter *bc)
 {
+	struct aggr_beancounter *ab = bc->ab;
+
+	ab->ab_parms[BC_PRIVVMPAGES].held = ab->unused_privvmpages
+#ifdef CONFIG_BEANCOUNTERS_RSS
+		+ (ab->rss_pages >> PB_PAGE_WEIGHT_SHIFT)
+#endif
+		;
 	bc->bc_parms[BC_PRIVVMPAGES].held = bc->unused_privvmpages
 #ifdef CONFIG_BEANCOUNTERS_RSS
 		+ (bc->rss_pages >> PB_PAGE_WEIGHT_SHIFT)
@@ -33,17 +40,29 @@ static inline int privvm_charge(struct b
 		return -ENOMEM;
 
 	bc->unused_privvmpages += sz;
+	bc->ab->unused_privvmpages += sz;
 	return 0;
 }
 
 static inline void privvm_uncharge(struct beancounter *bc, unsigned long sz)
 {
+	unsigned long sz2 = sz;
+	struct aggr_beancounter *ab = bc->ab;
+
 	if (unlikely(bc->unused_privvmpages < sz)) {
-		printk("BC: overuncharging %d unused pages: val %lu held %lu\n",
-				bc->bc_id, sz, bc->unused_privvmpages);
+		printk("privvm_uncharge: BC: overuncharging %d unused pages: "
+			" val %lu held %lu\n", bc->bc_id, sz,
+			bc->unused_privvmpages);
 		sz = bc->unused_privvmpages;
 	}
+	if (unlikely(ab->unused_privvmpages < sz2)) {
+		printk("privvm_uncharge: AB: overuncharging %d unused pages: "
+			"val %lu held %lu\n", ab->ab_id, sz,
+			ab->unused_privvmpages);
+		sz2 = ab->unused_privvmpages;
+	}
 	bc->unused_privvmpages -= sz;
+	ab->unused_privvmpages -= sz;
 	bc_update_privvmpages(bc);
 }
 
diff -puN include/bc/beancounter.h~aggr-bc-charging-support include/bc/beancounter.h
--- linux-2.6.18-rc5/include/bc/beancounter.h~aggr-bc-charging-support	2006-09-17 20:34:48.000000000 +0530
+++ linux-2.6.18-rc5-balbir/include/bc/beancounter.h	2006-09-17 20:34:48.000000000 +0530
@@ -77,6 +77,10 @@ struct aggr_beancounter {
 	spinlock_t 		ab_lock;
 	struct hlist_node	hash;
 	bcid_t			ab_id;
+	unsigned long		unused_privvmpages;
+#ifdef CONFIG_BEANCOUNTERS_RSS
+	unsigned long long	rss_pages;
+#endif
 };
 
 /*
diff -puN kernel/bc/vmrss.c~aggr-bc-charging-support kernel/bc/vmrss.c
--- linux-2.6.18-rc5/kernel/bc/vmrss.c~aggr-bc-charging-support	2006-09-17 20:34:48.000000000 +0530
+++ linux-2.6.18-rc5-balbir/kernel/bc/vmrss.c	2006-09-17 20:34:48.000000000 +0530
@@ -154,19 +154,30 @@ static void mod_rss_pages(struct beancou
 		struct vm_area_struct *vma, int unused)
 {
 	unsigned long flags;
+	int unused2 = unused;
 
 	spin_lock_irqsave(&bc->bc_lock, flags);
 	if (vma && BC_VM_PRIVATE(vma->vm_flags, vma->vm_file)) {
 		if (unused < 0 && unlikely(bc->unused_privvmpages < -unused)) {
-			printk("BC: overuncharging %d unused pages: "
+			printk("mod_rss: BC: overuncharging %d unused pages: "
 					"val %i, held %lu\n",
 					bc->bc_id, unused,
 					bc->unused_privvmpages);
 			unused = -bc->unused_privvmpages;
 		}
+		if (unused < 0 && unlikely(bc->ab->unused_privvmpages <
+						-unused)) {
+			printk("mod_rss: AB: overuncharging %d unused pages: "
+					"val %i, held %lu\n",
+					bc->ab->ab_id, unused,
+					bc->ab->unused_privvmpages);
+			unused2 = -bc->ab->unused_privvmpages;
+		}
 		bc->unused_privvmpages += unused;
+		bc->ab->unused_privvmpages += unused2;
 	}
 	bc->rss_pages += val;
+	bc->ab->rss_pages += val;
 	bc_update_privvmpages(bc);
 	spin_unlock_irqrestore(&bc->bc_lock, flags);
 }
_

-- 

	Balbir Singh,
	Linux Technology Center,
	IBM Software Labs

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux