On 05/09/2019 14:26, John Garry wrote:
On 05/09/2019 12:22, Marc Zyngier wrote:
OK, debug was slightly off, but it is interesting that the driver didn't
unmap the device, either because it is flagged as shared (with what?) or
that additional interrupts are allocated in the lpi_map for this
instance.
Here's an updated debug patch. Can you please run the same thing again?
As requested:
root@(none)$ echo 0000:74:02.0 > ./sys/bus/pci/drivers/hisi_sas_v3_hw/unbind
<snip>
[ 78.593897] Freed devid 7410 event 0 LPI 0
[ 78.597990] Freed devid 7410 event 1 LPI 0
[ 78.602080] Freed devid 7410 event 2 LPI 0
[ 78.606169] Freed devid 7410 event 3 LPI 0
[ 78.610253] Freed devid 7410 event 4 LPI 0
[ 78.614337] Freed devid 7410 event 5 LPI 0
[ 78.618422] Freed devid 7410 event 6 LPI 0
[ 78.622506] Freed devid 7410 event 7 LPI 0
[ 78.626590] Freed devid 7410 event 8 LPI 0
[ 78.630674] Freed devid 7410 event 9 LPI 0
[ 78.634758] Freed devid 7410 event 10 LPI 0
[ 78.638930] Freed devid 7410 event 11 LPI 0
[ 78.643101] Freed devid 7410 event 12 LPI 0
[ 78.647272] Freed devid 7410 event 13 LPI 0
[ 78.651445] Freed devid 7410 event 14 LPI 0
[ 78.655616] Freed devid 7410 event 15 LPI 0
[ 78.659787] Freed devid 7410 event 16 LPI 0
[ 78.663959] Unmap devid 7410 shared 0 lpi_map 17-31
Bah. Try this for size...
M.
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1b5c3672aea2..c3a8d732805f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2641,14 +2641,13 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
struct its_node *its = its_dev->its;
int i;
+ bitmap_release_region(its_dev->event_map.lpi_map,
+ its_get_event_id(irq_domain_get_irq_data(domain, virq)),
+ get_count_order(nr_irqs));
+
for (i = 0; i < nr_irqs; i++) {
struct irq_data *data = irq_domain_get_irq_data(domain,
virq + i);
- u32 event = its_get_event_id(data);
-
- /* Mark interrupt index as unused */
- clear_bit(event, its_dev->event_map.lpi_map);
-
/* Nuke the entry in the domain */
irq_domain_reset_irq_data(data);
}