From: "Nicholas Piggin" <npiggin@gmail.com>
To: "Michael Kowal" <kowal@linux.ibm.com>, <qemu-devel@nongnu.org>
Cc: <qemu-ppc@nongnu.org>, <fbarrat@linux.ibm.com>,
<milesg@linux.ibm.com>, <danielhb413@gmail.com>,
<david@gibson.dropbear.id.au>, <harshpb@linux.ibm.com>,
<thuth@redhat.com>, <lvivier@redhat.com>, <pbonzini@redhat.com>
Subject: Re: [PATCH v2 05/14] ppc/xive2: Add undelivered group interrupt to backlog
Date: Mon, 10 Mar 2025 14:07:18 +1000 [thread overview]
Message-ID: <D8CAGGO59SN8.F7LMIJ3I6930@gmail.com> (raw)
In-Reply-To: <20241210000527.9541-9-kowal@linux.ibm.com>
On Tue Dec 10, 2024 at 10:05 AM AEST, Michael Kowal wrote:
> From: Frederic Barrat <fbarrat@linux.ibm.com>
>
> When a group interrupt cannot be delivered, we need to:
> - increment the backlog counter for the group in the NVG table
> (if the END is configured to keep a backlog).
> - start a broadcast operation to set the LSMFB field on matching CPUs
> which can't take the interrupt now because they're running at too
> high a priority.
>
> Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
> ---
> include/hw/ppc/xive.h | 5 ++
> include/hw/ppc/xive2.h | 1 +
> hw/intc/pnv_xive2.c | 42 +++++++++++++++++
> hw/intc/xive2.c | 105 +++++++++++++++++++++++++++++++++++------
> hw/ppc/pnv.c | 22 ++++++++-
> 5 files changed, 159 insertions(+), 16 deletions(-)
>
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index ce4eb9726b..f443a39cf1 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -442,6 +442,9 @@ struct XivePresenterClass {
> uint32_t logic_serv, XiveTCTXMatch *match);
> bool (*in_kernel)(const XivePresenter *xptr);
> uint32_t (*get_config)(XivePresenter *xptr);
> + int (*broadcast)(XivePresenter *xptr,
> + uint8_t nvt_blk, uint32_t nvt_idx,
> + uint8_t priority);
> };
>
> int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
> @@ -472,6 +475,8 @@ struct XiveFabricClass {
> uint8_t nvt_blk, uint32_t nvt_idx,
> bool cam_ignore, uint8_t priority,
> uint32_t logic_serv, XiveTCTXMatch *match);
> + int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx,
> + uint8_t priority);
> };
>
> /*
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index 65154f78d8..ebf301bb5b 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -120,6 +120,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
> void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> hwaddr offset, uint64_t value, unsigned size);
> bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority);
> +void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority);
> void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
> hwaddr offset, uint64_t value, unsigned size);
> void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
> index 5cdd4fdcc9..41b727d1fb 100644
> --- a/hw/intc/pnv_xive2.c
> +++ b/hw/intc/pnv_xive2.c
> @@ -705,6 +705,47 @@ static uint32_t pnv_xive2_presenter_get_config(XivePresenter *xptr)
> return cfg;
> }
>
> +static int pnv_xive2_broadcast(XivePresenter *xptr,
> + uint8_t nvt_blk, uint32_t nvt_idx,
> + uint8_t priority)
> +{
> + PnvXive2 *xive = PNV_XIVE2(xptr);
> + PnvChip *chip = xive->chip;
> + int i, j;
> + bool gen1_tima_os =
> + xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
> +
> + for (i = 0; i < chip->nr_cores; i++) {
> + PnvCore *pc = chip->cores[i];
> + CPUCore *cc = CPU_CORE(pc);
> +
> + for (j = 0; j < cc->nr_threads; j++) {
> + PowerPCCPU *cpu = pc->threads[j];
> + XiveTCTX *tctx;
> + int ring;
> +
> + if (!pnv_xive2_is_cpu_enabled(xive, cpu)) {
> + continue;
> + }
> +
> + tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
> +
> + if (gen1_tima_os) {
> + ring = xive_presenter_tctx_match(xptr, tctx, 0, nvt_blk,
> + nvt_idx, true, 0);
> + } else {
> + ring = xive2_presenter_tctx_match(xptr, tctx, 0, nvt_blk,
> + nvt_idx, true, 0);
> + }
> +
> + if (ring != -1) {
> + xive2_tm_set_lsmfb(tctx, ring, priority);
> + }
> + }
> + }
> + return 0;
> +}
> +
> static uint8_t pnv_xive2_get_block_id(Xive2Router *xrtr)
> {
> return pnv_xive2_block_id(PNV_XIVE2(xrtr));
> @@ -2445,6 +2486,7 @@ static void pnv_xive2_class_init(ObjectClass *klass, void *data)
>
> xpc->match_nvt = pnv_xive2_match_nvt;
> xpc->get_config = pnv_xive2_presenter_get_config;
> + xpc->broadcast = pnv_xive2_broadcast;
> };
>
> static const TypeInfo pnv_xive2_info = {
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index cffcf3ff05..05cb17518d 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -62,6 +62,30 @@ static uint32_t xive2_nvgc_get_backlog(Xive2Nvgc *nvgc, uint8_t priority)
> return val;
> }
>
> +static void xive2_nvgc_set_backlog(Xive2Nvgc *nvgc, uint8_t priority,
> + uint32_t val)
> +{
> + uint8_t *ptr, i;
> + uint32_t shift;
> +
> + if (priority > 7) {
> + return;
> + }
> +
> + if (val > 0xFFFFFF) {
> + val = 0xFFFFFF;
> + }
Could these conditions have asserts or warnings? Seems like we
saturate a counter or silently drop an interrupt if these things
can happen. Can add something later.
> + /*
> + * The per-priority backlog counters are 24-bit and the structure
> + * is stored in big endian
> + */
> + ptr = (uint8_t *)&nvgc->w2 + priority * 3;
This fits because nvgc is 32 bytes so 24 bytes from w2, and
8 priorities * 3 bytes each is 24. I just added a bit more comment.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
> + for (i = 0; i < 3; i++, ptr++) {
> + shift = 8 * (2 - i);
> + *ptr = (val >> shift) & 0xFF;
> + }
> +}
> +
> void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf)
> {
> if (!xive2_eas_is_valid(eas)) {
> @@ -830,6 +854,19 @@ bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority)
> return true;
> }
>
> +void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority)
> +{
> + uint8_t *regs = &tctx->regs[ring];
> +
> + /*
> + * Called by the router during a VP-group notification when the
> + * thread matches but can't take the interrupt because it's
> + * already running at a more favored priority. It then stores the
> + * new interrupt priority in the LSMFB field.
> + */
> + regs[TM_LSMFB] = priority;
> +}
> +
> static void xive2_router_realize(DeviceState *dev, Error **errp)
> {
> Xive2Router *xrtr = XIVE2_ROUTER(dev);
> @@ -962,10 +999,9 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
> /*
> * If no matching NVP is dispatched on a HW thread :
> * - specific VP: update the NVP structure if backlog is activated
> - * - logical server : forward request to IVPE (not supported)
> + * - VP-group: update the backlog counter for that priority in the NVG
> */
> if (xive2_end_is_backlog(&end)) {
> - uint8_t ipb;
>
> if (format == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> @@ -974,19 +1010,58 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
> return;
> }
>
> - /*
> - * Record the IPB in the associated NVP structure for later
> - * use. The presenter will resend the interrupt when the vCPU
> - * is dispatched again on a HW thread.
> - */
> - ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) |
> - xive_priority_to_ipb(priority);
> - nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb);
> - xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2);
> -
> - /*
> - * On HW, follows a "Broadcast Backlog" to IVPEs
> - */
> + if (!xive2_end_is_ignore(&end)) {
> + uint8_t ipb;
> + /*
> + * Record the IPB in the associated NVP structure for later
> + * use. The presenter will resend the interrupt when the vCPU
> + * is dispatched again on a HW thread.
> + */
> + ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) |
> + xive_priority_to_ipb(priority);
> + nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb);
> + xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2);
> + } else {
> + Xive2Nvgc nvg;
> + uint32_t backlog;
> +
> + /* For groups, the per-priority backlog counters are in the NVG */
> + if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVG %x/%x\n",
> + nvp_blk, nvp_idx);
> + return;
> + }
> +
> + if (!xive2_nvgc_is_valid(&nvg)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVG %x/%x is invalid\n",
> + nvp_blk, nvp_idx);
> + return;
> + }
> +
> + /*
> + * Increment the backlog counter for that priority.
> + * For the precluded case, we only call broadcast the
> + * first time the counter is incremented. broadcast will
> + * set the LSMFB field of the TIMA of relevant threads so
> + * that they know an interrupt is pending.
> + */
> + backlog = xive2_nvgc_get_backlog(&nvg, priority) + 1;
> + xive2_nvgc_set_backlog(&nvg, priority, backlog);
> + xive2_router_write_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg);
> +
> + if (precluded && backlog == 1) {
> + XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xrtr->xfb);
> + xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx, priority);
> +
> + if (!xive2_end_is_precluded_escalation(&end)) {
> + /*
> + * The interrupt will be picked up when the
> + * matching thread lowers its priority level
> + */
> + return;
> + }
> + }
> + }
> }
>
> do_escalation:
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index f0f0d7567d..7c11143749 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -1,7 +1,9 @@
> /*
> * QEMU PowerPC PowerNV machine model
> *
> - * Copyright (c) 2016, IBM Corporation.
> + * Copyright (c) 2016-2024, IBM Corporation.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -2639,6 +2641,23 @@ static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format,
> return total_count;
> }
>
> +static int pnv10_xive_broadcast(XiveFabric *xfb,
> + uint8_t nvt_blk, uint32_t nvt_idx,
> + uint8_t priority)
> +{
> + PnvMachineState *pnv = PNV_MACHINE(xfb);
> + int i;
> +
> + for (i = 0; i < pnv->num_chips; i++) {
> + Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
> + XivePresenter *xptr = XIVE_PRESENTER(&chip10->xive);
> + XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
> +
> + xpc->broadcast(xptr, nvt_blk, nvt_idx, priority);
> + }
> + return 0;
> +}
> +
> static bool pnv_machine_get_big_core(Object *obj, Error **errp)
> {
> PnvMachineState *pnv = PNV_MACHINE(obj);
> @@ -2772,6 +2791,7 @@ static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data)
> pmc->dt_power_mgt = pnv_dt_power_mgt;
>
> xfc->match_nvt = pnv10_xive_match_nvt;
> + xfc->broadcast = pnv10_xive_broadcast;
>
> machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
> }
next prev parent reply other threads:[~2025-03-10 4:22 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-10 0:05 [PATCH v2 00/14] XIVE2 changes to support Group and Crowd operations Michael Kowal
2024-12-10 0:05 ` [PATCH v2 01/14] ppc/xive2: Update NVP save/restore for group attributes Michael Kowal
2025-03-10 3:22 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 02/14] ppc/xive2: Add grouping level to notification Michael Kowal
2025-03-10 3:27 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 02/14] ppc/xive: Rename ipb_to_pipr() to xive_ipb_to_pipr() Michael Kowal
2025-03-10 3:45 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 03/14] ppc/xive2: Add grouping level to notification Michael Kowal
2025-03-10 3:43 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 03/14] ppc/xive2: Support group-matching when looking for target Michael Kowal
2025-03-10 3:52 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 04/14] ppc/xive2: Add undelivered group interrupt to backlog Michael Kowal
2024-12-10 0:05 ` [PATCH v2 04/14] ppc/xive2: Support group-matching when looking for target Michael Kowal
2024-12-10 0:05 ` [PATCH v2 05/14] ppc/xive2: Add undelivered group interrupt to backlog Michael Kowal
2025-03-10 4:07 ` Nicholas Piggin [this message]
2024-12-10 0:05 ` [PATCH v2 05/14] ppc/xive2: Process group backlog when pushing an OS context Michael Kowal
2024-12-10 0:05 ` [PATCH v2 06/14] " Michael Kowal
2024-12-10 0:05 ` [PATCH v2 06/14] ppc/xive2: Process group backlog when updating the CPPR Michael Kowal
2024-12-10 0:05 ` [PATCH v2 07/14] " Michael Kowal
2025-03-10 4:35 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 07/14] qtest/xive: Add group-interrupt test Michael Kowal
2024-12-10 0:05 ` [PATCH v2 08/14] Add support for MMIO operations on the NVPG/NVC BAR Michael Kowal
2024-12-10 0:05 ` [PATCH v2 08/14] qtest/xive: Add group-interrupt test Michael Kowal
2025-03-10 4:46 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 09/14] ppc/xive2: Add support for MMIO operations on the NVPG/NVC BAR Michael Kowal
2025-03-10 5:10 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 09/14] ppc/xive2: Support crowd-matching when looking for target Michael Kowal
2024-12-10 0:05 ` [PATCH v2 10/14] ppc/xive2: Check crowd backlog when scanning group backlog Michael Kowal
2024-12-10 0:05 ` [PATCH v2 10/14] ppc/xive2: Support crowd-matching when looking for target Michael Kowal
2025-03-10 7:31 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 11/14] pnv/xive: Only support crowd size of 0, 2, 4 and 16 Michael Kowal
2025-03-10 5:15 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 11/14] ppc/xive2: Check crowd backlog when scanning group backlog Michael Kowal
2025-03-10 7:32 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 12/14] pnv/xive: Support ESB Escalation Michael Kowal
2025-03-10 8:07 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 13/14] pnv/xive: Fix problem with treating NVGC as a NVP Michael Kowal
2025-03-10 5:19 ` Nicholas Piggin
2024-12-10 0:05 ` [PATCH v2 14/14] qtest/xive: Add test of pool interrupts Michael Kowal
2025-03-10 8:20 ` Nicholas Piggin
2025-03-11 13:16 ` [PATCH v2 00/14] XIVE2 changes to support Group and Crowd operations Nicholas Piggin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=D8CAGGO59SN8.F7LMIJ3I6930@gmail.com \
--to=npiggin@gmail.com \
--cc=danielhb413@gmail.com \
--cc=david@gibson.dropbear.id.au \
--cc=fbarrat@linux.ibm.com \
--cc=harshpb@linux.ibm.com \
--cc=kowal@linux.ibm.com \
--cc=lvivier@redhat.com \
--cc=milesg@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).