Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318020
b: refs/heads/master
c: a694d1b
h: refs/heads/master
v: v3
  • Loading branch information
Anton Vorontsov authored and Greg Kroah-Hartman committed Jul 17, 2012
1 parent 148e46b commit 16c5f82
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c2b7113261c5bb49031a15b833e59ea2d8ec4074
refs/heads/master: a694d1b5916a486ce25fb5f2b39f2627f7afd5f3
25 changes: 25 additions & 0 deletions trunk/Documentation/ramoops.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,28 @@ timestamp and a new line. The dump then continues with the actual data.
The dump data can be read from the pstore filesystem. The format for these
files is "dmesg-ramoops-N", where N is the record number in memory. To delete
a stored record from RAM, simply unlink the respective pstore file.

5. Persistent function tracing

Persistent function tracing might be useful for debugging software or hardware
related hangs. The functions call chain log is stored in a "ftrace-ramoops"
file. Here is an example of usage:

# mount -t debugfs debugfs /sys/kernel/debug/
# cd /sys/kernel/debug/tracing
# echo function > current_tracer
# echo 1 > options/func_pstore
# reboot -f
[...]
# mount -t pstore pstore /mnt/
# tail /mnt/ftrace-ramoops
0 ffffffff8101ea64 ffffffff8101bcda native_apic_mem_read <- disconnect_bsp_APIC+0x6a/0xc0
0 ffffffff8101ea44 ffffffff8101bcf6 native_apic_mem_write <- disconnect_bsp_APIC+0x86/0xc0
0 ffffffff81020084 ffffffff8101a4b5 hpet_disable <- native_machine_shutdown+0x75/0x90
0 ffffffff81005f94 ffffffff8101a4bb iommu_shutdown_noop <- native_machine_shutdown+0x7b/0x90
0 ffffffff8101a6a1 ffffffff8101a437 native_machine_emergency_restart <- native_machine_restart+0x37/0x40
0 ffffffff811f9876 ffffffff8101a73a acpi_reboot <- native_machine_emergency_restart+0xaa/0x1e0
0 ffffffff8101a514 ffffffff8101a772 mach_reboot_fixups <- native_machine_emergency_restart+0xe2/0x1e0
0 ffffffff811d9c54 ffffffff8101a7a0 __const_udelay <- native_machine_emergency_restart+0x110/0x1e0
0 ffffffff811d9c34 ffffffff811d9c80 __delay <- __const_udelay+0x30/0x40
0 ffffffff811d9d14 ffffffff811d9c3f delay_tsc <- __delay+0xf/0x20
37 changes: 33 additions & 4 deletions trunk/fs/pstore/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ static ulong ramoops_console_size = MIN_MEM_SIZE;
module_param_named(console_size, ramoops_console_size, ulong, 0400);
MODULE_PARM_DESC(console_size, "size of kernel console log");

static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
MODULE_PARM_DESC(ftrace_size, "size of ftrace log");

static ulong mem_address;
module_param(mem_address, ulong, 0400);
MODULE_PARM_DESC(mem_address,
Expand All @@ -70,16 +74,19 @@ MODULE_PARM_DESC(ramoops_ecc,
struct ramoops_context {
struct persistent_ram_zone **przs;
struct persistent_ram_zone *cprz;
struct persistent_ram_zone *fprz;
phys_addr_t phys_addr;
unsigned long size;
size_t record_size;
size_t console_size;
size_t ftrace_size;
int dump_oops;
int ecc_size;
unsigned int max_dump_cnt;
unsigned int dump_write_cnt;
unsigned int dump_read_cnt;
unsigned int console_read_cnt;
unsigned int ftrace_read_cnt;
struct pstore_info pstore;
};

Expand Down Expand Up @@ -137,6 +144,9 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
if (!prz)
prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
1, id, type, PSTORE_TYPE_CONSOLE, 0);
if (!prz)
prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
1, id, type, PSTORE_TYPE_FTRACE, 0);
if (!prz)
return 0;

Expand Down Expand Up @@ -186,6 +196,11 @@ static int ramoops_pstore_write_buf(enum pstore_type_id type,
return -ENOMEM;
persistent_ram_write(cxt->cprz, buf, size);
return 0;
} else if (type == PSTORE_TYPE_FTRACE) {
if (!cxt->fprz)
return -ENOMEM;
persistent_ram_write(cxt->fprz, buf, size);
return 0;
}

if (type != PSTORE_TYPE_DMESG)
Expand Down Expand Up @@ -235,6 +250,9 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
case PSTORE_TYPE_CONSOLE:
prz = cxt->cprz;
break;
case PSTORE_TYPE_FTRACE:
prz = cxt->fprz;
break;
default:
return -EINVAL;
}
Expand Down Expand Up @@ -348,7 +366,8 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
if (cxt->max_dump_cnt)
goto fail_out;

if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size)) {
if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
!pdata->ftrace_size)) {
pr_err("The memory size and the record/console size must be "
"non-zero\n");
goto fail_out;
Expand All @@ -357,18 +376,20 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
pdata->record_size = rounddown_pow_of_two(pdata->record_size);
pdata->console_size = rounddown_pow_of_two(pdata->console_size);
pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);

cxt->dump_read_cnt = 0;
cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address;
cxt->record_size = pdata->record_size;
cxt->console_size = pdata->console_size;
cxt->ftrace_size = pdata->ftrace_size;
cxt->dump_oops = pdata->dump_oops;
cxt->ecc_size = pdata->ecc_size;

paddr = cxt->phys_addr;

dump_mem_sz = cxt->size - cxt->console_size;
dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size;
err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
if (err)
goto fail_out;
Expand All @@ -377,9 +398,14 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
if (err)
goto fail_init_cprz;

if (!cxt->przs && !cxt->cprz) {
err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size);
if (err)
goto fail_init_fprz;

if (!cxt->przs && !cxt->cprz && !cxt->fprz) {
pr_err("memory size too small, minimum is %lu\n",
cxt->console_size + cxt->record_size);
cxt->console_size + cxt->record_size +
cxt->ftrace_size);
goto fail_cnt;
}

Expand Down Expand Up @@ -426,6 +452,8 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
cxt->pstore.bufsize = 0;
cxt->max_dump_cnt = 0;
fail_cnt:
kfree(cxt->fprz);
fail_init_fprz:
kfree(cxt->cprz);
fail_init_cprz:
ramoops_free_przs(cxt);
Expand Down Expand Up @@ -480,6 +508,7 @@ static void ramoops_register_dummy(void)
dummy_data->mem_address = mem_address;
dummy_data->record_size = record_size;
dummy_data->console_size = ramoops_console_size;
dummy_data->ftrace_size = ramoops_ftrace_size;
dummy_data->dump_oops = dump_oops;
/*
* For backwards compatibility ramoops.ecc=1 means 16 bytes ECC
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/pstore_ram.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct ramoops_platform_data {
unsigned long mem_address;
unsigned long record_size;
unsigned long console_size;
unsigned long ftrace_size;
int dump_oops;
int ecc_size;
};
Expand Down

0 comments on commit 16c5f82

Please sign in to comment.