diff options
author | Nathan Fontenot <nfont@linux.vnet.ibm.com> | 2013-04-24 02:07:39 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-04-26 02:08:26 -0400 |
commit | e04fa61214a3e586282490af7e1b023522c1472a (patch) | |
tree | 44efd1187b1b9d77341cec4b80c4355a36a73afb | |
parent | 1b1218d32efdc81134eeb908935a18659cb3d9d7 (diff) |
powerpc/pseries: Add /proc interface to control topology updates
There are instances in which we do not want topology updates to occur.
In order to allow this a /proc interface (/proc/powerpc/topology_updates)
is introduced so that topology updates can be enabled and disabled.
This patch also adds a prrn_is_enabled() call so that PRRN events are
handled in the kernel only if topology updating is enabled.
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/include/asm/topology.h | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtasd.c | 7 | ||||
-rw-r--r-- | arch/powerpc/mm/numa.c | 62 |
3 files changed, 71 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 852ed1b384f6..161ab662843b 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -71,6 +71,7 @@ static inline void sysfs_remove_device_from_node(struct device *dev, | |||
71 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) | 71 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) |
72 | extern int start_topology_update(void); | 72 | extern int start_topology_update(void); |
73 | extern int stop_topology_update(void); | 73 | extern int stop_topology_update(void); |
74 | extern int prrn_is_enabled(void); | ||
74 | #else | 75 | #else |
75 | static inline int start_topology_update(void) | 76 | static inline int start_topology_update(void) |
76 | { | 77 | { |
@@ -80,6 +81,10 @@ static inline int stop_topology_update(void) | |||
80 | { | 81 | { |
81 | return 0; | 82 | return 0; |
82 | } | 83 | } |
84 | static inline int prrn_is_enabled(void) | ||
85 | { | ||
86 | return 0; | ||
87 | } | ||
83 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ | 88 | #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ |
84 | 89 | ||
85 | #include <asm-generic/topology.h> | 90 | #include <asm-generic/topology.h> |
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 8e52b6d8b6f2..1130c53ad652 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/nvram.h> | 29 | #include <asm/nvram.h> |
30 | #include <linux/atomic.h> | 30 | #include <linux/atomic.h> |
31 | #include <asm/machdep.h> | 31 | #include <asm/machdep.h> |
32 | #include <asm/topology.h> | ||
32 | 33 | ||
33 | 34 | ||
34 | static DEFINE_SPINLOCK(rtasd_log_lock); | 35 | static DEFINE_SPINLOCK(rtasd_log_lock); |
@@ -292,11 +293,13 @@ void prrn_schedule_update(u32 scope) | |||
292 | 293 | ||
293 | static void handle_rtas_event(const struct rtas_error_log *log) | 294 | static void handle_rtas_event(const struct rtas_error_log *log) |
294 | { | 295 | { |
295 | if (log->type == RTAS_TYPE_PRRN) | 296 | if (log->type == RTAS_TYPE_PRRN) { |
296 | /* For PRRN Events the extended log length is used to denote | 297 | /* For PRRN Events the extended log length is used to denote |
297 | * the scope for calling rtas update-nodes. | 298 | * the scope for calling rtas update-nodes. |
298 | */ | 299 | */ |
299 | prrn_schedule_update(log->extended_log_length); | 300 | if (prrn_is_enabled()) |
301 | prrn_schedule_update(log->extended_log_length); | ||
302 | } | ||
300 | 303 | ||
301 | return; | 304 | return; |
302 | } | 305 | } |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 908699fb61c9..2d13f90476bd 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/cpuset.h> | 23 | #include <linux/cpuset.h> |
24 | #include <linux/node.h> | 24 | #include <linux/node.h> |
25 | #include <linux/stop_machine.h> | 25 | #include <linux/stop_machine.h> |
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <linux/uaccess.h> | ||
26 | #include <asm/sparsemem.h> | 29 | #include <asm/sparsemem.h> |
27 | #include <asm/prom.h> | 30 | #include <asm/prom.h> |
28 | #include <asm/smp.h> | 31 | #include <asm/smp.h> |
@@ -1585,7 +1588,6 @@ int start_topology_update(void) | |||
1585 | 1588 | ||
1586 | return rc; | 1589 | return rc; |
1587 | } | 1590 | } |
1588 | __initcall(start_topology_update); | ||
1589 | 1591 | ||
1590 | /* | 1592 | /* |
1591 | * Disable polling for VPHN associativity changes. | 1593 | * Disable polling for VPHN associativity changes. |
@@ -1604,4 +1606,62 @@ int stop_topology_update(void) | |||
1604 | 1606 | ||
1605 | return rc; | 1607 | return rc; |
1606 | } | 1608 | } |
1609 | |||
1610 | int prrn_is_enabled(void) | ||
1611 | { | ||
1612 | return prrn_enabled; | ||
1613 | } | ||
1614 | |||
1615 | static int topology_read(struct seq_file *file, void *v) | ||
1616 | { | ||
1617 | if (vphn_enabled || prrn_enabled) | ||
1618 | seq_puts(file, "on\n"); | ||
1619 | else | ||
1620 | seq_puts(file, "off\n"); | ||
1621 | |||
1622 | return 0; | ||
1623 | } | ||
1624 | |||
1625 | static int topology_open(struct inode *inode, struct file *file) | ||
1626 | { | ||
1627 | return single_open(file, topology_read, NULL); | ||
1628 | } | ||
1629 | |||
1630 | static ssize_t topology_write(struct file *file, const char __user *buf, | ||
1631 | size_t count, loff_t *off) | ||
1632 | { | ||
1633 | char kbuf[4]; /* "on" or "off" plus null. */ | ||
1634 | int read_len; | ||
1635 | |||
1636 | read_len = count < 3 ? count : 3; | ||
1637 | if (copy_from_user(kbuf, buf, read_len)) | ||
1638 | return -EINVAL; | ||
1639 | |||
1640 | kbuf[read_len] = '\0'; | ||
1641 | |||
1642 | if (!strncmp(kbuf, "on", 2)) | ||
1643 | start_topology_update(); | ||
1644 | else if (!strncmp(kbuf, "off", 3)) | ||
1645 | stop_topology_update(); | ||
1646 | else | ||
1647 | return -EINVAL; | ||
1648 | |||
1649 | return count; | ||
1650 | } | ||
1651 | |||
1652 | static const struct file_operations topology_ops = { | ||
1653 | .read = seq_read, | ||
1654 | .write = topology_write, | ||
1655 | .open = topology_open, | ||
1656 | .release = single_release | ||
1657 | }; | ||
1658 | |||
1659 | static int topology_update_init(void) | ||
1660 | { | ||
1661 | start_topology_update(); | ||
1662 | proc_create("powerpc/topology_updates", 644, NULL, &topology_ops); | ||
1663 | |||
1664 | return 0; | ||
1665 | } | ||
1666 | device_initcall(topology_update_init); | ||
1607 | #endif /* CONFIG_PPC_SPLPAR */ | 1667 | #endif /* CONFIG_PPC_SPLPAR */ |