diff mbox series

[RFC,6/6] xive/p9: Allocate all XIVE structures on a selected chip

Message ID 20200917163544.142593-7-clg@kaod.org
State RFC
Headers show
Series OPAL debugfs calls | expand

Checks

Context Check Description
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (d362ae4f4c521a7faffb1befe2fbba467f2c4d18)

Commit Message

Cédric Le Goater Sept. 17, 2020, 4:35 p.m. UTC
Currently, the NVTs and ENDs are distributed across the chips of the
system. For test and performance, it is interesting to have a better
control on the allocation of the XIVE structures. Introduce a way to
force the allocation of the NVTs, the associated ENDs and the IPIs on
a XIVE preferred chip.

The NVTs and associated ENDs of the HW threads are still allocated on
their respective chip but for all OS interrupt contexts, the XIVE
structures are allocated on the preferred chip.

This behavior can be changed with the debugfs handler.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/xive.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 77 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/hw/xive.c b/hw/xive.c
index abdb2115a1a2..112b837f8a80 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -607,6 +607,7 @@  static uint32_t xive_chip_to_block(uint32_t chip_id)
 static uint32_t xive_chips_alloc_bits = 0;
 static struct buddy *xive_vp_buddy;
 static struct lock xive_buddy_lock = LOCK_UNLOCKED;
+static uint32_t xive_preferred_chip = OPAL_XIVE_ANY_CHIP;
 
 /* VP# decoding/encoding */
 static bool xive_decode_vp(uint32_t vp, uint32_t *blk, uint32_t *idx,
@@ -645,6 +646,9 @@  static bool xive_decode_vp(uint32_t vp, uint32_t *blk, uint32_t *idx,
 	if (blk)
 		*blk = (index >> (o - n)) & ((1 << n) - 1);
 
+	if (xive_preferred_chip != OPAL_XIVE_ANY_CHIP)
+		*blk = xive_chip_to_block(xive_preferred_chip);
+
 	/* Return order as well if asked for */
 	if (order)
 		*order = o;
@@ -1005,13 +1009,24 @@  static bool xive_provision_vp_ind(struct xive *x, uint32_t vp_idx, uint32_t orde
 	return true;
 }
 
+static void xive_init_vp_allocator_chip(uint32_t chip_id)
+{
+	if (chip_id == OPAL_XIVE_ANY_CHIP)  {
+		xive_chips_alloc_bits = ilog2(xive_block_count);
+		prlog(PR_INFO, "XIVE: %d chips considered for VP allocations\n",
+		      1 << xive_chips_alloc_bits);
+	} else {
+		xive_chips_alloc_bits = 0;
+		prlog(PR_INFO, "XIVE: single chip %d considered for VP allocations\n",
+		      chip_id);
+	}
+	xive_preferred_chip = chip_id;
+}
+
 static void xive_init_vp_allocator(void)
 {
 	/* Initialize chip alloc bits */
-	xive_chips_alloc_bits = ilog2(xive_block_count);
-
-	prlog(PR_INFO, "XIVE: %d chips considered for VP allocations\n",
-	      1 << xive_chips_alloc_bits);
+	xive_init_vp_allocator_chip(OPAL_XIVE_ANY_CHIP);
 
 	/* Allocate a buddy big enough for XIVE_VP_ORDER allocations.
 	 *
@@ -1052,7 +1067,9 @@  static uint32_t xive_alloc_vps(uint32_t order)
 
 	/* Provision on every chip considered for allocation */
 	for (i = 0; i < (1 << xive_chips_alloc_bits); i++) {
-		struct xive *x = xive_from_pc_blk(i);
+		uint32_t blk = xive_preferred_chip == OPAL_XIVE_ANY_CHIP ?
+			i : xive_chip_to_block(xive_preferred_chip);
+		struct xive *x = xive_from_pc_blk(blk);
 		bool success;
 
 		/* Return internal error & log rather than assert ? */
@@ -4718,8 +4735,13 @@  static int64_t opal_xive_free_vp_block(uint64_t vp_base)
 		return OPAL_PARAMETER;
 	if (group)
 		return OPAL_PARAMETER;
-	if (blk)
-		return OPAL_PARAMETER;
+	if (xive_preferred_chip == OPAL_XIVE_ANY_CHIP) {
+		if (blk)
+		    return OPAL_PARAMETER;
+	} else {
+		if (blk != xive_chip_to_block(xive_preferred_chip))
+			return OPAL_PARAMETER;
+	}
 	if (order < (xive_chips_alloc_bits + 1))
 		return OPAL_PARAMETER;
 	if (idx & ((1 << (order - xive_chips_alloc_bits)) - 1))
@@ -4913,7 +4935,10 @@  static int64_t opal_xive_allocate_irq(uint32_t chip_id)
 
 	if (chip_id == OPAL_XIVE_ANY_CHIP) {
 		try_all = true;
-		chip_id = this_cpu()->chip_id;
+		if (xive_preferred_chip == OPAL_XIVE_ANY_CHIP)
+			chip_id = this_cpu()->chip_id;
+		else
+			chip_id = xive_preferred_chip;
 	}
 	chip = get_chip(chip_id);
 	if (!chip)
@@ -5464,6 +5489,49 @@  static int xive_stat_write(struct opal_debug *d, void *buf, uint64_t size)
 	}
 }
 
+static int xive_vp_alloc_read(struct opal_debug *d __unused, void *buf,
+			      uint64_t size)
+{
+	int n = 0;
+
+	if (xive_chips_alloc_bits)
+		n += snprintf(buf + n, size - n, "VP allocator : distributed\n");
+	else
+		n += snprintf(buf + n, size - n, "VP allocator : single chip %d\n",
+			      xive_preferred_chip);
+
+	return n;
+}
+
+static int xive_vp_alloc_write(struct opal_debug *d  __unused, void *buf,
+			       uint64_t size)
+{
+	int chip_id;
+
+	if (!strncmp(buf, "distributed", size)) {
+		chip_id = OPAL_XIVE_ANY_CHIP;
+	} else if (!strncmp(buf, "single", size)) {
+		chip_id = 0;
+	} else {
+		char *p = NULL;
+
+		chip_id = strtol(buf, &p, 10);
+		if (*p || p == buf)
+			return OPAL_PARAMETER;
+		if (!get_chip(chip_id))
+			return OPAL_PARAMETER;
+	}
+
+	if (xive_preferred_chip != chip_id)
+		xive_init_vp_allocator_chip(chip_id);
+	return OPAL_SUCCESS;
+}
+
+static const struct opal_debug_ops xive_vp_alloc_ops = {
+	.read = xive_vp_alloc_read,
+	.write = xive_vp_alloc_write,
+};
+
 static const struct opal_debug_ops xive_ivt_ops = {
 	.read = xive_ivt_read,
 };
@@ -5494,6 +5562,7 @@  static const struct {
 	{ "xive-vpt",	&xive_vpt_ops,  },
 	{ "xive-perf",	&xive_perf_ops, },
 	{ "xive-stat",	&xive_stat_ops, },
+	{ "xive-vp-alloc",	&xive_vp_alloc_ops, },
 };
 
 static void xive_init_debug(struct xive *x)