[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 1/6] spapr/xive: Introduce a StoreEOI capability
From: |
Greg Kurz |
Subject: |
Re: [PATCH v2 1/6] spapr/xive: Introduce a StoreEOI capability |
Date: |
Tue, 6 Oct 2020 18:42:36 +0200 |
On Mon, 5 Oct 2020 18:51:42 +0200
Cédric Le Goater <clg@kaod.org> wrote:
> When an interrupt has been handled, the OS notifies the interrupt
> controller with an EOI sequence. On the XIVE interrupt controller
> (POWER9 and POWER10), this can be done with a load or a store
> operation on the ESB interrupt management page of the interrupt. The
> StoreEOI operation has less latency and improves interrupt handling
> performance but it was deactivated during the POWER9 DD2.0 time-frame
> because of ordering issues. POWER9 systems use the LoadEOI instead.
> POWER10 has fixed the issue with a special load command which enforces
> Load-after-Store ordering and StoreEOI can be safely used.
>
> The new StoreEOI capability adds StoreEOI support to the flags
> returned by the hcall H_INT_GET_SOURCE_INFO. When the machine is using
> an emulated interrupt controller, TCG or without kernel IRQ chip,
> there are no limitations and activating StoreEOI is not an issue.
> However, when running with a kernel IRQ chip, some verification needs
> to be done on the host. This is done through the DT, which tells us
> that firmware has configured the HW for StoreEOI, but a new KVM
> capability would be cleaner.
>
Cleaner and even required... a user could possibly run an older
KVM that doesn't know about StoreEOI on a POWER10 host and QEMU
would wrongly assume the feature is supported. Also, I guess this
should rather be an attribute of the XIVE KVM device rather than a
plain KVM property.
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> include/hw/ppc/spapr.h | 4 +++-
> target/ppc/kvm_ppc.h | 6 ++++++
> hw/ppc/spapr.c | 1 +
> hw/ppc/spapr_caps.c | 30 ++++++++++++++++++++++++++++++
> target/ppc/kvm.c | 18 ++++++++++++++++++
> 5 files changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index bba8736269f4..b701c14b4e09 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -74,8 +74,10 @@ typedef enum {
> #define SPAPR_CAP_CCF_ASSIST 0x09
> /* Implements PAPR FWNMI option */
> #define SPAPR_CAP_FWNMI 0x0A
> +/* Implements XIVE StoreEOI feature */
> +#define SPAPR_CAP_STOREEOI 0x0B
The name should mention XIVE, ie. SPAPR_CAP_XIVE_STOREEOI
> /* Num Caps */
> -#define SPAPR_CAP_NUM (SPAPR_CAP_FWNMI + 1)
> +#define SPAPR_CAP_NUM (SPAPR_CAP_STOREEOI + 1)
>
> /*
> * Capability Values
> diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
> index 72e05f1cd2fc..c5a487dbba13 100644
> --- a/target/ppc/kvm_ppc.h
> +++ b/target/ppc/kvm_ppc.h
> @@ -64,6 +64,7 @@ bool kvmppc_has_cap_htm(void);
> bool kvmppc_has_cap_mmu_radix(void);
> bool kvmppc_has_cap_mmu_hash_v3(void);
> bool kvmppc_has_cap_xive(void);
> +bool kvmppc_has_cap_xive_storeeoi(void);
> int kvmppc_get_cap_safe_cache(void);
> int kvmppc_get_cap_safe_bounds_check(void);
> int kvmppc_get_cap_safe_indirect_branch(void);
> @@ -346,6 +347,11 @@ static inline bool kvmppc_has_cap_xive(void)
> return false;
> }
>
> +static inline bool kvmppc_has_cap_xive_storeeoi(void)
> +{
> + return false;
> +}
> +
> static inline int kvmppc_get_cap_safe_cache(void)
> {
> return 0;
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 4256794f3bed..e83de0580142 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4447,6 +4447,7 @@ static void spapr_machine_class_init(ObjectClass *oc,
> void *data)
> smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
> smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
> smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
> + smc->default_caps.caps[SPAPR_CAP_STOREEOI] = SPAPR_CAP_OFF;
> spapr_caps_add_properties(smc);
> smc->irq = &spapr_irq_dual;
> smc->dr_phb_enabled = true;
> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> index 9341e9782a3f..57c62c22e4cc 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -524,6 +524,26 @@ static void cap_fwnmi_apply(SpaprMachineState *spapr,
> uint8_t val,
> }
> }
>
> +static void cap_storeeoi_apply(SpaprMachineState *spapr, uint8_t val,
> + Error **errp)
> +{
> + ERRP_GUARD();
From "qapi/error.h":
* = Why, when and how to use ERRP_GUARD() =
*
* Without ERRP_GUARD(), use of the @errp parameter is restricted:
* - It must not be dereferenced, because it may be null.
* - It should not be passed to error_prepend() or
* error_append_hint(), because that doesn't work with &error_fatal.
* ERRP_GUARD() lifts these restrictions.
*
* To use ERRP_GUARD(), add it right at the beginning of the function.
* @errp can then be used without worrying about the argument being
* NULL or &error_fatal.
*
* Using it when it's not needed is safe, but please avoid cluttering
* the source with useless code.
*
So for this ERRP_GUARD() to be justified, you should come up with
a hint, otherwise you should drop it.
> + MachineState *machine = MACHINE(spapr);
> + bool kvm_storeeoi = kvmppc_has_cap_xive_storeeoi();
> +
> + if (!val) {
> + return; /* Disabled by default */
> + }
> +
> + /* Check host support when the KVM device is in use */
> + if (kvm_irqchip_in_kernel()) {
Hmm... checking kvm_irqchip_in_kernel() is imprecise because
it returns true if either the XIVE or XICS KVM device has
been open, regardless of the flavor we're going to use. This
really depends on the ic-mode setting:
1) xics: we really don't care whether StoreEOI is available or not.
This is very similar to the case of POWER8 in patch 2. Spit a
warning and return.
2) xive: at this point the XIVE KVM device is open and we can check
the availability of StoreEOI with kvm_device_check_attr().
3) dual: this one is problematic because at this point the XICS KVM
device is open but XIVE KVM won't be open until CAS.
So I think we can only do something sensible for cases 1) and 2),
eg:
if (!spapr->irq->xive) {
warn_report(...);
return;
}
if (spapr_xive_in_kernel(spapr->xive)) {
!kvm_device_check_attr(spapr->xive->fd, ...) {
error_setg(errp, "StoreEOI not supported by XIVE KVM");
return;
}
Case 3) requires a similar check in CAS if the guest asked for XIVE
and cap-xive-storeeoi=on.
> + if (!kvm_storeeoi) {
> + error_setg(errp, "StoreEOI not supported by KVM");
> + return;
> + }
> + }
> +}
> +
> SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
> [SPAPR_CAP_HTM] = {
> .name = "htm",
> @@ -632,6 +652,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
> .type = "bool",
> .apply = cap_fwnmi_apply,
> },
> + [SPAPR_CAP_STOREEOI] = {
> + .name = "storeeoi",
> + .description = "Implements XIVE StoreEOI feature",
> + .index = SPAPR_CAP_STOREEOI,
> + .get = spapr_cap_get_bool,
> + .set = spapr_cap_set_bool,
> + .type = "bool",
> + .apply = cap_storeeoi_apply,
> + },
> };
>
> static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
> @@ -772,6 +801,7 @@ SPAPR_CAP_MIG_STATE(nested_kvm_hv,
> SPAPR_CAP_NESTED_KVM_HV);
> SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
> SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
> SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);
> +SPAPR_CAP_MIG_STATE(storeeoi, SPAPR_CAP_STOREEOI);
>
> void spapr_caps_init(SpaprMachineState *spapr)
> {
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index d85ba8ffe00b..9ad637151070 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -2448,6 +2448,24 @@ bool kvmppc_has_cap_xive(void)
> return cap_xive;
> }
>
> +/*
> + * TODO: Introduce a new KVM capability
> + */
Is there anything that prevents to add such a capability
or KVM device attribute before modifying QEMU ?
> +bool kvmppc_has_cap_xive_storeeoi(void)
> +{
> + static const char *compat = "ibm,opal-xive-pe";
> + void *host_fdt;
> + int xive_node;
> +
> + host_fdt = load_device_tree_from_sysfs();
> + xive_node = fdt_node_offset_by_compatible(host_fdt, -1, compat);
> + if (xive_node < 0) {
> + return false;
> + }
> +
> + return !!fdt_getprop(host_fdt, xive_node, "store-eoi-support", NULL);
> +}
> +
> static void kvmppc_get_cpu_characteristics(KVMState *s)
> {
> struct kvm_ppc_cpu_char c;
Re: [PATCH v2 0/6] spapr/xive: Activate StoreEOI in P10 compat guests, David Gibson, 2020/10/08