blob: bba8207cdd68dffdbfa1de0280dca1ae756c4f51 [file] [log] [blame]
---
drivers/misc/Makefile | 2 +
drivers/misc/dump-test.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
drivers/misc/printk-race.c | 70 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+)
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -51,3 +51,5 @@ obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_MEI) += mei/
+obj-m += printk-race.o
+obj-y += dump-test.o
--- /dev/null
+++ b/drivers/misc/dump-test.c
@@ -0,0 +1,72 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kmsg_dump.h>
+
+static char buf[64 * 1024];
+
+static int trigger_dump(const char *str, struct kernel_param *kp)
+{
+ kmsg_dump(KMSG_DUMP_OOPS);
+ return 0;
+}
+module_param_call(dump, trigger_dump, NULL, NULL, 0600);
+
+static void test_dump(struct kmsg_dumper *dumper,
+ enum kmsg_dump_reason reason)
+{
+ char s[512];
+ size_t len = 0;
+ size_t l;
+ int i = 0;
+
+#if 0
+ while (kmsg_dump_get_line(dumper, true, buf + len, sizeof(buf) - len, &l)) {
+ i++;
+ len += l;
+ }
+#else
+ while (len < sizeof(buf)) {
+ len += sprintf(buf + len, "#### Dump %i at %zi\n", i, len);
+
+ if (!kmsg_dump_get_buffer(dumper, true, buf + len, sizeof(buf), &l))
+ break;
+
+ len += l;
+ i++;
+ }
+#endif
+
+ printk("#### dumped %i pages, and %zi bytes\n", i, len);
+
+ memcpy(s, buf, 511);
+ s[511] = '\0';
+ printk("#### '%s'\n", s);
+
+ memcpy(s, buf + (len-512), 511);
+ s[511] = '\0';
+ printk("#### '%s'\n", s);
+}
+
+static struct kmsg_dumper test_dumper = {
+ .dump = test_dump,
+};
+
+static int __init test_init(void)
+{
+ printk(KERN_DEFAULT "dump test init\n");
+ kmsg_dump_register(&test_dumper);
+ return 0;
+}
+
+static void __exit test_exit(void)
+{
+ kmsg_dump_unregister(&test_dumper);
+ printk(KERN_DEFAULT "dump test cleanup\n");
+}
+
+module_init(test_init);
+module_exit(test_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kay Sievers <kay@vrfy.org>");
+MODULE_DESCRIPTION("kmsg dump test");
--- /dev/null
+++ b/drivers/misc/printk-race.c
@@ -0,0 +1,70 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+static void print_cont(char c)
+{
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ int k;
+
+ printk("(%c", c);
+ for (k = 0; k < 58; k++) {
+ printk(KERN_CONT "%c", c);
+ msleep(1);
+ }
+ printk(KERN_CONT "%c)\n", c);
+ }
+}
+
+static void print_c(struct work_struct *work)
+{
+ print_cont('C');
+}
+
+static void print_x(struct work_struct *work)
+{
+ print_cont('X');
+}
+
+static void print_atomic(struct work_struct *work)
+{
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ printk("(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)\n");
+ msleep(1);
+ }
+}
+
+
+static int __init printk_race_init(void)
+{
+ struct work_struct a_work;
+ struct work_struct c_work;
+ struct work_struct x_work;
+
+ printk(KERN_DEFAULT "printk test init\n");
+
+ INIT_WORK(&a_work, print_atomic);
+ INIT_WORK(&c_work, print_c);
+ INIT_WORK(&x_work, print_x);
+
+ schedule_work(&a_work);
+ schedule_work(&c_work);
+ //schedule_work(&x_work);
+
+ flush_work_sync(&a_work);
+ flush_work_sync(&c_work);
+ flush_work_sync(&x_work);
+
+ printk(KERN_DEFAULT "printk test cleanup\n");
+ return -EINVAL;
+}
+
+module_init(printk_race_init);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kay Sievers <kay@vrfy.org>");
+MODULE_DESCRIPTION("printk race test");