aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ramoops.txt25
-rw-r--r--fs/pstore/ram.c37
-rw-r--r--include/linux/pstore_ram.h1
3 files changed, 59 insertions, 4 deletions
diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 59a74a8ee2e5..197ad59ab9bf 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -94,3 +94,28 @@ timestamp and a new line. The dump then continues with the actual data.
94The dump data can be read from the pstore filesystem. The format for these 94The dump data can be read from the pstore filesystem. The format for these
95files is "dmesg-ramoops-N", where N is the record number in memory. To delete 95files is "dmesg-ramoops-N", where N is the record number in memory. To delete
96a stored record from RAM, simply unlink the respective pstore file. 96a stored record from RAM, simply unlink the respective pstore file.
97
985. Persistent function tracing
99
100Persistent function tracing might be useful for debugging software or hardware
101related hangs. The functions call chain log is stored in a "ftrace-ramoops"
102file. Here is an example of usage:
103
104 # mount -t debugfs debugfs /sys/kernel/debug/
105 # cd /sys/kernel/debug/tracing
106 # echo function > current_tracer
107 # echo 1 > options/func_pstore
108 # reboot -f
109 [...]
110 # mount -t pstore pstore /mnt/
111 # tail /mnt/ftrace-ramoops
112 0 ffffffff8101ea64 ffffffff8101bcda native_apic_mem_read <- disconnect_bsp_APIC+0x6a/0xc0
113 0 ffffffff8101ea44 ffffffff8101bcf6 native_apic_mem_write <- disconnect_bsp_APIC+0x86/0xc0
114 0 ffffffff81020084 ffffffff8101a4b5 hpet_disable <- native_machine_shutdown+0x75/0x90
115 0 ffffffff81005f94 ffffffff8101a4bb iommu_shutdown_noop <- native_machine_shutdown+0x7b/0x90
116 0 ffffffff8101a6a1 ffffffff8101a437 native_machine_emergency_restart <- native_machine_restart+0x37/0x40
117 0 ffffffff811f9876 ffffffff8101a73a acpi_reboot <- native_machine_emergency_restart+0xaa/0x1e0
118 0 ffffffff8101a514 ffffffff8101a772 mach_reboot_fixups <- native_machine_emergency_restart+0xe2/0x1e0
119 0 ffffffff811d9c54 ffffffff8101a7a0 __const_udelay <- native_machine_emergency_restart+0x110/0x1e0
120 0 ffffffff811d9c34 ffffffff811d9c80 __delay <- __const_udelay+0x30/0x40
121 0 ffffffff811d9d14 ffffffff811d9c3f delay_tsc <- __delay+0xf/0x20
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 74f4111bd0da..1dd108e0cc60 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -45,6 +45,10 @@ static ulong ramoops_console_size = MIN_MEM_SIZE;
45module_param_named(console_size, ramoops_console_size, ulong, 0400); 45module_param_named(console_size, ramoops_console_size, ulong, 0400);
46MODULE_PARM_DESC(console_size, "size of kernel console log"); 46MODULE_PARM_DESC(console_size, "size of kernel console log");
47 47
48static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
49module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
50MODULE_PARM_DESC(ftrace_size, "size of ftrace log");
51
48static ulong mem_address; 52static ulong mem_address;
49module_param(mem_address, ulong, 0400); 53module_param(mem_address, ulong, 0400);
50MODULE_PARM_DESC(mem_address, 54MODULE_PARM_DESC(mem_address,
@@ -70,16 +74,19 @@ MODULE_PARM_DESC(ramoops_ecc,
70struct ramoops_context { 74struct ramoops_context {
71 struct persistent_ram_zone **przs; 75 struct persistent_ram_zone **przs;
72 struct persistent_ram_zone *cprz; 76 struct persistent_ram_zone *cprz;
77 struct persistent_ram_zone *fprz;
73 phys_addr_t phys_addr; 78 phys_addr_t phys_addr;
74 unsigned long size; 79 unsigned long size;
75 size_t record_size; 80 size_t record_size;
76 size_t console_size; 81 size_t console_size;
82 size_t ftrace_size;
77 int dump_oops; 83 int dump_oops;
78 int ecc_size; 84 int ecc_size;
79 unsigned int max_dump_cnt; 85 unsigned int max_dump_cnt;
80 unsigned int dump_write_cnt; 86 unsigned int dump_write_cnt;
81 unsigned int dump_read_cnt; 87 unsigned int dump_read_cnt;
82 unsigned int console_read_cnt; 88 unsigned int console_read_cnt;
89 unsigned int ftrace_read_cnt;
83 struct pstore_info pstore; 90 struct pstore_info pstore;
84}; 91};
85 92
@@ -138,6 +145,9 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
138 prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt, 145 prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
139 1, id, type, PSTORE_TYPE_CONSOLE, 0); 146 1, id, type, PSTORE_TYPE_CONSOLE, 0);
140 if (!prz) 147 if (!prz)
148 prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
149 1, id, type, PSTORE_TYPE_FTRACE, 0);
150 if (!prz)
141 return 0; 151 return 0;
142 152
143 /* TODO(kees): Bogus time for the moment. */ 153 /* TODO(kees): Bogus time for the moment. */
@@ -186,6 +196,11 @@ static int ramoops_pstore_write_buf(enum pstore_type_id type,
186 return -ENOMEM; 196 return -ENOMEM;
187 persistent_ram_write(cxt->cprz, buf, size); 197 persistent_ram_write(cxt->cprz, buf, size);
188 return 0; 198 return 0;
199 } else if (type == PSTORE_TYPE_FTRACE) {
200 if (!cxt->fprz)
201 return -ENOMEM;
202 persistent_ram_write(cxt->fprz, buf, size);
203 return 0;
189 } 204 }
190 205
191 if (type != PSTORE_TYPE_DMESG) 206 if (type != PSTORE_TYPE_DMESG)
@@ -235,6 +250,9 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
235 case PSTORE_TYPE_CONSOLE: 250 case PSTORE_TYPE_CONSOLE:
236 prz = cxt->cprz; 251 prz = cxt->cprz;
237 break; 252 break;
253 case PSTORE_TYPE_FTRACE:
254 prz = cxt->fprz;
255 break;
238 default: 256 default:
239 return -EINVAL; 257 return -EINVAL;
240 } 258 }
@@ -348,7 +366,8 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
348 if (cxt->max_dump_cnt) 366 if (cxt->max_dump_cnt)
349 goto fail_out; 367 goto fail_out;
350 368
351 if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size)) { 369 if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
370 !pdata->ftrace_size)) {
352 pr_err("The memory size and the record/console size must be " 371 pr_err("The memory size and the record/console size must be "
353 "non-zero\n"); 372 "non-zero\n");
354 goto fail_out; 373 goto fail_out;
@@ -357,18 +376,20 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
357 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); 376 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
358 pdata->record_size = rounddown_pow_of_two(pdata->record_size); 377 pdata->record_size = rounddown_pow_of_two(pdata->record_size);
359 pdata->console_size = rounddown_pow_of_two(pdata->console_size); 378 pdata->console_size = rounddown_pow_of_two(pdata->console_size);
379 pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
360 380
361 cxt->dump_read_cnt = 0; 381 cxt->dump_read_cnt = 0;
362 cxt->size = pdata->mem_size; 382 cxt->size = pdata->mem_size;
363 cxt->phys_addr = pdata->mem_address; 383 cxt->phys_addr = pdata->mem_address;
364 cxt->record_size = pdata->record_size; 384 cxt->record_size = pdata->record_size;
365 cxt->console_size = pdata->console_size; 385 cxt->console_size = pdata->console_size;
386 cxt->ftrace_size = pdata->ftrace_size;
366 cxt->dump_oops = pdata->dump_oops; 387 cxt->dump_oops = pdata->dump_oops;
367 cxt->ecc_size = pdata->ecc_size; 388 cxt->ecc_size = pdata->ecc_size;
368 389
369 paddr = cxt->phys_addr; 390 paddr = cxt->phys_addr;
370 391
371 dump_mem_sz = cxt->size - cxt->console_size; 392 dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size;
372 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); 393 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
373 if (err) 394 if (err)
374 goto fail_out; 395 goto fail_out;
@@ -377,9 +398,14 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
377 if (err) 398 if (err)
378 goto fail_init_cprz; 399 goto fail_init_cprz;
379 400
380 if (!cxt->przs && !cxt->cprz) { 401 err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size);
402 if (err)
403 goto fail_init_fprz;
404
405 if (!cxt->przs && !cxt->cprz && !cxt->fprz) {
381 pr_err("memory size too small, minimum is %lu\n", 406 pr_err("memory size too small, minimum is %lu\n",
382 cxt->console_size + cxt->record_size); 407 cxt->console_size + cxt->record_size +
408 cxt->ftrace_size);
383 goto fail_cnt; 409 goto fail_cnt;
384 } 410 }
385 411
@@ -426,6 +452,8 @@ fail_clear:
426 cxt->pstore.bufsize = 0; 452 cxt->pstore.bufsize = 0;
427 cxt->max_dump_cnt = 0; 453 cxt->max_dump_cnt = 0;
428fail_cnt: 454fail_cnt:
455 kfree(cxt->fprz);
456fail_init_fprz:
429 kfree(cxt->cprz); 457 kfree(cxt->cprz);
430fail_init_cprz: 458fail_init_cprz:
431 ramoops_free_przs(cxt); 459 ramoops_free_przs(cxt);
@@ -480,6 +508,7 @@ static void ramoops_register_dummy(void)
480 dummy_data->mem_address = mem_address; 508 dummy_data->mem_address = mem_address;
481 dummy_data->record_size = record_size; 509 dummy_data->record_size = record_size;
482 dummy_data->console_size = ramoops_console_size; 510 dummy_data->console_size = ramoops_console_size;
511 dummy_data->ftrace_size = ramoops_ftrace_size;
483 dummy_data->dump_oops = dump_oops; 512 dummy_data->dump_oops = dump_oops;
484 /* 513 /*
485 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC 514 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index dcf805f56bc6..af848e1593b9 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -72,6 +72,7 @@ struct ramoops_platform_data {
72 unsigned long mem_address; 72 unsigned long mem_address;
73 unsigned long record_size; 73 unsigned long record_size;
74 unsigned long console_size; 74 unsigned long console_size;
75 unsigned long ftrace_size;
75 int dump_oops; 76 int dump_oops;
76 int ecc_size; 77 int ecc_size;
77}; 78};