diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 6f5811aae59c..f324d3df56c0 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -2108,11 +2108,15 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span) { struct lpi_range *range; - range = kmalloc_obj(*range); - if (range) { - range->base_id = base; - range->span = span; - } + /* + * Handing a range back is not allowed to fail: the callers of + * free_lpi_range() have no way of reporting an error, and losing the + * range here would leak the LPIs for good. This is a small, order-0 + * request and lpi_range_lock is a mutex, so the context is sleepable. + */ + range = kmalloc_obj(*range, GFP_KERNEL | __GFP_NOFAIL); + range->base_id = base; + range->span = span; return range; } @@ -2158,13 +2162,11 @@ static void merge_lpi_ranges(struct lpi_range *a, struct lpi_range *b) kfree(a); } -static int free_lpi_range(u32 base, u32 nr_lpis) +static void free_lpi_range(u32 base, u32 nr_lpis) { struct lpi_range *new, *old; new = mk_lpi_range(base, nr_lpis); - if (!new) - return -ENOMEM; mutex_lock(&lpi_range_lock); @@ -2188,14 +2190,12 @@ static int free_lpi_range(u32 base, u32 nr_lpis) merge_lpi_ranges(new, list_next_entry(new, entry)); mutex_unlock(&lpi_range_lock); - return 0; } -static int __init its_lpi_init(u32 id_bits) +static void __init its_lpi_init(u32 id_bits) { u32 lpis = (1UL << id_bits) - 8192; u32 numlpis; - int err; numlpis = 1UL << GICD_TYPER_NUM_LPIS(gic_rdists->gicd_typer); @@ -2209,9 +2209,8 @@ static int __init its_lpi_init(u32 id_bits) * Initializing the allocator is just the same as freeing the * full range of LPIs. */ - err = free_lpi_range(8192, lpis); + free_lpi_range(8192, lpis); pr_debug("ITS: Allocator initialized for %u LPIs\n", lpis); - return err; } static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) @@ -2248,7 +2247,7 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids) { - WARN_ON(free_lpi_range(base, nr_ids)); + free_lpi_range(base, nr_ids); bitmap_free(bitmap); } @@ -2349,7 +2348,9 @@ static int __init its_setup_lpi_prop_table(void) pr_info("GICv3: using LPI property table @%pa\n", &gic_rdists->prop_table_pa); - return its_lpi_init(lpi_id_bits); + its_lpi_init(lpi_id_bits); + + return 0; } static const char *its_base_type_string[] = {