Problem with IPMI KCS driver

John Baldwin jhb at freebsd.org
Wed Aug 29 12:25:49 UTC 2012


On Wednesday, August 29, 2012 5:36:43 am Anton Yuzhaninov wrote:
> We use servers witch motherboard Supermicro X8DTT-H and meet with such problem:
> when watchdogd started, server is rebooted by IPMI watchdog several times per week.
> 
> After some debugging I've found, that sometimes IPMI driver entered endless 
> loop, and watchdogd have no chances to reset watchdog timer.
> In such situation top show:
> 
> PID USERNAME      PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
> ...
> 113 root          -16    -     0K    16K CPU4    4  17:18 99.17% ipmi0: kcs
> 
> Endless loop located in file /sys/dev/ipmi/ipmi_kcs.c and function 
> kcs_wait_for_obf():
> 
>          int status, start = ticks;
> 
>          status = INB(sc, KCS_CTL_STS);
>          if (state == 0) {
>                  /* WAIT FOR OBF = 0 */
>                  while (ticks - start < MAX_TIMEOUT && status & KCS_STATUS_OBF) {
>                          DELAY(100);
>                          status = INB(sc, KCS_CTL_STS);
>                  }
>          } else {
>                  /* WAIT FOR OBF = 1 */
>                  while (ticks - start < MAX_TIMEOUT &&
>                      !(status & KCS_STATUS_OBF)) {
>                          DELAY(100);
>                          status = INB(sc, KCS_CTL_STS);
>                  }
>          }
> 
> It seems to be, that this loop intended to run no more than MAX_TIMEOUT ticks.
> but by some reason this timeout does not works and loop runs until reboot.
> 
> Questions:
> 1. Is it correct to check ticks to implement timeout here?
> 2. how to fix this timeout?

Hmm.  Can you try this:

Index: kern/kern_clock.c
===================================================================
--- kern/kern_clock.c	(revision 239819)
+++ kern/kern_clock.c	(working copy)
@@ -382,7 +382,7 @@
 int	stathz;
 int	profhz;
 int	profprocs;
-int	ticks;
+volatile int	ticks;
 int	psratio;
 
 static DPCPU_DEFINE(int, pcputicks);	/* Per-CPU version of ticks. */
@@ -469,7 +469,7 @@
 hardclock(int usermode, uintfptr_t pc)
 {
 
-	atomic_add_int((volatile int *)&ticks, 1);
+	atomic_add_int(&ticks, 1);
 	hardclock_cpu(usermode);
 	tc_ticktock(1);
 	cpu_tick_calibration();
Index: sys/kernel.h
===================================================================
--- sys/kernel.h	(revision 239819)
+++ sys/kernel.h	(working copy)
@@ -63,7 +63,7 @@
 extern int stathz;			/* statistics clock's frequency */
 extern int profhz;			/* profiling clock's frequency */
 extern int profprocs;			/* number of process's profiling */
-extern int ticks;
+extern volatile int ticks;
 
 #endif /* _KERNEL */
 

-- 
John Baldwin


More information about the freebsd-stable mailing list