ipmi_si: Only schedule continuously in the thread in maintenance mode
ipmi_thread() uses back-to-back schedule() to poll for command completion which, on some machines, can push up CPU consumption and heavily tax the scheduler locks leading to noticeable overall performance degradation. This was originally added so firmware updates through IPMI would complete in a timely manner. But we can't kill the scheduler locks for that one use case. Instead, only run schedule() continuously in maintenance mode, where firmware updates should run. Signed-off-by: Corey Minyard <cminyard@mvista.com>
This commit is contained in:
parent
93b6984b31
commit
340ff31ab0
|
@ -222,6 +222,9 @@ struct smi_info {
|
||||||
*/
|
*/
|
||||||
bool irq_enable_broken;
|
bool irq_enable_broken;
|
||||||
|
|
||||||
|
/* Is the driver in maintenance mode? */
|
||||||
|
bool in_maintenance_mode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Did we get an attention that we did not handle?
|
* Did we get an attention that we did not handle?
|
||||||
*/
|
*/
|
||||||
|
@ -1008,11 +1011,20 @@ static int ipmi_thread(void *data)
|
||||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||||
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
|
||||||
&busy_until);
|
&busy_until);
|
||||||
if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
|
if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
|
||||||
; /* do nothing */
|
; /* do nothing */
|
||||||
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
|
} else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) {
|
||||||
|
/*
|
||||||
|
* In maintenance mode we run as fast as
|
||||||
|
* possible to allow firmware updates to
|
||||||
|
* complete as fast as possible, but normally
|
||||||
|
* don't bang on the scheduler.
|
||||||
|
*/
|
||||||
|
if (smi_info->in_maintenance_mode)
|
||||||
schedule();
|
schedule();
|
||||||
else if (smi_result == SI_SM_IDLE) {
|
else
|
||||||
|
usleep_range(100, 200);
|
||||||
|
} else if (smi_result == SI_SM_IDLE) {
|
||||||
if (atomic_read(&smi_info->need_watch)) {
|
if (atomic_read(&smi_info->need_watch)) {
|
||||||
schedule_timeout_interruptible(100);
|
schedule_timeout_interruptible(100);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1020,9 +1032,10 @@ static int ipmi_thread(void *data)
|
||||||
__set_current_state(TASK_INTERRUPTIBLE);
|
__set_current_state(TASK_INTERRUPTIBLE);
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
schedule_timeout_interruptible(1);
|
schedule_timeout_interruptible(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1199,6 +1212,7 @@ static void set_maintenance_mode(void *send_info, bool enable)
|
||||||
|
|
||||||
if (!enable)
|
if (!enable)
|
||||||
atomic_set(&smi_info->req_events, 0);
|
atomic_set(&smi_info->req_events, 0);
|
||||||
|
smi_info->in_maintenance_mode = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shutdown_smi(void *send_info);
|
static void shutdown_smi(void *send_info);
|
||||||
|
|
Loading…
Reference in New Issue