Commit 762ec157 authored by Nathan Fontenot's avatar Nathan Fontenot Committed by Benjamin Herrenschmidt

powerpc/pseries: Expose pseries devicetree_update()

Newer firmware on Power systems can transparently reassign platform resources
(CPU and Memory) in use. For instance, if a processor or memory unit is
predicted to fail, the platform may transparently move the processing to an
equivalent unused processor or the memory state to an equivalent unused
memory unit. However, reassigning resources across NUMA boundaries may alter
the performance of the partition. When such reassignment is necessary, the
Platform Resource Reassignment Notification (PRRN) option provides a
mechanism to inform the Linux kernel of changes to the NUMA affinity of
its platform resources.

When rtasd receives a PRRN event, it needs to make a series of RTAS
calls (ibm,update-nodes and ibm,update-properties) to retrieve the
updated device tree information. These calls are already handled in the
pseries_devicetree_update() routine used in partition migration.

This patch exposes pseries_devicetree_update() to make it accessible
to other pseries routines, this patch also updates pseries_devicetree_update()
to take a 32-bit scope parameter. The scope value, which was previously hard
coded to 1 for partition migration, is used for the RTAS calls
ibm,update-nodes/properties to update the device tree.
Signed-off-by: default avatarNathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 3e96ca7f
...@@ -277,6 +277,10 @@ extern int early_init_dt_scan_rtas(unsigned long node, ...@@ -277,6 +277,10 @@ extern int early_init_dt_scan_rtas(unsigned long node,
extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
#ifdef CONFIG_PPC_PSERIES
extern int pseries_devicetree_update(s32 scope);
#endif
#ifdef CONFIG_PPC_RTAS_DAEMON #ifdef CONFIG_PPC_RTAS_DAEMON
extern void rtas_cancel_event_scan(void); extern void rtas_cancel_event_scan(void);
#else #else
......
...@@ -37,14 +37,16 @@ struct update_props_workarea { ...@@ -37,14 +37,16 @@ struct update_props_workarea {
#define UPDATE_DT_NODE 0x02000000 #define UPDATE_DT_NODE 0x02000000
#define ADD_DT_NODE 0x03000000 #define ADD_DT_NODE 0x03000000
static int mobility_rtas_call(int token, char *buf) #define MIGRATION_SCOPE (1)
static int mobility_rtas_call(int token, char *buf, s32 scope)
{ {
int rc; int rc;
spin_lock(&rtas_data_buf_lock); spin_lock(&rtas_data_buf_lock);
memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, 1); rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
spin_unlock(&rtas_data_buf_lock); spin_unlock(&rtas_data_buf_lock);
...@@ -123,7 +125,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, ...@@ -123,7 +125,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
return 0; return 0;
} }
static int update_dt_node(u32 phandle) static int update_dt_node(u32 phandle, s32 scope)
{ {
struct update_props_workarea *upwa; struct update_props_workarea *upwa;
struct device_node *dn; struct device_node *dn;
...@@ -151,7 +153,8 @@ static int update_dt_node(u32 phandle) ...@@ -151,7 +153,8 @@ static int update_dt_node(u32 phandle)
upwa->phandle = phandle; upwa->phandle = phandle;
do { do {
rc = mobility_rtas_call(update_properties_token, rtas_buf); rc = mobility_rtas_call(update_properties_token, rtas_buf,
scope);
if (rc < 0) if (rc < 0)
break; break;
...@@ -219,7 +222,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index) ...@@ -219,7 +222,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
return rc; return rc;
} }
static int pseries_devicetree_update(void) int pseries_devicetree_update(s32 scope)
{ {
char *rtas_buf; char *rtas_buf;
u32 *data; u32 *data;
...@@ -235,7 +238,7 @@ static int pseries_devicetree_update(void) ...@@ -235,7 +238,7 @@ static int pseries_devicetree_update(void)
return -ENOMEM; return -ENOMEM;
do { do {
rc = mobility_rtas_call(update_nodes_token, rtas_buf); rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope);
if (rc && rc != 1) if (rc && rc != 1)
break; break;
...@@ -256,7 +259,7 @@ static int pseries_devicetree_update(void) ...@@ -256,7 +259,7 @@ static int pseries_devicetree_update(void)
delete_dt_node(phandle); delete_dt_node(phandle);
break; break;
case UPDATE_DT_NODE: case UPDATE_DT_NODE:
update_dt_node(phandle); update_dt_node(phandle, scope);
break; break;
case ADD_DT_NODE: case ADD_DT_NODE:
drc_index = *data++; drc_index = *data++;
...@@ -276,7 +279,7 @@ void post_mobility_fixup(void) ...@@ -276,7 +279,7 @@ void post_mobility_fixup(void)
int rc; int rc;
int activate_fw_token; int activate_fw_token;
rc = pseries_devicetree_update(); rc = pseries_devicetree_update(MIGRATION_SCOPE);
if (rc) { if (rc) {
printk(KERN_ERR "Initial post-mobility device tree update " printk(KERN_ERR "Initial post-mobility device tree update "
"failed: %d\n", rc); "failed: %d\n", rc);
...@@ -292,7 +295,7 @@ void post_mobility_fixup(void) ...@@ -292,7 +295,7 @@ void post_mobility_fixup(void)
rc = rtas_call(activate_fw_token, 0, 1, NULL); rc = rtas_call(activate_fw_token, 0, 1, NULL);
if (!rc) { if (!rc) {
rc = pseries_devicetree_update(); rc = pseries_devicetree_update(MIGRATION_SCOPE);
if (rc) if (rc)
printk(KERN_ERR "Secondary post-mobility device tree " printk(KERN_ERR "Secondary post-mobility device tree "
"update failed: %d\n", rc); "update failed: %d\n", rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment