public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [Resend Patch] kexec: allow to shrink reserved memory
@ 2009-11-23  9:37 Amerigo Wang
  2009-11-23 19:41 ` Eric W. Biederman
  2009-11-24  7:58 ` Dan Carpenter
  0 siblings, 2 replies; 5+ messages in thread
From: Amerigo Wang @ 2009-11-23  9:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Eric W. Biederman, akpm, Andi Kleen, Amerigo Wang, Neil Horman


This patch implements shrinking the reserved memory for crash kernel,
if it is more than enough.

For example, if you have already reserved 128M, now you just want 100M,
you can do:

# echo $((100*1024*1024)) > /sys/kernel/kexec_crash_size

Note, you can only do this before loading the crash kernel.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Neil Horman <nhorman@redhat.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Andi Kleen <andi@firstfloor.org>

---
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index adc34f2..c356b69 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -206,6 +206,8 @@ extern size_t vmcoreinfo_max_size;
 
 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
 		unsigned long long *crash_size, unsigned long long *crash_base);
+int crash_shrink_memory(unsigned long new_size);
+size_t crash_get_memory_size(void);
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
diff --git a/kernel/kexec.c b/kernel/kexec.c
index f336e21..433e9fc 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -31,6 +31,7 @@
 #include <linux/cpu.h>
 #include <linux/console.h>
 #include <linux/vmalloc.h>
+#include <linux/swap.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -1082,6 +1083,64 @@ void crash_kexec(struct pt_regs *regs)
 	}
 }
 
+size_t crash_get_memory_size(void)
+{
+	size_t size;
+	mutex_lock(&kexec_mutex);
+	size = crashk_res.end - crashk_res.start + 1;
+	mutex_unlock(&kexec_mutex);
+	return size;
+}
+
+static void free_reserved_phys_range(unsigned long begin, unsigned long end)
+{
+	unsigned long addr;
+
+	for (addr = begin; addr < end; addr += PAGE_SIZE) {
+		ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT));
+		init_page_count(pfn_to_page(addr >> PAGE_SHIFT));
+		free_page((unsigned long)__va(addr));
+		totalram_pages++;
+	}
+}
+
+int crash_shrink_memory(unsigned long new_size)
+{
+	int ret = 0;
+	unsigned long start, end;
+
+	mutex_lock(&kexec_mutex);
+
+	if (kexec_crash_image) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+	start = crashk_res.start;
+	end = crashk_res.end;
+
+	if (new_size >= end - start + 1) {
+		ret = -EINVAL;
+		if (new_size == end - start + 1)
+			ret = 0;
+		goto unlock;
+	}
+
+	start = roundup(start, PAGE_SIZE);
+	end = roundup(start + new_size, PAGE_SIZE);
+
+	free_reserved_phys_range(end, crashk_res.end);
+
+	if (start == end) {
+		crashk_res.end = end;
+		release_resource(&crashk_res);
+	} else
+		crashk_res.end = end - 1;
+
+unlock:
+	mutex_unlock(&kexec_mutex);
+	return ret;
+}
+
 static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
 			    size_t data_len)
 {
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 528dd78..5b9276b 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -100,6 +100,26 @@ static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
 }
 KERNEL_ATTR_RO(kexec_crash_loaded);
 
+static ssize_t kexec_crash_size_show(struct kobject *kobj,
+				       struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%lu\n", crash_get_memory_size());
+}
+static ssize_t kexec_crash_size_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t count)
+{
+	unsigned long cnt;
+	int ret;
+
+	if (strict_strtoul(buf, 0, &cnt))
+		return -EINVAL;
+
+	ret = crash_shrink_memory(cnt);
+	return ret < 0 ? ret : count;
+}
+KERNEL_ATTR_RW(kexec_crash_size);
+
 static ssize_t vmcoreinfo_show(struct kobject *kobj,
 			       struct kobj_attribute *attr, char *buf)
 {
@@ -147,6 +167,7 @@ static struct attribute * kernel_attrs[] = {
 #ifdef CONFIG_KEXEC
 	&kexec_loaded_attr.attr,
 	&kexec_crash_loaded_attr.attr,
+	&kexec_crash_size_attr.attr,
 	&vmcoreinfo_attr.attr,
 #endif
 	NULL

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Resend Patch] kexec: allow to shrink reserved memory
  2009-11-23  9:37 [Resend Patch] kexec: allow to shrink reserved memory Amerigo Wang
@ 2009-11-23 19:41 ` Eric W. Biederman
  2009-11-24  7:58 ` Dan Carpenter
  1 sibling, 0 replies; 5+ messages in thread
From: Eric W. Biederman @ 2009-11-23 19:41 UTC (permalink / raw)
  To: Amerigo Wang; +Cc: linux-kernel, akpm, Andi Kleen, Neil Horman

Amerigo Wang <amwang@redhat.com> writes:

> This patch implements shrinking the reserved memory for crash kernel,
> if it is more than enough.
>
> For example, if you have already reserved 128M, now you just want 100M,
> you can do:
>
> # echo $((100*1024*1024)) > /sys/kernel/kexec_crash_size
>
> Note, you can only do this before loading the crash kernel.

Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>

Looks good to me.

Eric



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Resend Patch] kexec: allow to shrink reserved memory
  2009-11-23  9:37 [Resend Patch] kexec: allow to shrink reserved memory Amerigo Wang
  2009-11-23 19:41 ` Eric W. Biederman
@ 2009-11-24  7:58 ` Dan Carpenter
  2009-11-24  8:37   ` Cong Wang
  2009-11-24  8:50   ` Cong Wang
  1 sibling, 2 replies; 5+ messages in thread
From: Dan Carpenter @ 2009-11-24  7:58 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, Eric W. Biederman, akpm, Andi Kleen, Neil Horman

On Mon, Nov 23, 2009 at 04:37:02AM -0500, Amerigo Wang wrote:
[snip]
> +size_t crash_get_memory_size(void);
[snip]
> +static ssize_t kexec_crash_size_show(struct kobject *kobj,
> +				       struct kobj_attribute *attr, char *buf)
> +{
> +	return sprintf(buf, "%lu\n", crash_get_memory_size());
> +}

  CC      kernel/ksysfs.o
kernel/ksysfs.c: In function ‘kexec_crash_size_show’:
kernel/ksysfs.c:106: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘size_t’

Could we get suppress this gcc warning?

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Resend Patch] kexec: allow to shrink reserved memory
  2009-11-24  7:58 ` Dan Carpenter
@ 2009-11-24  8:37   ` Cong Wang
  2009-11-24  8:50   ` Cong Wang
  1 sibling, 0 replies; 5+ messages in thread
From: Cong Wang @ 2009-11-24  8:37 UTC (permalink / raw)
  To: Dan Carpenter, Amerigo Wang, linux-kernel, Eric W. Biederman,
	akpm, Andi Kleen, Neil Horman

Dan Carpenter wrote:
> On Mon, Nov 23, 2009 at 04:37:02AM -0500, Amerigo Wang wrote:
> [snip]
>> +size_t crash_get_memory_size(void);
> [snip]
>> +static ssize_t kexec_crash_size_show(struct kobject *kobj,
>> +				       struct kobj_attribute *attr, char *buf)
>> +{
>> +	return sprintf(buf, "%lu\n", crash_get_memory_size());
>> +}
> 
>   CC      kernel/ksysfs.o
> kernel/ksysfs.c: In function ‘kexec_crash_size_show’:
> kernel/ksysfs.c:106: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘size_t’
> 
> Could we get suppress this gcc warning?

Oops! Try to replace '%lu' with '%zu'...

I didn't see this warning, will cook a delta patch.

Thanks!

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Resend Patch] kexec: allow to shrink reserved memory
  2009-11-24  7:58 ` Dan Carpenter
  2009-11-24  8:37   ` Cong Wang
@ 2009-11-24  8:50   ` Cong Wang
  1 sibling, 0 replies; 5+ messages in thread
From: Cong Wang @ 2009-11-24  8:50 UTC (permalink / raw)
  To: Dan Carpenter, Amerigo Wang, linux-kernel, Eric W. Biederman,
	akpm, Andi Kleen, Neil Horman

[-- Attachment #1: Type: text/plain, Size: 623 bytes --]

Dan Carpenter wrote:
> On Mon, Nov 23, 2009 at 04:37:02AM -0500, Amerigo Wang wrote:
> [snip]
>> +size_t crash_get_memory_size(void);
> [snip]
>> +static ssize_t kexec_crash_size_show(struct kobject *kobj,
>> +				       struct kobj_attribute *attr, char *buf)
>> +{
>> +	return sprintf(buf, "%lu\n", crash_get_memory_size());
>> +}
> 
>   CC      kernel/ksysfs.o
> kernel/ksysfs.c: In function ‘kexec_crash_size_show’:
> kernel/ksysfs.c:106: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘size_t’
> 

Patch below fixes this.

Andrew, could you please fold it in? Thanks!


[-- Attachment #2: kexec-free-reserved-memory-delta-fix.diff --]
[-- Type: text/plain, Size: 507 bytes --]

diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 5b9276b..3feaf5a 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -103,7 +103,7 @@ KERNEL_ATTR_RO(kexec_crash_loaded);
 static ssize_t kexec_crash_size_show(struct kobject *kobj,
 				       struct kobj_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%lu\n", crash_get_memory_size());
+	return sprintf(buf, "%zu\n", crash_get_memory_size());
 }
 static ssize_t kexec_crash_size_store(struct kobject *kobj,
 				   struct kobj_attribute *attr,

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-11-24  8:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-23  9:37 [Resend Patch] kexec: allow to shrink reserved memory Amerigo Wang
2009-11-23 19:41 ` Eric W. Biederman
2009-11-24  7:58 ` Dan Carpenter
2009-11-24  8:37   ` Cong Wang
2009-11-24  8:50   ` Cong Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox