summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris Cain <cjcain@us.ibm.com>2017-11-21 19:21:16 -0600
committerChristopher J. Cain <cjcain@us.ibm.com>2017-12-01 16:07:38 -0500
commit06ef7787e76281b40fb961048bc79b22610241a0 (patch)
tree35f959645c4c6eb180070bec907d96ad9dc55019 /src
parentd0f8e5fb2c5a2cd78453630e869d74d569cad394 (diff)
downloadtalos-occ-06ef7787e76281b40fb961048bc79b22610241a0.tar.gz
talos-occ-06ef7787e76281b40fb961048bc79b22610241a0.zip
Handle redundant power supply policy
When redundant power supply policy is disabled: 1. Skip power capping algorithm when in oversubscription 2. No power brake support (don't set the GPIO to enable the automatic HW power braking) 3. Remove clipping to turbo when in oversubscription Initialize frequency votes to prevent throttling when booted in oversubscription. Allow truncated exception buffer data to be parsed. Change-Id: I4fef673feb0a3d0025e00d8fd219cf4cc24d8685 CQ: SW408974 CQ: SW409666 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50071 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: Andres A. Lugo-Reyes <aalugore@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/occ_405/amec/amec_freq.c37
-rw-r--r--src/occ_405/amec/amec_init.c4
-rwxr-xr-xsrc/occ_405/amec/amec_pcap.c84
-rwxr-xr-xsrc/occ_405/cmdh/cmdh_fsp_cmds.c21
-rwxr-xr-xsrc/occ_405/gpu/gpu.c8
-rwxr-xr-xsrc/occ_405/occ_sys_config.h3
-rwxr-xr-xsrc/occ_405/occbuildname.c2
-rw-r--r--src/tools/ffdcparser/ffdcparser.c25
8 files changed, 98 insertions, 86 deletions
diff --git a/src/occ_405/amec/amec_freq.c b/src/occ_405/amec/amec_freq.c
index 7b02ba7..d1e8aad 100755
--- a/src/occ_405/amec/amec_freq.c
+++ b/src/occ_405/amec/amec_freq.c
@@ -156,26 +156,31 @@ errlHndl_t amec_set_freq_range(const OCC_MODE i_mode)
}
}
- // check if need to lower max frequency due to being in oversubscription. 0 oversub freq means no freq limitation
- if( AMEC_INTF_GET_OVERSUBSCRIPTION() && (G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB]) &&
- (G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB] < l_freq_max) )
+ // if (redundant ps policy is being enforced)
+ if (G_sysConfigData.system_type.non_redund_ps == false)
{
- // If oversub is lower than system minimum then set to min
- if(G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB] < l_freq_min)
+ // OVERSUB is actually TURBO
+ // check if need to lower max frequency due to being in oversubscription. 0 oversub freq means no freq limitation
+ if( AMEC_INTF_GET_OVERSUBSCRIPTION() && (G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB]) &&
+ (G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB] < l_freq_max) )
{
- TRAC_IMP("amec_set_freq_range: max frequency lowered from %u to system min %u due to oversubscription",
- l_freq_max,
- l_freq_min);
+ // If oversub is lower than system minimum then set to min
+ if(G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB] < l_freq_min)
+ {
+ TRAC_IMP("amec_set_freq_range: max frequency lowered from %u to system min %u due to oversubscription",
+ l_freq_max,
+ l_freq_min);
- l_freq_max = l_freq_min;
- }
- else
- {
- TRAC_IMP("amec_set_freq_range: max frequency lowered from %u to %u due to Oversubscription",
- l_freq_max,
- G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB]);
+ l_freq_max = l_freq_min;
+ }
+ else
+ {
+ TRAC_IMP("amec_set_freq_range: max frequency lowered from %u to %u due to Oversubscription",
+ l_freq_max,
+ G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB]);
- l_freq_max = G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB];
+ l_freq_max = G_sysConfigData.sys_mode_freq.table[OCC_MODE_OVERSUB];
+ }
}
}
diff --git a/src/occ_405/amec/amec_init.c b/src/occ_405/amec/amec_init.c
index 4ba89fc..e6c40f2 100644
--- a/src/occ_405/amec/amec_init.c
+++ b/src/occ_405/amec/amec_init.c
@@ -291,6 +291,10 @@ void amec_init_gamec_struct(void)
//Initialize processor power votes
g_amec->proc[0].pwr_votes.pmax_clip_freq = 0xFFFF;
g_amec->proc[0].pwr_votes.apss_pmax_clip_freq = 0xFFFF;
+ g_amec->proc[0].pwr_votes.proc_pcap_nom_vote = 0xFFFF;
+ g_amec->proc[0].pwr_votes.proc_pcap_vote = 0xFFFF;
+ g_amec->proc[0].pwr_votes.ppb_fmax = 0xFFFF;
+ g_amec->proc[0].pwr_votes.nom_pcap_fmin = 0;
//Initialize stream buffer recording parameters
g_amec->recordflag=0; // Never enable recording until requested via Amester API call
diff --git a/src/occ_405/amec/amec_pcap.c b/src/occ_405/amec/amec_pcap.c
index 531c738..caf8419 100755
--- a/src/occ_405/amec/amec_pcap.c
+++ b/src/occ_405/amec/amec_pcap.c
@@ -327,12 +327,8 @@ void amec_gpu_pcap(bool i_oversubscription, bool i_active_pcap_changed, int32_t
// Thread: Real Time Loop
//
// End Function Specification
-void amec_pcap_calc(void)
+void amec_pcap_calc(const bool i_oversub_state)
{
- /*------------------------------------------------------------------------*/
- /* Local Variables */
- /*------------------------------------------------------------------------*/
- bool l_oversub_state = 0;
bool l_active_pcap_changed = FALSE;
uint16_t l_node_pwr = AMECSENSOR_PTR(PWRSYS)->sample;
uint16_t l_p0_pwr = AMECSENSOR_PTR(PWRPROC)->sample;
@@ -342,17 +338,11 @@ void amec_pcap_calc(void)
static uint32_t L_prev_node_pcap = 0;
static bool L_apss_error_traced = FALSE;
- /*------------------------------------------------------------------------*/
- /* Code */
- /*------------------------------------------------------------------------*/
-
- l_oversub_state = AMEC_INTF_GET_OVERSUBSCRIPTION();
-
// Determine the active power cap. norm_node_pcap is set as lowest
// between sys (N+1 mode) and user in amec_data_write_pcap()
// when in oversub (N mode) only use oversub pcap if lower than norm_node_pcap
// to handle user set power cap lower than the oversub power cap
- if( (TRUE == l_oversub_state) &&
+ if( (TRUE == i_oversub_state) &&
(g_amec->pcap.ovs_node_pcap < g_amec->pcap.norm_node_pcap) )
{
g_amec->pcap.active_node_pcap = g_amec->pcap.ovs_node_pcap;
@@ -379,7 +369,7 @@ void amec_pcap_calc(void)
// Determine GPU power cap if there are GPUs present
if(G_first_proc_gpu_config)
{
- amec_gpu_pcap(l_oversub_state, l_active_pcap_changed, l_avail_power);
+ amec_gpu_pcap(i_oversub_state, l_active_pcap_changed, l_avail_power);
}
if(l_node_pwr != 0)
@@ -617,39 +607,47 @@ void amec_power_control(void)
if(G_pwr_reading_type == PWR_READING_TYPE_APSS)
{
- // Calculate the pcap for the proc, memory and the power capping limit
- // for nominal cores.
- amec_pcap_calc();
+ const bool l_oversub_state = AMEC_INTF_GET_OVERSUBSCRIPTION();
- // skip processor changes until memory is un-capped
- if(!g_amec->pcap.active_mem_level)
- {
- // Calculate voting box input freq for staying with the current pcap
- amec_pcap_controller();
+ // if (power supply policy == redundant) or (not in oversubscription)
+ if ((G_sysConfigData.system_type.non_redund_ps == FALSE) ||
+ (l_oversub_state == FALSE))
+ {
+ // Calculate the pcap for the proc, memory and the power capping limit
+ // for nominal cores.
+ amec_pcap_calc(l_oversub_state);
- // Calculate the performance preserving bounds voting box input freq
- amec_ppb_fmax_calc();
- }
+ // skip processor changes until memory is un-capped
+ if(!g_amec->pcap.active_mem_level)
+ {
+ // Calculate voting box input freq for staying with the current pcap
+ amec_pcap_controller();
- // Update the Processor and Memory Throttle due to power sensors
- if(g_amec->proc[0].pwr_votes.proc_pcap_vote < G_proc_fmax_mhz)
- {
- // Frequency is being throttled due to power cap
- sensor_update(AMECSENSOR_PTR(PROCPWRTHROT), 1);
- }
- else // not currently throttled due to power
- {
- sensor_update(AMECSENSOR_PTR(PROCPWRTHROT), 0);
- }
- if(g_amec->pcap.active_mem_level != 0)
- {
- // Memory is being throttled due to power cap
- sensor_update(AMECSENSOR_PTR(MEMPWRTHROT), 1);
- }
- else // not currently throttled due to power
- {
- sensor_update(AMECSENSOR_PTR(MEMPWRTHROT), 0);
- }
+ // Calculate the performance preserving bounds voting box input freq
+ amec_ppb_fmax_calc();
+ }
+
+ // Update the Processor and Memory Throttle due to power sensors
+ if(g_amec->proc[0].pwr_votes.proc_pcap_vote < G_proc_fmax_mhz)
+ {
+ // Frequency is being throttled due to power cap
+ sensor_update(AMECSENSOR_PTR(PROCPWRTHROT), 1);
+ }
+ else // not currently throttled due to power
+ {
+ sensor_update(AMECSENSOR_PTR(PROCPWRTHROT), 0);
+ }
+ if(g_amec->pcap.active_mem_level != 0)
+ {
+ // Memory is being throttled due to power cap
+ sensor_update(AMECSENSOR_PTR(MEMPWRTHROT), 1);
+ }
+ else // not currently throttled due to power
+ {
+ sensor_update(AMECSENSOR_PTR(MEMPWRTHROT), 0);
+ }
+ }
+ // else, dont run pcap algorithm while: oversubscription AND non-redundant ps
}
else
{
diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c
index f253375..90c6d3b 100755
--- a/src/occ_405/cmdh/cmdh_fsp_cmds.c
+++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c
@@ -611,14 +611,19 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
// OCC can't support power capping without knowing the system power
if(G_pwr_reading_type != PWR_READING_TYPE_NONE)
{
- l_pcapData.current = g_amec->pcap.active_node_pcap;
- l_pcapData.system = G_amec_sensor_list[PWRSYS]->sample;
- l_pcapData.n = G_sysConfigData.pcap.oversub_pcap;
- l_pcapData.max = G_sysConfigData.pcap.max_pcap;
- l_pcapData.hard_min = G_sysConfigData.pcap.hard_min_pcap;
- l_pcapData.soft_min = G_sysConfigData.pcap.soft_min_pcap;
- l_pcapData.user = G_sysConfigData.pcap.current_pcap;
- l_pcapData.source = G_sysConfigData.pcap.source;
+ if ((G_sysConfigData.system_type.non_redund_ps == false) ||
+ (! AMEC_INTF_GET_OVERSUBSCRIPTION()))
+ {
+ l_pcapData.current = g_amec->pcap.active_node_pcap;
+ }
+ // else OCC is not running pcap algorithim so leave current cap as 0
+ l_pcapData.system = G_amec_sensor_list[PWRSYS]->sample;
+ l_pcapData.n = G_sysConfigData.pcap.oversub_pcap;
+ l_pcapData.max = G_sysConfigData.pcap.max_pcap;
+ l_pcapData.hard_min = G_sysConfigData.pcap.hard_min_pcap;
+ l_pcapData.soft_min = G_sysConfigData.pcap.soft_min_pcap;
+ l_pcapData.user = G_sysConfigData.pcap.current_pcap;
+ l_pcapData.source = G_sysConfigData.pcap.source;
}
// Copy header to response buffer.
diff --git a/src/occ_405/gpu/gpu.c b/src/occ_405/gpu/gpu.c
index 9c473b9..72697eb 100755
--- a/src/occ_405/gpu/gpu.c
+++ b/src/occ_405/gpu/gpu.c
@@ -646,8 +646,12 @@ void gpu_ipc_init()
}
else
{
- // gpe gpu init only needs to be done once, so do it here.
- schedule_gpe_gpu_init_req();
+ // if (redundant ps policy is set)
+ if (G_sysConfigData.system_type.non_redund_ps == false)
+ {
+ // gpe gpu init only needs to be done once, so do it here.
+ schedule_gpe_gpu_init_req();
+ }
}
}
diff --git a/src/occ_405/occ_sys_config.h b/src/occ_405/occ_sys_config.h
index 6cfe2b1..a00157e 100755
--- a/src/occ_405/occ_sys_config.h
+++ b/src/occ_405/occ_sys_config.h
@@ -77,7 +77,8 @@ typedef union
uint8_t kvm: 1;
uint8_t reserved: 3;
uint8_t report_dvfs_nom: 1;
- uint8_t reserved_2: 2;
+ uint8_t reserved_2: 1;
+ uint8_t non_redund_ps: 1;
uint8_t single: 1;
};
uint8_t byte;
diff --git a/src/occ_405/occbuildname.c b/src/occ_405/occbuildname.c
index bb0c9f9..c163980 100755
--- a/src/occ_405/occbuildname.c
+++ b/src/occ_405/occbuildname.c
@@ -34,6 +34,6 @@ volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) =
#else
-volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_171115a\0" /*</BuildName>*/ ;
+volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_171129a\0" /*</BuildName>*/ ;
#endif
diff --git a/src/tools/ffdcparser/ffdcparser.c b/src/tools/ffdcparser/ffdcparser.c
index e1bcb59..5fcaaa6 100644
--- a/src/tools/ffdcparser/ffdcparser.c
+++ b/src/tools/ffdcparser/ffdcparser.c
@@ -24,6 +24,7 @@
/* IBM_PROLOG_END_TAG */
#include <stdio.h>
#include <stdint.h>
+#include <sys/stat.h>
// NOTE: This tool is to be used when FFDC is dumped by the OCC, and currently
// only accepts input files in binary format.
@@ -162,18 +163,6 @@ uint16_t get_uint16(FILE* i_fhndl)
return ret;
}
-int file_length_valid(FILE* i_fhndl, uint16_t i_exp_size)
-{
- uint32_t len = 0;
-
- while(EOF != fgetc(i_fhndl))
- {
- len++;
- }
-
- return (len < i_exp_size) ? 0 : 1;
-}
-
void get_thread_data(FILE* i_fhndl, thread_dump_t * i_thrd)
{
uint32_t i = 0;
@@ -297,16 +286,22 @@ int main(int argc, char** argv)
}
}
+ // Get file size
+ fseek(ffdc_file, 0, SEEK_END);
+ const unsigned int file_size = ftell(ffdc_file);
+ fseek(ffdc_file, 0, SEEK_SET);
+
// Binary file is open, parse it
data.seq = fgetc(ffdc_file);
data.cmd = fgetc(ffdc_file);
data.excp = fgetc(ffdc_file);
data.len = get_uint16(ffdc_file);
- if( (!file_length_valid(ffdc_file, data.len)) )
+ if (file_size < data.len)
{
- fprintf(stderr, "ERROR: FFDC file not valid size\n");
- return -1;
+ fprintf(stderr, "WARNING: FFDC file size (%d) is less than what was expected (%d)\n",
+ file_size, data.len);
+ // fgetc will continue to return 0xFF once the end of file is reached
}
if(fseek(ffdc_file, 5, SEEK_SET))
OpenPOWER on IntegriCloud