aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/debug')
-rw-r--r--kernel/debug/kdb/kdb_io.c30
-rw-r--r--kernel/debug/kdb/kdb_private.h1
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