Subject: [PATCH 8/8] pseries: phyp dump: Tracking memory range freed.

From: Manish Ahuja <[email-masked]>
Date: Mon, 07 Jan 2008 18:39:52 -0600

This patch tracks the size freed. For now it does a simple
rudimentary calculation of the ranges freed. The idea is
to keep it simple at the external shell script level and 
send in large chunks for now.

Signed-off-by: Manish Ahuja <[email-masked]>
-----

---
 arch/powerpc/platforms/pseries/phyp_dump.c |   36 +++++++++++++++++++++++++++++
 include/asm-powerpc/phyp_dump.h            |    3 ++
 2 files changed, 39 insertions(+)

Index: 2.6.24-rc5/include/asm-powerpc/phyp_dump.h
===================================================================
--- 2.6.24-rc5.orig/include/asm-powerpc/phyp_dump.h	2008-01-07 22:55:28.000000000 -0600
+++ 2.6.24-rc5/include/asm-powerpc/phyp_dump.h	2008-01-07 22:58:02.000000000 -0600
@@ -24,6 +24,9 @@ struct phyp_dump {
 	/* Memory that is reserved during very early boot. */
 	unsigned long init_reserve_start;
 	unsigned long init_reserve_size;
+	/* Scratch area memory details */
+	unsigned long scratch_reserve_start;
+	unsigned long scratch_reserve_size;
 };
 
 extern struct phyp_dump *phyp_dump_info;
Index: 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c
===================================================================
--- 2.6.24-rc5.orig/arch/powerpc/platforms/pseries/phyp_dump.c	2008-01-07 22:57:27.000000000 -0600
+++ 2.6.24-rc5/arch/powerpc/platforms/pseries/phyp_dump.c	2008-01-07 22:58:02.000000000 -0600
@@ -287,6 +287,39 @@ release_memory_range(unsigned long start
 	}
 }
 
+/**
+ * track_freed_range -- Counts the range being freed.
+ * Once the counter goes to zero, it re-registers dump for
+ * future use.
+ */
+static void
+track_freed_range(unsigned long addr, unsigned long length)
+{
+	static unsigned long scratch_area_size, reserved_area_size;
+
+	if (addr < phyp_dump_info->init_reserve_start)
+		return;
+
+	if ((addr >= phyp_dump_info->init_reserve_start) &&
+	    (addr <= phyp_dump_info->init_reserve_start +
+	     phyp_dump_info->init_reserve_size))
+		reserved_area_size += length;
+
+	if ((addr >= phyp_dump_info->scratch_reserve_start) &&
+	    (addr <= phyp_dump_info->scratch_reserve_start +
+	     phyp_dump_info->scratch_reserve_size))
+		scratch_area_size += length;
+
+	if ((reserved_area_size == phyp_dump_info->init_reserve_start) &&
+	    (scratch_area_size == phyp_dump_info->scratch_reserve_size)) {
+
+		invalidate_last_dump(&phdr,
+				phyp_dump_info->scratch_reserve_start);
+		register_dump_area (&phdr,
+				phyp_dump_info->scratch_reserve_start);
+	}
+}
+
 /* ------------------------------------------------- */
 /**
  * sysfs_release_region -- sysfs interface to release memory range.
@@ -310,6 +343,8 @@ store_release_region(struct kset *kset, 
 	if (ret != 2)
 		return -EINVAL;
 
+	track_freed_range(start_addr, length);
+
 	/* Range-check - don't free any reserved memory that
 	 * wasn't reserved for phyp-dump */
 	if (start_addr < phyp_dump_info->init_reserve_start)
@@ -414,6 +449,7 @@ static int __init phyp_dump_setup(void)
 	}
 
 	/* Don't allow user to release the 256MB scratch area */
+	/* this might be wrong */
 	phyp_dump_info->init_reserve_size = free_area_length;
 
 	/* Should we create a dump_subsys, analogous to s390/ipl.c ? */