diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2018-07-03 19:15:14 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-07-04 18:40:54 -0500 |
commit | 7a3f307ed0db8552a086dd0e4a45fe08e1807084 (patch) | |
tree | cbe82e17eb87986f0e9eff7b7d74838cd66ad4db /core | |
parent | 9078f8268922b44c3b0f2cd44f567b9389073142 (diff) | |
download | skiboot-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.c | 47 |
1 files changed, 37 insertions, 10 deletions
@@ -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; } |