aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@de.ibm.com>2005-09-03 18:57:58 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:26 -0400
commit942eaabd5d77522223a311ed9bddaaa3cefde27d (patch)
tree2b16d5c788d79d9670b3b816851ae0c8a4ef0ef2 /arch
parentae6aa2ea8973e200cb3d0564a64a1b441d233428 (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>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/debug.c52
1 files changed, 32 insertions, 20 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
65extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); 65extern 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 }
388out: 403out:
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
833debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, 845debug_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
1432debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, 1444debug_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}