[Skiboot] [PATCH 25/60] xive: Add API to donate pages in indirect mode
Benjamin Herrenschmidt
benh at kernel.crashing.org
Thu Dec 22 14:16:33 AEDT 2016
This allows the OS to donate pagess to XIVE for VP and EQ
allocation
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
hw/xive.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/hw/xive.c b/hw/xive.c
index d6e4218..4f755aa 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -344,6 +344,11 @@ struct xive {
#else
void *vp_base;
#endif
+#ifdef USE_INDIRECT
+ /* Pool of donated pages for provisioning indirect EQ and VP pages */
+ struct list_head donated_pages;
+#endif
+
/* To ease a possible change to supporting more than one block of
* interrupts per chip, we store here the "base" global number
* and max number of interrupts for this chip. The global number
@@ -653,6 +658,13 @@ static uint32_t *xive_get_eq_buf(uint32_t eq_blk, uint32_t eq_idx)
return (uint32_t *)addr;
}
+#ifdef USE_INDIRECT
+static void *xive_get_donated_page(struct xive *x __unused)
+{
+ return (void *)list_pop_(&x->donated_pages, 0);
+}
+#endif
+
#define XIVE_ALLOC_IS_ERR(_idx) ((_idx) >= 0xfffffff0)
#define XIVE_ALLOC_NO_SPACE 0xffffffff /* No possible space */
@@ -704,13 +716,19 @@ static uint32_t xive_alloc_eq_set(struct xive *x, bool alloc_indirect __unused)
}
vsd_flags |= VSD_FIRMWARE;
} else {
- return XIVE_ALLOC_NO_IND;
+ xive_dbg(x, "Indirect empty, provisioning from donated pages\n");
+ page = xive_get_donated_page(x);
+ if (!page) {
+ xive_dbg(x, "none available !\n");
+ return XIVE_ALLOC_NO_IND;
+ }
}
memset(page, 0, 0x10000);
x->eq_ind_base[ind_idx] = vsd_flags | (((uint64_t)page) & VSD_ADDRESS_MASK);
/* Any cache scrub needed ? */
}
-#endif
+#endif /* USE_INDIRECT */
+
return idx;
}
@@ -2004,6 +2022,9 @@ static void init_one_xive(struct dt_node *np)
xive_dbg(x, "Initializing...\n");
chip->xive = x;
+#ifdef USE_INDIRECT
+ list_head_init(&x->donated_pages);
+#endif
/* Base interrupt numbers and allocator init */
/* XXX Consider allocating half as many ESBs than MMIO space
* so that HW sources land outside of ESB space...
@@ -2727,6 +2748,26 @@ static int64_t opal_xive_set_irq_config(uint32_t girq,
return OPAL_SUCCESS;
}
+static int64_t opal_xive_donate_page(uint32_t chip_id, uint64_t addr)
+{
+ struct proc_chip *c = get_chip(chip_id);
+ struct list_node *n __unused;
+
+ if (!c)
+ return OPAL_PARAMETER;
+ if (!c->xive)
+ return OPAL_PARAMETER;
+ if (addr & 0xffff)
+ return OPAL_PARAMETER;
+#ifdef USE_INDIRECT
+ n = (struct list_node *)addr;
+ lock(&c->xive->lock);
+ list_add(&c->xive->donated_pages, n);
+ unlock(&c->xive->lock);
+#endif
+ return OPAL_SUCCESS;
+}
+
static void xive_init_globals(void)
{
uint32_t i;
@@ -2784,5 +2825,6 @@ void init_xive(void)
opal_register(OPAL_XIVE_GET_IRQ_INFO, opal_xive_get_irq_info, 6);
opal_register(OPAL_XIVE_GET_IRQ_CONFIG, opal_xive_get_irq_config, 4);
opal_register(OPAL_XIVE_SET_IRQ_CONFIG, opal_xive_set_irq_config, 4);
+ opal_register(OPAL_XIVE_DONATE_PAGE, opal_xive_donate_page, 2);
}
--
2.9.3
More information about the Skiboot
mailing list