public inbox for kexec@lists.infradead.org
 help / color / mirror / Atom feed
* getting memory footprint of new kernel
@ 2013-01-18 16:38 Olaf Hering
  2013-01-18 19:41 ` [PATCH 1/2] kexec_newkernel_phys and kexec_newkernel_memsz Olaf Hering
  2013-01-18 19:44 ` [PATCH 2/2] register_balloon_populate_range Olaf Hering
  0 siblings, 2 replies; 3+ messages in thread
From: Olaf Hering @ 2013-01-18 16:38 UTC (permalink / raw)
  To: kexec


I'm working on kexec support for a ballooned Xen PVonHVM guest.

One of the issues is that the new kernel must run in populated memory,
otherwise it will access ballooned pages and crash.

The kexec syscall passes several physical memory ranges in
kexec_segment->{mem,memsz}. Thats enough info to populate the purgatory
code and early startup code of the new kernel. 

But it lacks the memory range of the new kernel. From my understanding
the entry point is know by kexec(1), it is
kexec/arch/i386/kexec-bzImage.c:do_bzImage_load():kernel32_load_addr
The memory size howver is not known, and I dont see a way to retreive
this information from a bzImage. I think it should be all in the ELF
data of the compressed vmlinux.bin, but this compressed content is not
accessible. 

So what would be a good way to know or estimate the memory size of the
new kernel, and pass the start and size to the balloon driver so that it
can populate the range? I see there are already a few kexec related
sysfs files in kernel/ksysfs.c. What about something like
kexec_newkernel_phys and kexec_newkernel_memsz?

Olaf

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH 1/2] kexec_newkernel_phys and kexec_newkernel_memsz
  2013-01-18 16:38 getting memory footprint of new kernel Olaf Hering
@ 2013-01-18 19:41 ` Olaf Hering
  2013-01-18 19:44 ` [PATCH 2/2] register_balloon_populate_range Olaf Hering
  1 sibling, 0 replies; 3+ messages in thread
From: Olaf Hering @ 2013-01-18 19:41 UTC (permalink / raw)
  To: kexec


This adds sysfs entries /sys/kernel/kexec_newkernel_phys and
/sys/kernel/kexec_newkernel_memsz. Both are supposed to be passed to a
balloon driver.

---
 include/linux/kexec.h |  5 +++++
 kernel/kexec.c        | 24 ++++++++++++++++++++++++
 kernel/ksysfs.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index d0b8458..3a317b6 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -203,6 +203,11 @@ int crash_shrink_memory(unsigned long new_size);
 size_t crash_get_memory_size(void);
 void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
 
+unsigned long kexec_newkernel_get_phys(void);
+void kexec_newkernel_set_phys(unsigned long phys);
+unsigned long kexec_newkernel_get_memsz(void);
+void kexec_newkernel_set_memsz(unsigned long memsz);
+
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
 struct task_struct;
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 5e4bd78..9e421a8 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -38,6 +38,9 @@
 #include <asm/io.h>
 #include <asm/sections.h>
 
+static unsigned long kexec_newkernel_phys;
+static unsigned long kexec_newkernel_memsz;
+
 /* Per cpu memory for storing cpu states in case of system crash. */
 note_buf_t __percpu *crash_notes;
 
@@ -62,6 +65,27 @@ int kexec_should_crash(struct task_struct *p)
 	return 0;
 }
 
+unsigned long kexec_newkernel_get_phys(void)
+{
+	return kexec_newkernel_phys;
+}
+
+void kexec_newkernel_set_phys(unsigned long phys)
+{
+	printk("%s: kexec_newkernel_phys %lx -> %lx\n", __func__, kexec_newkernel_phys, phys);
+	kexec_newkernel_phys = phys;
+}
+
+unsigned long kexec_newkernel_get_memsz(void)
+{
+	return kexec_newkernel_memsz;
+}
+
+void kexec_newkernel_set_memsz(unsigned long memsz)
+{
+	printk("%s: kexec_newkernel_mensz %lx -> %lx\n", __func__, kexec_newkernel_memsz, memsz);
+	kexec_newkernel_memsz = memsz;
+}
 /*
  * When kexec transitions to the new kernel there is a one-to-one
  * mapping between physical and virtual addresses.  On processors
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 6ada93c..0660e40 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -121,6 +121,44 @@ static ssize_t kexec_crash_size_store(struct kobject *kobj,
 }
 KERNEL_ATTR_RW(kexec_crash_size);
 
+static ssize_t kexec_newkernel_phys_show(struct kobject *kobj,
+				       struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%zu\n", kexec_newkernel_get_phys());
+}
+static ssize_t kexec_newkernel_phys_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t count)
+{
+	unsigned long phys;
+
+	if (strict_strtoul(buf, 0, &phys))
+		return -EINVAL;
+
+	kexec_newkernel_set_phys(phys);
+	return count;
+}
+KERNEL_ATTR_RW(kexec_newkernel_phys);
+
+static ssize_t kexec_newkernel_memsz_show(struct kobject *kobj,
+				       struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%zu\n", kexec_newkernel_get_memsz());
+}
+static ssize_t kexec_newkernel_memsz_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t count)
+{
+	unsigned long memsz;
+
+	if (strict_strtoul(buf, 0, &memsz))
+		return -EINVAL;
+
+	kexec_newkernel_set_memsz(memsz);
+	return count;
+}
+KERNEL_ATTR_RW(kexec_newkernel_memsz);
+
 static ssize_t vmcoreinfo_show(struct kobject *kobj,
 			       struct kobj_attribute *attr, char *buf)
 {
@@ -194,6 +232,8 @@ static struct attribute * kernel_attrs[] = {
 	&kexec_loaded_attr.attr,
 	&kexec_crash_loaded_attr.attr,
 	&kexec_crash_size_attr.attr,
+	&kexec_newkernel_phys_attr.attr,
+	&kexec_newkernel_memsz_attr.attr,
 	&vmcoreinfo_attr.attr,
 #endif
 	&rcu_expedited_attr.attr,
-- 
1.8.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH 2/2] register_balloon_populate_range
  2013-01-18 16:38 getting memory footprint of new kernel Olaf Hering
  2013-01-18 19:41 ` [PATCH 1/2] kexec_newkernel_phys and kexec_newkernel_memsz Olaf Hering
@ 2013-01-18 19:44 ` Olaf Hering
  1 sibling, 0 replies; 3+ messages in thread
From: Olaf Hering @ 2013-01-18 19:44 UTC (permalink / raw)
  To: kexec

This patch adds a hook for a balloon driver to populate segments before
the actual kexec.

---
 include/linux/kexec.h |  2 ++
 kernel/kexec.c        | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 3a317b6..b46f9c6 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -207,11 +207,13 @@ unsigned long kexec_newkernel_get_phys(void);
 void kexec_newkernel_set_phys(unsigned long phys);
 unsigned long kexec_newkernel_get_memsz(void);
 void kexec_newkernel_set_memsz(unsigned long memsz);
+void register_balloon_populate_range(void (*fn)(unsigned long pfn, unsigned long num));
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
 struct task_struct;
 static inline void crash_kexec(struct pt_regs *regs) { }
 static inline int kexec_should_crash(struct task_struct *p) { return 0; }
+static inline void register_balloon_populate_range(void (*fn)(unsigned long pfn, unsigned long num)) { }
 #endif /* CONFIG_KEXEC */
 #endif /* LINUX_KEXEC_H */
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 9e421a8..22a3881 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -32,6 +32,7 @@
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
 #include <linux/syscore_ops.h>
+#include <linux/export.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -86,6 +87,41 @@ void kexec_newkernel_set_memsz(unsigned long memsz)
 	printk("%s: kexec_newkernel_mensz %lx -> %lx\n", __func__, kexec_newkernel_memsz, memsz);
 	kexec_newkernel_memsz = memsz;
 }
+
+static void (*balloon_populate_range)(unsigned long pfn, unsigned long num);
+
+void register_balloon_populate_range(void (*fn)(unsigned long pfn, unsigned long num))
+{
+	if (!balloon_populate_range)
+		balloon_populate_range = fn;
+}
+EXPORT_SYMBOL_GPL(register_balloon_populate_range);
+
+static void populate_range(unsigned long mem, size_t memsz)
+{
+	unsigned long pfn, num;
+
+
+
+	pfn = PFN_DOWN(mem);
+	num = PFN_UP(memsz);
+	if (pfn && num)
+		balloon_populate_range(pfn, num);
+}
+
+static void kimage_populate_ranges(struct kimage *image)
+{
+	unsigned long i;
+
+	if (!balloon_populate_range)
+		return;
+
+	for (i = 0; i < image->nr_segments; i++)
+		populate_range(image->segment[i].mem, image->segment[i].memsz);
+
+	populate_range(kexec_newkernel_phys, kexec_newkernel_memsz);
+}
+
 /*
  * When kexec transitions to the new kernel there is a one-to-one
  * mapping between physical and virtual addresses.  On processors
@@ -1598,6 +1634,8 @@ int kernel_kexec(void)
 		machine_shutdown();
 	}
 
+	kimage_populate_ranges(kexec_image);
+
 	machine_kexec(kexec_image);
 
 #ifdef CONFIG_KEXEC_JUMP
-- 
1.8.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

end of thread, other threads:[~2013-01-18 19:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-18 16:38 getting memory footprint of new kernel Olaf Hering
2013-01-18 19:41 ` [PATCH 1/2] kexec_newkernel_phys and kexec_newkernel_memsz Olaf Hering
2013-01-18 19:44 ` [PATCH 2/2] register_balloon_populate_range Olaf Hering

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