]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/irqchip/irq-gic-v3-its.c
irqchip/gic-v3-its: Don't bind LPI to unavailable NUMA node
[mirror_ubuntu-bionic-kernel.git] / drivers / irqchip / irq-gic-v3-its.c
index 06f025fd5726f6b230d51c880e7b8accf9e8c738..da73b8fea770427f3c4a80445a69bc1f489f2291 100644 (file)
@@ -1412,7 +1412,7 @@ static struct irq_chip its_irq_chip = {
  * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations.
  */
 #define IRQS_PER_CHUNK_SHIFT   5
-#define IRQS_PER_CHUNK         (1 << IRQS_PER_CHUNK_SHIFT)
+#define IRQS_PER_CHUNK         (1UL << IRQS_PER_CHUNK_SHIFT)
 #define ITS_MAX_LPI_NRBITS     16 /* 64K LPIs */
 
 static unsigned long *lpi_bitmap;
@@ -2119,11 +2119,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        /*
-        * At least one bit of EventID is being used, hence a minimum
-        * of two entries. No, the architecture doesn't let you
-        * express an ITT with a single entry.
+        * We allocate at least one chunk worth of LPIs bet device,
+        * and thus that many ITEs. The device may require less though.
         */
-       nr_ites = max(2UL, roundup_pow_of_two(nvecs));
+       nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs));
        sz = nr_ites * its->ite_size;
        sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
        itt = kzalloc(sz, GFP_KERNEL);
@@ -2315,7 +2314,14 @@ static int its_irq_domain_activate(struct irq_domain *domain,
                cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
        /* Bind the LPI to the first possible CPU */
-       cpu = cpumask_first(cpu_mask);
+       cpu = cpumask_first_and(cpu_mask, cpu_online_mask);
+       if (cpu >= nr_cpu_ids) {
+               if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144)
+                       return;
+
+               cpu = cpumask_first(cpu_online_mask);
+       }
+
        its_dev->event_map.col_map[event] = cpu;
        irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
@@ -3314,6 +3320,8 @@ static int __init its_of_probe(struct device_node *node)
 
        for (np = of_find_matching_node(node, its_device_id); np;
             np = of_find_matching_node(np, its_device_id)) {
+               if (!of_device_is_available(np))
+                       continue;
                if (!of_property_read_bool(np, "msi-controller")) {
                        pr_warn("%pOF: no msi-controller property, ITS ignored\n",
                                np);