|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 04/12] microcode: introduce a global cache of ucode patch
Thanks for your great suggestion.
On Tue, Mar 12, 2019 at 05:53:53PM +0100, Roger Pau Monné wrote:
>On Mon, Mar 11, 2019 at 03:57:28PM +0800, Chao Gao wrote:
>> to replace the current per-cpu cache 'uci->mc'.
>>
>> Compared to the current per-cpu cache, the benefits of the global
>> microcode cache are:
>> 1. It reduces the work that need to be done on each CPU. Parsing ucode
>> file is done once on one CPU. Other CPUs needn't parse ucode file.
>> Instead, they can find out and load the newest patch from the global
>> cache.
>> 2. It reduces the memory consumption on a system with many CPU cores.
>>
>> Two functions, microcode_save_patch() and microcode_find_patch() are
>> introduced. The former adds one given patch to the global cache. The
>> latter gets a newer and matched ucode patch from the global cache.
>> All operations on the cache is expected to be done with the
>> 'microcode_mutex' hold.
>>
>> Note that I deliberately avoid touching 'uci->mc' as I am going to
>> remove it completely in the next patch.
>>
>> Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
>> ---
>> Changes in v6:
>> - constify local variables and function parameters if possible
>> - comment that the global cache is protected by 'microcode_mutex'.
>> and add assertions to catch violations in microcode_{save/find}_patch()
>>
>> Changes in v5:
>> - reword the commit description
>> - find_patch() and save_patch() are abstracted into common functions
>> with some hooks for AMD and Intel
>> ---
>> xen/arch/x86/microcode.c | 60 +++++++++++++++++++++++++++
>> xen/arch/x86/microcode_amd.c | 91
>> +++++++++++++++++++++++++++++++++++++----
>> xen/arch/x86/microcode_intel.c | 66 ++++++++++++++++++++++++++----
>> xen/include/asm-x86/microcode.h | 13 ++++++
>> 4 files changed, 215 insertions(+), 15 deletions(-)
>>
>> diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
>> index 4163f50..e629e6c 100644
>> --- a/xen/arch/x86/microcode.c
>> +++ b/xen/arch/x86/microcode.c
>> @@ -61,6 +61,8 @@ static struct ucode_mod_blob __initdata ucode_blob;
>> */
>> static bool_t __initdata ucode_scan;
>>
>> +static LIST_HEAD(microcode_cache);
>> +
>> void __init microcode_set_module(unsigned int idx)
>> {
>> ucode_mod_idx = idx;
>> @@ -208,6 +210,64 @@ static void microcode_fini_cpu(unsigned int cpu)
>> spin_unlock(µcode_mutex);
>> }
>>
>> +/*
>> + * Save an ucode patch to the global cache list.
>> + *
>> + * Return true if a patch is added to the global cache or it replaces
>> + * one old patch in the cache. Otherwise, return false. According to
>> + * the return value, the caller decides not to do an expensive ucode
>> + * update for some cases (i.e. when admin provides an old ucode).
>> + */
>> +bool microcode_save_patch(struct microcode_patch *new)
>> +{
>> + struct microcode_patch *old;
>> +
>> + ASSERT(spin_is_locked(µcode_mutex));
>> +
>> + list_for_each_entry(old, µcode_cache, list)
>> + {
>> + enum microcode_match_result result =
>> + microcode_ops->compare_patch(new, old);
>> +
>> + if ( result == OLD_UCODE )
>> + {
>> + microcode_ops->free_patch(new);
>> + return false;
>> + }
>> + else if ( result == NEW_UCODE )
>> + {
>> + list_replace(&old->list, &new->list);
>> + microcode_ops->free_patch(old);
>> + return true;
>> + }
>> + else /* result == MIS_UCODE */
>> + continue;
>
>I think this is rather too simplistic, and I'm not sure you really
>need a list in order to store the microcodes.
>
>IIRC we agreed that systems with mixed CPU versions are not supported,
In previous version, I also mentioned that one instance might be enough.
(two instances considering the concern you elaborated below)
But I was told that it would be better to support mixed CPUs if they are
allowed by Intel or AMD. And the old per-cpu cache, IMO, also supports
mixed CPUs.
If now we don't want to support it any longer, I agree to your proposal.
I will defer to Jan's opinion.
Thanks
Chao
>hence the same microcode blob should be used to update all the
>possible CPUs on the system, so a list should not be needed here.
>
>Also I'm afraid that freeing the old microcode when a new version is
>uploaded is not fully correct. For example given the following
>scenario:
>
>1. Upload a microcode blob to the hypervisor and apply it to online
>CPUs.
>
>2. Upload a microcode blob with a higher version than the previous one,
>but which fails to apply. This microcode would replace the
>previous one.
>
>3. Online a CPU. This CPU will try to use the last uploaded microcode
>and fail, because last uploaded version is broken. Newly onlined CPUs
>would then end up with a microcode version different from the
>currently running CPUs, likely breaking the system.
>
>I think the best way to solve this is to ditch the list usage and
>instead only keep at most two microcode versions cached in the
>hypervisor:
>
> - The microcode version that's currently successfully applied (if any).
> - A microcode version higher than the current version, that has yet
> to be applied.
>
>Once this new microcode version has been applied it will replace the
>previously applied version. If the new microcode version fails to
>apply it will be discarded, thus keeping a copy of the currently
>applied microcode version.
>
>With this approach AFAICT you only need two variables, one to store
>the currently applied microcode_patch and another one to save the new
>microcode version in order to attempt to apply it.
>
>I think this will also simplify some of the code. Let me know if this
>sounds sensible, or if I'm missing something.
>
>Thanks, Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |