aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-09-10 17:36:07 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-09-12 22:52:08 -0500
commit291d58000b96d39576e4736af939b3ec29e00b88 (patch)
treee9cd3425706486d763367ab46c7a139a1f614391 /hw
parenta87db66d0a9449a8a30a566cd1de7d5465036287 (diff)
downloadskiboot-291d58000b96d39576e4736af939b3ec29e00b88.zip
skiboot-291d58000b96d39576e4736af939b3ec29e00b88.tar.gz
skiboot-291d58000b96d39576e4736af939b3ec29e00b88.tar.bz2
xive: Make opal_xive_allocate_irq() properly try all chips
When requested via OPAL_XIVE_ANY_CHIP, we need to try all chips. We first try the current one (on which the caller sits) and if that fails, we iterate all chips until the allocation succeeds. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xive.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/hw/xive.c b/hw/xive.c
index 0736357..21dd3d9 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -4592,27 +4592,11 @@ static int64_t opal_xive_alloc_vp_block(uint32_t alloc_order)
return rc;
}
-static int64_t opal_xive_allocate_irq(uint32_t chip_id)
+static int64_t xive_try_allocate_irq(struct xive *x)
{
- struct proc_chip *chip;
int idx, base_idx, max_count, girq;
struct xive_ive *ive;
- struct xive *x;
-
- if (xive_mode != XIVE_MODE_EXPL)
- return OPAL_WRONG_STATE;
- /* XXX Make this try multiple chips ... */
- if (chip_id == OPAL_XIVE_ANY_CHIP)
- chip_id = this_cpu()->chip_id;
-
- chip = get_chip(chip_id);
- if (!chip)
- return OPAL_PARAMETER;
- if (!chip->xive)
- return OPAL_PARAMETER;
-
- x = chip->xive;
lock(&x->lock);
base_idx = x->int_ipi_top - x->int_base;
@@ -4642,6 +4626,42 @@ static int64_t opal_xive_allocate_irq(uint32_t chip_id)
return girq;
}
+static int64_t opal_xive_allocate_irq(uint32_t chip_id)
+{
+ struct proc_chip *chip;
+ bool try_all = false;
+ int64_t rc;
+
+ if (xive_mode != XIVE_MODE_EXPL)
+ return OPAL_WRONG_STATE;
+
+ if (chip_id == OPAL_XIVE_ANY_CHIP) {
+ try_all = true;
+ chip_id = this_cpu()->chip_id;
+ }
+ chip = get_chip(chip_id);
+ if (!chip)
+ return OPAL_PARAMETER;
+
+ /* Try initial target chip */
+ if (!chip->xive)
+ rc = OPAL_PARAMETER;
+ else
+ rc = xive_try_allocate_irq(chip->xive);
+ if (rc >= 0 || !try_all)
+ return rc;
+
+ /* Failed and we try all... do so */
+ for_each_chip(chip) {
+ if (!chip->xive)
+ continue;
+ rc = xive_try_allocate_irq(chip->xive);
+ if (rc >= 0)
+ break;
+ }
+ return rc;
+}
+
static int64_t opal_xive_free_irq(uint32_t girq)
{
struct irq_source *is = irq_find_source(girq);