[RFC PATCH 4/5] crash dump bitmap: add a proc interface for crash dump bitmap

Jingbai Ma jingbai.ma at hp.com
Thu Mar 7 09:59:08 EST 2013


Add a procfs driver for selecting exclude pages in userspace.
/proc/crash_dump_bitmap/

Signed-off-by: Jingbai Ma <jingbai.ma at hp.com>
---
 fs/proc/Makefile            |    1 
 fs/proc/crash_dump_bitmap.c |  221 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 222 insertions(+), 0 deletions(-)
 create mode 100644 fs/proc/crash_dump_bitmap.c

diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index 712f24d..2dfcff1 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -27,6 +27,7 @@ proc-$(CONFIG_PROC_SYSCTL)	+= proc_sysctl.o
 proc-$(CONFIG_NET)		+= proc_net.o
 proc-$(CONFIG_PROC_KCORE)	+= kcore.o
 proc-$(CONFIG_PROC_VMCORE)	+= vmcore.o
+proc-$(CONFIG_CRASH_DUMP_BITMAP)	+= crash_dump_bitmap.o
 proc-$(CONFIG_PROC_DEVICETREE)	+= proc_devtree.o
 proc-$(CONFIG_PRINTK)	+= kmsg.o
 proc-$(CONFIG_PROC_PAGE_MONITOR)	+= page.o
diff --git a/fs/proc/crash_dump_bitmap.c b/fs/proc/crash_dump_bitmap.c
new file mode 100644
index 0000000..77ecaae
--- /dev/null
+++ b/fs/proc/crash_dump_bitmap.c
@@ -0,0 +1,221 @@
+/*
+ *    fs/proc/crash_dump_bitmap.c
+ *    Interface for controlling the crash dump bitmap from user space.
+ *
+ *    (C) Copyright 2013 Hewlett-Packard Development Company, L.P.
+ *    Author: Jingbai Ma <jingbai.ma at hp.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of version 2 of the GNU General Public License as
+ *    published by the Free Software Foundation.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *    General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/jiffies.h>
+#include <linux/crash_dump.h>
+#include <linux/crash_dump_bitmap.h>
+
+#ifdef CONFIG_CRASH_DUMP_BITMAP
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jingbai Ma <jingbai.ma at hp.com>");
+MODULE_DESCRIPTION("Crash dump bitmap support driver");
+
+static const char *proc_dir_name = "crash_dump_bitmap";
+static const char *proc_page_status_name = "page_status";
+static const char *proc_dump_level_name = "dump_level";
+
+static struct proc_dir_entry *proc_dir, *proc_page_status, *proc_dump_level;
+
+static unsigned int get_dump_level(void)
+{
+	unsigned int dump_level;
+
+	dump_level = crash_dump_bitmap_ctrl.exclude_zero_pages
+		? CRASH_DUMP_LEVEL_EXCLUDE_ZERO_PAGES : 0;
+	dump_level |= crash_dump_bitmap_ctrl.exclude_cache_pages
+		? CRASH_DUMP_LEVEL_EXCLUDE_CACHE_PAGES : 0;
+	dump_level |= crash_dump_bitmap_ctrl.exclude_cache_private_pages
+		? CRASH_DUMP_LEVEL_EXCLUDE_CACHE_PRIVATE_PAGES : 0;
+	dump_level |= crash_dump_bitmap_ctrl.exclude_user_pages
+		? CRASH_DUMP_LEVEL_EXCLUDE_USER_PAGES : 0;
+	dump_level |= crash_dump_bitmap_ctrl.exclude_free_pages
+		? CRASH_DUMP_LEVEL_EXCLUDE_FREE_PAGES : 0;
+
+	return dump_level;
+}
+
+static void set_dump_level(unsigned int dump_level)
+{
+	crash_dump_bitmap_ctrl.exclude_zero_pages =
+		(dump_level & CRASH_DUMP_LEVEL_EXCLUDE_ZERO_PAGES) ? 1 : 0;
+	crash_dump_bitmap_ctrl.exclude_cache_pages =
+		(dump_level & CRASH_DUMP_LEVEL_EXCLUDE_CACHE_PAGES) ? 1 : 0;
+	crash_dump_bitmap_ctrl.exclude_cache_private_pages =
+		(dump_level & CRASH_DUMP_LEVEL_EXCLUDE_CACHE_PRIVATE_PAGES)
+		 ? 1 : 0;
+	crash_dump_bitmap_ctrl.exclude_user_pages =
+		(dump_level & CRASH_DUMP_LEVEL_EXCLUDE_USER_PAGES) ? 1 : 0;
+	crash_dump_bitmap_ctrl.exclude_free_pages =
+		(dump_level & CRASH_DUMP_LEVEL_EXCLUDE_FREE_PAGES) ? 1 : 0;
+}
+
+static int proc_page_status_show(struct seq_file *m, void *v)
+{
+	u64 start, duration;
+
+	if (!crash_dump_bitmap_mem) {
+		seq_printf(m,
+			"crash_dump_bitmap: crash_dump_bitmap_mem not found!\n");
+
+		return -EINVAL;
+	}
+
+	seq_printf(m, "Exclude page flag status:\n");
+	seq_printf(m, "    exclude_dump_bitmap_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_crash_dump_bitmap_pages);
+	seq_printf(m, "    exclude_zero_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_zero_pages);
+	seq_printf(m, "    exclude_cache_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_cache_pages);
+	seq_printf(m, "    exclude_cache_private_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_cache_private_pages);
+	seq_printf(m, "    exclude_user_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_user_pages);
+	seq_printf(m, "    exclude_free_pages=%d\n",
+		crash_dump_bitmap_ctrl.exclude_free_pages);
+
+	seq_printf(m, "Scanning all memory pages:\n");
+	start = get_jiffies_64();
+	generate_crash_dump_bitmap();
+	duration = get_jiffies_64() - start;
+	seq_printf(m, "    Done. Duration=%dms\n", jiffies_to_msecs(duration));
+
+	seq_printf(m, "Excluded memory page status:\n");
+	seq_printf(m, "    cache_pages=%ld\n",
+		crash_dump_bitmap_info.cache_pages);
+	seq_printf(m, "    cache_private_pages=%ld\n",
+		crash_dump_bitmap_info.cache_private_pages);
+	seq_printf(m, "    user_pages=%ld\n",
+		crash_dump_bitmap_info.user_pages);
+	seq_printf(m, "    free_pages=%ld\n",
+		crash_dump_bitmap_info.free_pages);
+	seq_printf(m, "    hwpoison_pages=%ld\n",
+		crash_dump_bitmap_info.hwpoison_pages);
+
+	return 0;
+}
+
+static int proc_page_status_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_page_status_show, NULL);
+}
+
+static const struct file_operations proc_page_status_fops = {
+	.open		= proc_page_status_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int proc_dump_level_show(struct seq_file *m, void *v)
+{
+	if (!crash_dump_bitmap_mem) {
+		seq_printf(m,
+			"crash_dump_bitmap: crash_dump_bitmap_mem not found!\n");
+
+		return -EINVAL;
+	}
+
+	seq_printf(m, "%d\n", get_dump_level());
+
+	return 0;
+}
+
+static ssize_t proc_dump_level_write(struct file *file,
+	const char __user *buffer, size_t count, loff_t *ppos)
+{
+	int ret;
+	unsigned int dump_level;
+
+	ret = kstrtouint_from_user(buffer, count, 10, &dump_level);
+	if (ret)
+		return -EFAULT;
+
+	set_dump_level(dump_level);
+
+	pr_info("crash_dump_bitmap: new dump_level=%d\n", dump_level);
+
+	return count;
+}
+
+static int proc_dump_level_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_dump_level_show, NULL);
+}
+
+static const struct file_operations proc_dump_level_fops = {
+	.open		= proc_dump_level_open,
+	.read		= seq_read,
+	.write		= proc_dump_level_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+int __init init_proc_crash_dump_bitmap(void)
+{
+	if (is_kdump_kernel() || (crash_dump_bitmap_mem == 0)
+		|| (crash_dump_bitmap_mem_size == 0))
+		return 0;
+
+	proc_dir = proc_mkdir(proc_dir_name, NULL);
+	if (proc_dir == NULL) {
+		pr_err("crash_dump_bitmap: proc_mkdir failed!\n");
+		return -EINVAL;
+	}
+
+	proc_page_status = proc_create(proc_page_status_name, 0444,
+		proc_dir, &proc_page_status_fops);
+	if (proc_page_status == NULL) {
+		pr_err("crash_dump_bitmap: create procfs %s failed!\n",
+			proc_page_status_name);
+		remove_proc_entry(proc_dir_name, NULL);
+		return -EINVAL;
+	}
+
+	proc_dump_level = proc_create(proc_dump_level_name, 0644,
+		proc_dir, &proc_dump_level_fops);
+	if (proc_dump_level == NULL) {
+		pr_err("crash_dump_bitmap: create procfs %s failed!\n",
+			proc_dump_level_name);
+		remove_proc_entry(proc_page_status_name, proc_dir);
+		remove_proc_entry(proc_dir_name, NULL);
+		return -EINVAL;
+	}
+
+	pr_info("crash_dump_bitmap: procfs driver initialized successfully!\n");
+
+	return 0;
+}
+
+void __exit cleanup_proc_crash_dump_bitmap(void)
+{
+	remove_proc_entry(proc_dump_level_name, proc_dir);
+	remove_proc_entry(proc_page_status_name, proc_dir);
+	remove_proc_entry(proc_dir_name, NULL);
+
+	pr_info("crash_dump_bitmap: procfs driver unloaded!\n");
+}
+
+module_init(init_proc_crash_dump_bitmap);
+module_exit(cleanup_proc_crash_dump_bitmap);
+
+#endif /* CONFIG_CRASH_DUMP_BITMAP */




More information about the kexec mailing list