diff options
Diffstat (limited to 'kernel/debug')
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 30 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_private.h | 1 |
2 files changed, 13 insertions, 18 deletions
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 46f477bebe0c..daa76154fb1b 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
| @@ -555,16 +555,16 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) | |||
| 555 | int colcount; | 555 | int colcount; |
| 556 | int logging, saved_loglevel = 0; | 556 | int logging, saved_loglevel = 0; |
| 557 | int saved_trap_printk; | 557 | int saved_trap_printk; |
| 558 | int got_printf_lock = 0; | ||
| 559 | int retlen = 0; | 558 | int retlen = 0; |
| 560 | int fnd, len; | 559 | int fnd, len; |
| 560 | int this_cpu, old_cpu; | ||
| 561 | static int kdb_printf_cpu = -1; | ||
| 561 | char *cp, *cp2, *cphold = NULL, replaced_byte = ' '; | 562 | char *cp, *cp2, *cphold = NULL, replaced_byte = ' '; |
| 562 | char *moreprompt = "more> "; | 563 | char *moreprompt = "more> "; |
| 563 | struct console *c = console_drivers; | 564 | struct console *c = console_drivers; |
| 564 | static DEFINE_SPINLOCK(kdb_printf_lock); | ||
| 565 | unsigned long uninitialized_var(flags); | 565 | unsigned long uninitialized_var(flags); |
| 566 | 566 | ||
| 567 | preempt_disable(); | 567 | local_irq_save(flags); |
| 568 | saved_trap_printk = kdb_trap_printk; | 568 | saved_trap_printk = kdb_trap_printk; |
| 569 | kdb_trap_printk = 0; | 569 | kdb_trap_printk = 0; |
| 570 | 570 | ||
| @@ -572,12 +572,13 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) | |||
| 572 | * But if any cpu goes recursive in kdb, just print the output, | 572 | * But if any cpu goes recursive in kdb, just print the output, |
| 573 | * even if it is interleaved with any other text. | 573 | * even if it is interleaved with any other text. |
| 574 | */ | 574 | */ |
| 575 | if (!KDB_STATE(PRINTF_LOCK)) { | 575 | this_cpu = smp_processor_id(); |
| 576 | KDB_STATE_SET(PRINTF_LOCK); | 576 | for (;;) { |
| 577 | spin_lock_irqsave(&kdb_printf_lock, flags); | 577 | old_cpu = cmpxchg(&kdb_printf_cpu, -1, this_cpu); |
| 578 | got_printf_lock = 1; | 578 | if (old_cpu == -1 || old_cpu == this_cpu) |
| 579 | } else { | 579 | break; |
| 580 | __acquire(kdb_printf_lock); | 580 | |
| 581 | cpu_relax(); | ||
| 581 | } | 582 | } |
| 582 | 583 | ||
| 583 | diag = kdbgetintenv("LINES", &linecount); | 584 | diag = kdbgetintenv("LINES", &linecount); |
| @@ -846,15 +847,10 @@ kdb_print_out: | |||
| 846 | suspend_grep = 0; /* end of what may have been a recursive call */ | 847 | suspend_grep = 0; /* end of what may have been a recursive call */ |
| 847 | if (logging) | 848 | if (logging) |
| 848 | console_loglevel = saved_loglevel; | 849 | console_loglevel = saved_loglevel; |
| 849 | if (KDB_STATE(PRINTF_LOCK) && got_printf_lock) { | 850 | /* kdb_printf_cpu locked the code above. */ |
| 850 | got_printf_lock = 0; | 851 | smp_store_release(&kdb_printf_cpu, old_cpu); |
| 851 | spin_unlock_irqrestore(&kdb_printf_lock, flags); | ||
| 852 | KDB_STATE_CLEAR(PRINTF_LOCK); | ||
| 853 | } else { | ||
| 854 | __release(kdb_printf_lock); | ||
| 855 | } | ||
| 856 | kdb_trap_printk = saved_trap_printk; | 852 | kdb_trap_printk = saved_trap_printk; |
| 857 | preempt_enable(); | 853 | local_irq_restore(flags); |
| 858 | return retlen; | 854 | return retlen; |
| 859 | } | 855 | } |
| 860 | 856 | ||
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 75014d7f4568..fc224fbcf954 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
| @@ -132,7 +132,6 @@ extern int kdb_state; | |||
| 132 | #define KDB_STATE_PAGER 0x00000400 /* pager is available */ | 132 | #define KDB_STATE_PAGER 0x00000400 /* pager is available */ |
| 133 | #define KDB_STATE_GO_SWITCH 0x00000800 /* go is switching | 133 | #define KDB_STATE_GO_SWITCH 0x00000800 /* go is switching |
| 134 | * back to initial cpu */ | 134 | * back to initial cpu */ |
| 135 | #define KDB_STATE_PRINTF_LOCK 0x00001000 /* Holds kdb_printf lock */ | ||
| 136 | #define KDB_STATE_WAIT_IPI 0x00002000 /* Waiting for kdb_ipi() NMI */ | 135 | #define KDB_STATE_WAIT_IPI 0x00002000 /* Waiting for kdb_ipi() NMI */ |
| 137 | #define KDB_STATE_RECURSE 0x00004000 /* Recursive entry to kdb */ | 136 | #define KDB_STATE_RECURSE 0x00004000 /* Recursive entry to kdb */ |
| 138 | #define KDB_STATE_IP_ADJUSTED 0x00008000 /* Restart IP has been | 137 | #define KDB_STATE_IP_ADJUSTED 0x00008000 /* Restart IP has been |
