Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/irqflags: optimize irq restore

The ssm instruction takes longer that stnsm/stosm as it is often
used to modify DAT and PER. We know that irqsave/irqrestore only
deals with external and I/O interrupts and we know that irqrestore
can transition only from disabled->disabled or disabled->enabled,
so we can use the faster stosm.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>

authored by

Christian Borntraeger and committed by
Martin Schwidefsky
204ee2c5 a9d7ab97

+8 -3
+7 -2
arch/s390/include/asm/irqflags.h
··· 8 8 9 9 #include <linux/types.h> 10 10 11 + #define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) 12 + 11 13 /* store then OR system mask. */ 12 14 #define __arch_local_irq_stosm(__or) \ 13 15 ({ \ ··· 56 54 __arch_local_irq_stosm(0x03); 57 55 } 58 56 57 + /* This only restores external and I/O interrupt state */ 59 58 static inline notrace void arch_local_irq_restore(unsigned long flags) 60 59 { 61 - __arch_local_irq_ssm(flags); 60 + /* only disabled->disabled and disabled->enabled is valid */ 61 + if (flags & ARCH_IRQ_ENABLED) 62 + arch_local_irq_enable(); 62 63 } 63 64 64 65 static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) 65 66 { 66 - return !(flags & (3UL << (BITS_PER_LONG - 8))); 67 + return !(flags & ARCH_IRQ_ENABLED); 67 68 } 68 69 69 70 static inline notrace bool arch_irqs_disabled(void)
+1 -1
arch/s390/mm/init.c
··· 98 98 __ctl_load(S390_lowcore.kernel_asce, 1, 1); 99 99 __ctl_load(S390_lowcore.kernel_asce, 7, 7); 100 100 __ctl_load(S390_lowcore.kernel_asce, 13, 13); 101 - arch_local_irq_restore(4UL << (BITS_PER_LONG - 8)); 101 + __arch_local_irq_stosm(0x04); 102 102 103 103 sparse_memory_present_with_active_regions(MAX_NUMNODES); 104 104 sparse_init();