Skip to content
  • Thommy Jakobsson's avatar
    415abcdf
    uio: disable lazy irq disable to avoid double fire · 415abcdf
    Thommy Jakobsson authored
    
    
    uio_pdrv_genirq and uio_dmem_genirq interrupts are handled in
    userspace. So the condition for the interrupt hasn't normally not been
    cleared when top half returns. disable_irq_nosync is called in top half,
    but since that normally is lazy the irq isn't actually disabled.
    
    For level triggered interrupts this will always result in a spurious
    additional fire since the level in to the interrupt controller still is
    active. The actual interrupt handler isn't run though since this
    spurious irq is just recorded, and later on discared (for level).
    
    This commit disables lazy masking for level triggered interrupts. It
    leaves edge triggered interrupts as before, because they work with the
    lazy scheme.
    
    All other UIO drivers already seem to clear the interrupt cause at
    driver levels.
    
    Example of double fire. First goes all the way up to
    uio_pdrv_genirq_handler, second is terminated in handle_fasteoi_irq and
    marked as pending.
    
    <idle>-0 [000] d... 8.245870: gic_handle_irq: irq 29
    <idle>-0 [000] d.h. 8.245873: uio_pdrv_genirq_handler: disable irq 29
    <idle>-0 [000] d... 8.245878: gic_handle_irq: irq 29
    <idle>-0 [000] d.h. 8.245880: handle_fasteoi_irq: irq 29 PENDING
    HInt-34  [001] d... 8.245897: uio_pdrv_genirq_irqcontrol: enable irq 29
    
    Tested on 5.7rc2 using uio_pdrv_genirq and a custom Xilinx MPSoC board.
    
    Signed-off-by: default avatarThommy Jakobsson <thommyj@gmail.com>
    Link: https://lore.kernel.org/r/20200628141229.16121-1-thommyj@gmail.com
    
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    415abcdf
    uio: disable lazy irq disable to avoid double fire
    Thommy Jakobsson authored
    
    
    uio_pdrv_genirq and uio_dmem_genirq interrupts are handled in
    userspace. So the condition for the interrupt hasn't normally not been
    cleared when top half returns. disable_irq_nosync is called in top half,
    but since that normally is lazy the irq isn't actually disabled.
    
    For level triggered interrupts this will always result in a spurious
    additional fire since the level in to the interrupt controller still is
    active. The actual interrupt handler isn't run though since this
    spurious irq is just recorded, and later on discared (for level).
    
    This commit disables lazy masking for level triggered interrupts. It
    leaves edge triggered interrupts as before, because they work with the
    lazy scheme.
    
    All other UIO drivers already seem to clear the interrupt cause at
    driver levels.
    
    Example of double fire. First goes all the way up to
    uio_pdrv_genirq_handler, second is terminated in handle_fasteoi_irq and
    marked as pending.
    
    <idle>-0 [000] d... 8.245870: gic_handle_irq: irq 29
    <idle>-0 [000] d.h. 8.245873: uio_pdrv_genirq_handler: disable irq 29
    <idle>-0 [000] d... 8.245878: gic_handle_irq: irq 29
    <idle>-0 [000] d.h. 8.245880: handle_fasteoi_irq: irq 29 PENDING
    HInt-34  [001] d... 8.245897: uio_pdrv_genirq_irqcontrol: enable irq 29
    
    Tested on 5.7rc2 using uio_pdrv_genirq and a custom Xilinx MPSoC board.
    
    Signed-off-by: default avatarThommy Jakobsson <thommyj@gmail.com>
    Link: https://lore.kernel.org/r/20200628141229.16121-1-thommyj@gmail.com
    
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Loading