[Skiboot] [PATCH 1/2] fast-reboot: occ: Remove 'freq-domain-mask' from fast-reboot path
Shilpasri G Bhat
shilpa.bhat at linux.vnet.ibm.com
Wed Mar 6 20:23:18 AEDT 2019
OCC can change the pstate table at runtime to modify pstate limits or
for characterization purpose. These changes are reflected by re-parsing
the pstate table during fast-reboot to update the device-tree. Only
relevant pstate DT properties are deleted and newly added during
fast-reboot. The device-tree properties like 'freq-domain-mask' and
'domain-runs-at' are currently hard-coded and need not be updated
during fast-reboot. So this patch removes them from the fast-reboot path.
This patch fixes the below crash:
[ 270.313998453,5] OCC: All Chip Rdy after 0 ms
[ 270.314148918,3] Duplicate property "freq-domain-mask" in node /ibm,opal/power-mgt
[ 270.314208553,0] Aborting!
CPU 083c Backtrace:
S: 0000000035de3a20 R: 000000003001b480 ._abort+0x4c
S: 0000000035de3aa0 R: 0000000030028704 .new_property+0xd8
S: 0000000035de3b30 R: 0000000030028964 .__dt_add_property_cells+0x30
S: 0000000035de3bd0 R: 0000000030042980 .occ_pstates_init+0x7c8
S: 0000000035de3d90 R: 00000000300145f4 .load_and_boot_kernel+0x980
S: 0000000035de3e70 R: 00000000300276b4 .fast_reboot_entry+0x37c
S: 0000000035de3f00 R: 0000000030002ac4 reset_fast_reboot_wakeup+0x40
Fixes: b821f8c2a8e3("power-mgmt : occ : Add 'freq-domain-mask' DT property")
Reported-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
hw/occ.c | 85 ++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 42 insertions(+), 43 deletions(-)
diff --git a/hw/occ.c b/hw/occ.c
index 9af0338..5dc05d3 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -491,27 +491,18 @@ static void parse_vid(struct occ_pstate_table *occ_data,
/* Add device tree properties to describe pstates states */
/* Return nominal pstate to set in each core */
-static bool add_cpu_pstate_properties(int *pstate_nom)
+static bool add_cpu_pstate_properties(struct dt_node *power_mgt,
+ int *pstate_nom)
{
struct proc_chip *chip;
uint64_t occ_data_area;
struct occ_pstate_table *occ_data;
- struct dt_node *power_mgt;
/* Arrays for device tree */
u32 *dt_id, *dt_freq;
int pmax, pmin, pnom;
u8 nr_pstates;
bool ultra_turbo_supported;
int i, major, minor;
- u8 domain_runs_at;
- u32 freq_domain_mask;
-
- /* TODO Firmware plumbing required so as to have two modes to set
- * PMCR based on max in domain or most recently used. As of today,
- * it is always max in domain for P9.
- */
- domain_runs_at = 0;
- freq_domain_mask = 0;
prlog(PR_DEBUG, "OCC: CPU pstate state device tree init\n");
@@ -654,18 +645,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
return false;
}
- power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
- if (!power_mgt) {
- /**
- * @fwts-label OCCDTNodeNotFound
- * @fwts-advice Device tree node /ibm,opal/power-mgt not
- * found. OPAL didn't add pstate information to device tree.
- * Probably a firmware bug.
- */
- prlog(PR_ERR, "OCC: dt node /ibm,opal/power-mgt not found\n");
- return false;
- }
-
dt_id = malloc(nr_pstates * sizeof(u32));
assert(dt_id);
dt_freq = malloc(nr_pstates * sizeof(u32));
@@ -684,14 +663,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
return false;
}
- if (proc_gen == proc_gen_p8) {
- freq_domain_mask = P8_PIR_CORE_MASK;
- domain_runs_at = FREQ_MOST_RECENTLY_SET;
- } else if (proc_gen == proc_gen_p9) {
- freq_domain_mask = P9_PIR_QUAD_MASK;
- domain_runs_at = FREQ_MAX_IN_DOMAIN;
- }
-
/* Add the device-tree entries */
dt_add_property(power_mgt, "ibm,pstate-ids", dt_id,
nr_pstates * sizeof(u32));
@@ -700,8 +671,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
dt_add_property_cells(power_mgt, "ibm,pstate-min", pmin);
dt_add_property_cells(power_mgt, "ibm,pstate-nominal", pnom);
dt_add_property_cells(power_mgt, "ibm,pstate-max", pmax);
- dt_add_property_cells(power_mgt, "freq-domain-mask", freq_domain_mask);
- dt_add_property_cells(power_mgt, "domain-runs-at", domain_runs_at);
free(dt_freq);
free(dt_id);
@@ -1752,15 +1721,31 @@ void occ_pstates_init(void)
{
struct proc_chip *chip;
struct cpu_thread *c;
+ struct dt_node *power_mgt;
int pstate_nom;
+ u32 freq_domain_mask;
+ u8 domain_runs_at;
static bool occ_pstates_initialized;
/* OCC is supported in P8 and P9 */
if (proc_gen < proc_gen_p8)
return;
+
+ power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
+ if (!power_mgt) {
+ /**
+ * @fwts-label OCCDTNodeNotFound
+ * @fwts-advice Device tree node /ibm,opal/power-mgt not
+ * found. OPAL didn't add pstate information to device tree.
+ * Probably a firmware bug.
+ */
+ prlog(PR_ERR, "OCC: dt node /ibm,opal/power-mgt not found\n");
+ return;
+ }
+
/* Handle fast reboots */
if (occ_pstates_initialized) {
- struct dt_node *power_mgt, *child;
+ struct dt_node *child;
int i;
const char *props[] = {
"ibm,pstate-core-max",
@@ -1775,15 +1760,12 @@ void occ_pstates_init(void)
"#size-cells",
};
- power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
- if (power_mgt) {
- for (i = 0; i < ARRAY_SIZE(props); i++)
- dt_check_del_prop(power_mgt, props[i]);
+ for (i = 0; i < ARRAY_SIZE(props); i++)
+ dt_check_del_prop(power_mgt, props[i]);
- dt_for_each_child(power_mgt, child)
- if (!strncmp(child->name, "occ", 3))
- dt_free(child);
- }
+ dt_for_each_child(power_mgt, child)
+ if (!strncmp(child->name, "occ", 3))
+ dt_free(child);
}
switch (proc_gen) {
@@ -1816,7 +1798,7 @@ void occ_pstates_init(void)
* Check boundary conditions and add device tree nodes
* and return nominal pstate to set for the core
*/
- if (!add_cpu_pstate_properties(&pstate_nom)) {
+ if (!add_cpu_pstate_properties(power_mgt, &pstate_nom)) {
log_simple_error(&e_info(OPAL_RC_OCC_PSTATE_INIT),
"Skiping core cpufreq init due to OCC error\n");
} else if (proc_gen == proc_gen_p8) {
@@ -1840,6 +1822,23 @@ void occ_pstates_init(void)
/* Init OPAL-OCC command-response interface */
occ_cmd_interface_init();
+
+ /* TODO Firmware plumbing required so as to have two modes to set
+ * PMCR based on max in domain or most recently used. As of today,
+ * it is always max in domain for P9.
+ */
+ domain_runs_at = 0;
+ freq_domain_mask = 0;
+ if (proc_gen == proc_gen_p8) {
+ freq_domain_mask = P8_PIR_CORE_MASK;
+ domain_runs_at = FREQ_MOST_RECENTLY_SET;
+ } else if (proc_gen == proc_gen_p9) {
+ freq_domain_mask = P9_PIR_QUAD_MASK;
+ domain_runs_at = FREQ_MAX_IN_DOMAIN;
+ }
+
+ dt_add_property_cells(power_mgt, "freq-domain-mask", freq_domain_mask);
+ dt_add_property_cells(power_mgt, "domain-runs-at", domain_runs_at);
}
struct occ_load_req {
--
1.8.3.1
More information about the Skiboot
mailing list