diff options
author | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-07-09 20:10:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-17 13:14:17 -0400 |
commit | a694d1b5916a486ce25fb5f2b39f2627f7afd5f3 (patch) | |
tree | 541a95c58880019cffe90c79a9468746893caa0d /fs/pstore/ram.c | |
parent | c2b7113261c5bb49031a15b833e59ea2d8ec4074 (diff) |
pstore/ram: Add ftrace messages handling
The ftrace log size is configurable via ramoops.ftrace_size
module option, and the log itself is available via
<pstore-mount>/ftrace-ramoops file.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r-- | fs/pstore/ram.c | 37 |
1 files changed, 33 insertions, 4 deletions
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; | |||
45 | module_param_named(console_size, ramoops_console_size, ulong, 0400); | 45 | module_param_named(console_size, ramoops_console_size, ulong, 0400); |
46 | MODULE_PARM_DESC(console_size, "size of kernel console log"); | 46 | MODULE_PARM_DESC(console_size, "size of kernel console log"); |
47 | 47 | ||
48 | static ulong ramoops_ftrace_size = MIN_MEM_SIZE; | ||
49 | module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400); | ||
50 | MODULE_PARM_DESC(ftrace_size, "size of ftrace log"); | ||
51 | |||
48 | static ulong mem_address; | 52 | static ulong mem_address; |
49 | module_param(mem_address, ulong, 0400); | 53 | module_param(mem_address, ulong, 0400); |
50 | MODULE_PARM_DESC(mem_address, | 54 | MODULE_PARM_DESC(mem_address, |
@@ -70,16 +74,19 @@ MODULE_PARM_DESC(ramoops_ecc, | |||
70 | struct ramoops_context { | 74 | struct 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; |
428 | fail_cnt: | 454 | fail_cnt: |
455 | kfree(cxt->fprz); | ||
456 | fail_init_fprz: | ||
429 | kfree(cxt->cprz); | 457 | kfree(cxt->cprz); |
430 | fail_init_cprz: | 458 | fail_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 |