x86: Improve Intel microcode loader performance
We've noticed that on large SGI UV system configurations, running microcode.ctl can take very long periods of time. This is due to the large number of vmalloc/vfree calls made by the Intel generic_load_microcode() logic. By reusing allocated space, the following patch reduces the time to run microcode.ctl on a 1024 cpu system from approximately 80 seconds down to 1 or 2 seconds. Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> Acked-by: Dmitry Adamushko <dmitry.adamushko@gmail.com> Cc: Avi Kivity <avi@redhat.com> Cc: Bill Davidsen <davidsen@tmr.com> LKML-Reference: <20100305174203.GA19638@sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
522dba7134
commit
938179b4f8
1 changed files with 16 additions and 6 deletions
|
@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
int (*get_ucode_data)(void *, const void *, size_t))
|
||||
{
|
||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||
u8 *ucode_ptr = data, *new_mc = NULL, *mc;
|
||||
u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
|
||||
int new_rev = uci->cpu_sig.rev;
|
||||
unsigned int leftover = size;
|
||||
enum ucode_state state = UCODE_OK;
|
||||
unsigned int curr_mc_size = 0;
|
||||
|
||||
while (leftover) {
|
||||
struct microcode_header_intel mc_header;
|
||||
|
@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
break;
|
||||
}
|
||||
|
||||
mc = vmalloc(mc_size);
|
||||
if (!mc)
|
||||
break;
|
||||
/* For performance reasons, reuse mc area when possible */
|
||||
if (!mc || mc_size > curr_mc_size) {
|
||||
if (mc)
|
||||
vfree(mc);
|
||||
mc = vmalloc(mc_size);
|
||||
if (!mc)
|
||||
break;
|
||||
curr_mc_size = mc_size;
|
||||
}
|
||||
|
||||
if (get_ucode_data(mc, ucode_ptr, mc_size) ||
|
||||
microcode_sanity_check(mc) < 0) {
|
||||
|
@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
vfree(new_mc);
|
||||
new_rev = mc_header.rev;
|
||||
new_mc = mc;
|
||||
} else
|
||||
vfree(mc);
|
||||
mc = NULL; /* trigger new vmalloc */
|
||||
}
|
||||
|
||||
ucode_ptr += mc_size;
|
||||
leftover -= mc_size;
|
||||
}
|
||||
|
||||
if (mc)
|
||||
vfree(mc);
|
||||
|
||||
if (leftover) {
|
||||
if (new_mc)
|
||||
vfree(new_mc);
|
||||
|
|
Loading…
Reference in a new issue