aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2018-07-03 19:15:14 +1000
committerStewart Smith <stewart@linux.ibm.com>2018-07-04 18:40:54 -0500
commit7a3f307ed0db8552a086dd0e4a45fe08e1807084 (patch)
treecbe82e17eb87986f0e9eff7b7d74838cd66ad4db /core
parent9078f8268922b44c3b0f2cd44f567b9389073142 (diff)
downloadskiboot-7a3f307ed0db8552a086dd0e4a45fe08e1807084.zip
skiboot-7a3f307ed0db8552a086dd0e4a45fe08e1807084.tar.gz
skiboot-7a3f307ed0db8552a086dd0e4a45fe08e1807084.tar.bz2
core/cpu: parallelise global CPU register setting jobs
On a 176 thread system, before: [ 122.319923233,5] OPAL: Switch to big-endian OS [ 126.317897467,5] OPAL: Switch to little-endian OS after: [ 212.439299889,5] OPAL: Switch to big-endian OS [ 212.469323643,5] OPAL: Switch to little-endian OS Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/cpu.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/core/cpu.c b/core/cpu.c
index a8936fa..2f30c58 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -1304,17 +1304,30 @@ static void cpu_change_hid0(void *__req)
static int64_t cpu_change_all_hid0(struct hid0_change_req *req)
{
struct cpu_thread *cpu;
+ struct cpu_job **jobs;
+
+ jobs = zalloc(sizeof(struct cpu_job *) * cpu_max_pir + 1);
+ assert(jobs);
for_each_available_cpu(cpu) {
if (!cpu_is_thread0(cpu))
continue;
- if (cpu == this_cpu()) {
- cpu_change_hid0(req);
+ if (cpu == this_cpu())
continue;
- }
- cpu_wait_job(cpu_queue_job(cpu, "cpu_change_hid0",
- cpu_change_hid0, req), true);
+ jobs[cpu->pir] = cpu_queue_job(cpu, "cpu_change_hid0",
+ cpu_change_hid0, req);
}
+
+ /* this cpu */
+ cpu_change_hid0(req);
+
+ for_each_available_cpu(cpu) {
+ if (jobs[cpu->pir])
+ cpu_wait_job(jobs[cpu->pir], true);
+ }
+
+ free(jobs);
+
return OPAL_SUCCESS;
}
@@ -1342,15 +1355,29 @@ static void cpu_cleanup_one(void *param __unused)
static int64_t cpu_cleanup_all(void)
{
struct cpu_thread *cpu;
+ struct cpu_job **jobs;
+
+ jobs = zalloc(sizeof(struct cpu_job *) * cpu_max_pir + 1);
+ assert(jobs);
for_each_available_cpu(cpu) {
- if (cpu == this_cpu()) {
- cpu_cleanup_one(NULL);
+ if (cpu == this_cpu())
continue;
- }
- cpu_wait_job(cpu_queue_job(cpu, "cpu_cleanup",
- cpu_cleanup_one, NULL), true);
+ jobs[cpu->pir] = cpu_queue_job(cpu, "cpu_cleanup",
+ cpu_cleanup_one, NULL);
+ }
+
+ /* this cpu */
+ cpu_cleanup_one(NULL);
+
+ for_each_available_cpu(cpu) {
+ if (jobs[cpu->pir])
+ cpu_wait_job(jobs[cpu->pir], true);
}
+
+ free(jobs);
+
+
return OPAL_SUCCESS;
}