Skip to content

Commit

Permalink
x86: Improve Intel microcode loader performance
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dimitri Sivanich authored and Ingo Molnar committed Mar 11, 2010
1 parent 522dba7 commit 938179b
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions arch/x86/kernel/microcode_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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);
Expand Down

0 comments on commit 938179b

Please sign in to comment.