• Miquel Raynal's avatar
    platform-msi: Free descriptors in platform_msi_domain_free() · 81b1e6e6
    Miquel Raynal authored
    Since the addition of platform MSI support, there were two helpers
    supposed to allocate/free IRQs for a device:
    
        platform_msi_domain_alloc_irqs()
        platform_msi_domain_free_irqs()
    
    In these helpers, IRQ descriptors are allocated in the "alloc" routine
    while they are freed in the "free" one.
    
    Later, two other helpers have been added to handle IRQ domains on top
    of MSI domains:
    
        platform_msi_domain_alloc()
        platform_msi_domain_free()
    
    Seen from the outside, the logic is pretty close with the former
    helpers and people used it with the same logic as before: a
    platform_msi_domain_alloc() call should be balanced with a
    platform_msi_domain_free() call. While this is probably what was
    intended to do, the platform_msi_domain_free() does not remove/free
    the IRQ descriptor(s) created/inserted in
    platform_msi_domain_alloc().
    
    One effect of such situation is that removing a module that requested
    an IRQ will let one orphaned IRQ descriptor (with an allocated MSI
    entry) in the device descriptors list. Next time the module will be
    inserted back, one will observe that the allocation will happen twice
    in the MSI domain, one time for the remaining descriptor, one time for
    the new one. It also has the side effect to quickly overshoot the
    maximum number of allocated MSI and then prevent any module requesting
    an interrupt in the same domain to be inserted anymore.
    
    This situation has been met with loops of insertion/removal of the
    mvpp2.ko module (requesting 15 MSIs each time).
    
    Fixes: 552c494a ("platform-msi: Allow creation of a MSI-based stacked irq domain")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    81b1e6e6