diff options
author | Michael Holzheu <holzheu@de.ibm.com> | 2005-09-03 18:57:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:26 -0400 |
commit | 942eaabd5d77522223a311ed9bddaaa3cefde27d (patch) | |
tree | 2b16d5c788d79d9670b3b816851ae0c8a4ef0ef2 | |
parent | ae6aa2ea8973e200cb3d0564a64a1b441d233428 (diff) |
[PATCH] s390: debug feature changes
debug feature changes/bug fixes:
- Use get_clock() function instead of private inline assembly.
- Use 'struct timeval' instead of 'struct timespec' for call to
tod_to_timeval(). Now the microsecond part of the timestamp is correct
again.
- Fix a locking problem: when creating a snapshot of the current content
of the debug areas, lock the entire debug_info object.
Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/s390/kernel/debug.c | 52 | ||||
-rw-r--r-- | include/asm-s390/debug.h | 2 |
2 files changed, 32 insertions, 22 deletions
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 960ba6029c3a..bc59282da762 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -62,7 +62,7 @@ typedef struct | |||
62 | } debug_sprintf_entry_t; | 62 | } debug_sprintf_entry_t; |
63 | 63 | ||
64 | 64 | ||
65 | extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); | 65 | extern void tod_to_timeval(uint64_t todval, struct timespec *xtime); |
66 | 66 | ||
67 | /* internal function prototyes */ | 67 | /* internal function prototyes */ |
68 | 68 | ||
@@ -374,9 +374,24 @@ debug_info_copy(debug_info_t* in, int mode) | |||
374 | { | 374 | { |
375 | int i,j; | 375 | int i,j; |
376 | debug_info_t* rc; | 376 | debug_info_t* rc; |
377 | unsigned long flags; | ||
378 | |||
379 | /* get a consistent copy of the debug areas */ | ||
380 | do { | ||
381 | rc = debug_info_alloc(in->name, in->pages_per_area, | ||
382 | in->nr_areas, in->buf_size, in->level, mode); | ||
383 | spin_lock_irqsave(&in->lock, flags); | ||
384 | if(!rc) | ||
385 | goto out; | ||
386 | /* has something changed in the meantime ? */ | ||
387 | if((rc->pages_per_area == in->pages_per_area) && | ||
388 | (rc->nr_areas == in->nr_areas)) { | ||
389 | break; | ||
390 | } | ||
391 | spin_unlock_irqrestore(&in->lock, flags); | ||
392 | debug_info_free(rc); | ||
393 | } while (1); | ||
377 | 394 | ||
378 | rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas, | ||
379 | in->buf_size, in->level, mode); | ||
380 | if(!rc || (mode == NO_AREAS)) | 395 | if(!rc || (mode == NO_AREAS)) |
381 | goto out; | 396 | goto out; |
382 | 397 | ||
@@ -386,6 +401,7 @@ debug_info_copy(debug_info_t* in, int mode) | |||
386 | } | 401 | } |
387 | } | 402 | } |
388 | out: | 403 | out: |
404 | spin_unlock_irqrestore(&in->lock, flags); | ||
389 | return rc; | 405 | return rc; |
390 | } | 406 | } |
391 | 407 | ||
@@ -593,19 +609,15 @@ debug_open(struct inode *inode, struct file *file) | |||
593 | debug_info_t *debug_info, *debug_info_snapshot; | 609 | debug_info_t *debug_info, *debug_info_snapshot; |
594 | 610 | ||
595 | down(&debug_lock); | 611 | down(&debug_lock); |
596 | 612 | debug_info = (struct debug_info*)file->f_dentry->d_inode->u.generic_ip; | |
597 | /* find debug log and view */ | 613 | /* find debug view */ |
598 | debug_info = debug_area_first; | 614 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
599 | while(debug_info != NULL){ | 615 | if (!debug_info->views[i]) |
600 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 616 | continue; |
601 | if (!debug_info->views[i]) | 617 | else if (debug_info->debugfs_entries[i] == |
602 | continue; | 618 | file->f_dentry) { |
603 | else if (debug_info->debugfs_entries[i] == | 619 | goto found; /* found view ! */ |
604 | file->f_dentry) { | ||
605 | goto found; /* found view ! */ | ||
606 | } | ||
607 | } | 620 | } |
608 | debug_info = debug_info->next; | ||
609 | } | 621 | } |
610 | /* no entry found */ | 622 | /* no entry found */ |
611 | rc = -EINVAL; | 623 | rc = -EINVAL; |
@@ -833,7 +845,7 @@ extern inline void | |||
833 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, | 845 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, |
834 | int exception) | 846 | int exception) |
835 | { | 847 | { |
836 | STCK(active->id.stck); | 848 | active->id.stck = get_clock(); |
837 | active->id.fields.cpuid = smp_processor_id(); | 849 | active->id.fields.cpuid = smp_processor_id(); |
838 | active->caller = __builtin_return_address(0); | 850 | active->caller = __builtin_return_address(0); |
839 | active->id.fields.exception = exception; | 851 | active->id.fields.exception = exception; |
@@ -1078,7 +1090,7 @@ debug_register_view(debug_info_t * id, struct debug_view *view) | |||
1078 | if (view->input_proc) | 1090 | if (view->input_proc) |
1079 | mode |= S_IWUSR; | 1091 | mode |= S_IWUSR; |
1080 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, | 1092 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, |
1081 | NULL, &debug_file_ops); | 1093 | id , &debug_file_ops); |
1082 | if (!pde){ | 1094 | if (!pde){ |
1083 | printk(KERN_WARNING "debug: debugfs_create_file() failed!"\ | 1095 | printk(KERN_WARNING "debug: debugfs_create_file() failed!"\ |
1084 | " Cannot register view %s/%s\n", id->name,view->name); | 1096 | " Cannot register view %s/%s\n", id->name,view->name); |
@@ -1432,7 +1444,7 @@ int | |||
1432 | debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | 1444 | debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, |
1433 | int area, debug_entry_t * entry, char *out_buf) | 1445 | int area, debug_entry_t * entry, char *out_buf) |
1434 | { | 1446 | { |
1435 | struct timeval time_val; | 1447 | struct timespec time_spec; |
1436 | unsigned long long time; | 1448 | unsigned long long time; |
1437 | char *except_str; | 1449 | char *except_str; |
1438 | unsigned long caller; | 1450 | unsigned long caller; |
@@ -1443,7 +1455,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
1443 | time = entry->id.stck; | 1455 | time = entry->id.stck; |
1444 | /* adjust todclock to 1970 */ | 1456 | /* adjust todclock to 1970 */ |
1445 | time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); | 1457 | time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); |
1446 | tod_to_timeval(time, &time_val); | 1458 | tod_to_timeval(time, &time_spec); |
1447 | 1459 | ||
1448 | if (entry->id.fields.exception) | 1460 | if (entry->id.fields.exception) |
1449 | except_str = "*"; | 1461 | except_str = "*"; |
@@ -1451,7 +1463,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
1451 | except_str = "-"; | 1463 | except_str = "-"; |
1452 | caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; | 1464 | caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; |
1453 | rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ", | 1465 | rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ", |
1454 | area, time_val.tv_sec, time_val.tv_usec, level, | 1466 | area, time_spec.tv_sec, time_spec.tv_nsec / 1000, level, |
1455 | except_str, entry->id.fields.cpuid, (void *) caller); | 1467 | except_str, entry->id.fields.cpuid, (void *) caller); |
1456 | return rc; | 1468 | return rc; |
1457 | } | 1469 | } |
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 92360d90144b..7127030ae162 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h | |||
@@ -52,8 +52,6 @@ struct __debug_entry{ | |||
52 | #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */ | 52 | #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */ |
53 | /* the entry information */ | 53 | /* the entry information */ |
54 | 54 | ||
55 | #define STCK(x) asm volatile ("STCK 0(%1)" : "=m" (x) : "a" (&(x)) : "cc") | ||
56 | |||
57 | typedef struct __debug_entry debug_entry_t; | 55 | typedef struct __debug_entry debug_entry_t; |
58 | 56 | ||
59 | struct debug_view; | 57 | struct debug_view; |