KVM: s390: use switch vs jump table in interrupt.c
PATCH 1/1 KVM: s390: use switch vs jump table in interrupt.c
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)
arch/s390/kvm/interrupt.c +50 -34
@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)return kvm_s390_get_cpu_timer (vcpu) >>63 ; } -static inline int is_ioirq (unsigned long irq_type) -{ -return ((irq_type >=IRQ_PEND_IO_ISC_7 ) && - (irq_type <=IRQ_PEND_IO_ISC_0 )); -} -static uint64_t isc_to_isc_bits (int isc) {return (0x80 >> isc) <<24 ;
@@ -1011,24 +1005,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,return rc; } -typedef int (*deliver_irq_t )(struct kvm_vcpu *vcpu); - -static const deliver_irq_t deliver_irq_funcs[] = { - [IRQ_PEND_MCHK_EX ] = __deliver_machine_check, - [IRQ_PEND_MCHK_REP ] = __deliver_machine_check, - [IRQ_PEND_PROG ] = __deliver_prog, - [IRQ_PEND_EXT_EMERGENCY ] = __deliver_emergency_signal, - [IRQ_PEND_EXT_EXTERNAL ] = __deliver_external_call, - [IRQ_PEND_EXT_CLOCK_COMP ] = __deliver_ckc, - [IRQ_PEND_EXT_CPU_TIMER ] = __deliver_cpu_timer, - [IRQ_PEND_RESTART ] = __deliver_restart, - [IRQ_PEND_SET_PREFIX ] = __deliver_set_prefix, - [IRQ_PEND_PFAULT_INIT ] = __deliver_pfault_init, - [IRQ_PEND_EXT_SERVICE ] = __deliver_service, - [IRQ_PEND_PFAULT_DONE ] = __deliver_pfault_done, - [IRQ_PEND_VIRTIO ] = __deliver_virtio, -}; -/* Check whether an external call is pending (deliverable or not) */ int kvm_s390_ext_call_pending (struct kvm_vcpu *vcpu) {
@@ -1192,7 +1168,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)int __must_check kvm_s390_deliver_pending_interrupts (struct kvm_vcpu *vcpu) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -deliver_irq_t func;int rc =0 ;unsigned long irq_type;unsigned long irqs;
@@ -1212,16 +1187,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)while ((irqs =deliverable_irqs (vcpu)) && !rc) {/* bits are in the reverse order of interrupt priority */ irq_type =find_last_bit (&irqs,IRQ_PEND_COUNT ); -if (is_ioirq (irq_type)) { +switch (irq_type) { +case IRQ_PEND_IO_ISC_0 : +case IRQ_PEND_IO_ISC_1 : +case IRQ_PEND_IO_ISC_2 : +case IRQ_PEND_IO_ISC_3 : +case IRQ_PEND_IO_ISC_4 : +case IRQ_PEND_IO_ISC_5 : +case IRQ_PEND_IO_ISC_6 : +case IRQ_PEND_IO_ISC_7 : rc =__deliver_io (vcpu, irq_type); - }else { - func = deliver_irq_funcs[irq_type]; -if (!func) { -WARN_ON_ONCE (func ==NULL ); -clear_bit (irq_type, &li->pending_irqs); -continue ; - } - rc =func (vcpu); +break ; +case IRQ_PEND_MCHK_EX : +case IRQ_PEND_MCHK_REP : + rc =__deliver_machine_check (vcpu); +break ; +case IRQ_PEND_PROG : + rc =__deliver_prog (vcpu); +break ; +case IRQ_PEND_EXT_EMERGENCY : + rc =__deliver_emergency_signal (vcpu); +break ; +case IRQ_PEND_EXT_EXTERNAL : + rc =__deliver_external_call (vcpu); +break ; +case IRQ_PEND_EXT_CLOCK_COMP : + rc =__deliver_ckc (vcpu); +break ; +case IRQ_PEND_EXT_CPU_TIMER : + rc =__deliver_cpu_timer (vcpu); +break ; +case IRQ_PEND_RESTART : + rc =__deliver_restart (vcpu); +break ; +case IRQ_PEND_SET_PREFIX : + rc =__deliver_set_prefix (vcpu); +break ; +case IRQ_PEND_PFAULT_INIT : + rc =__deliver_pfault_init (vcpu); +break ; +case IRQ_PEND_EXT_SERVICE : + rc =__deliver_service (vcpu); +break ; +case IRQ_PEND_PFAULT_DONE : + rc =__deliver_pfault_done (vcpu); +break ; +case IRQ_PEND_VIRTIO : + rc =__deliver_virtio (vcpu); +break ; +default : +WARN_ONCE (1 ,"Unknown pending irq type %ld" , irq_type); +clear_bit (irq_type, &li->pending_irqs); } }
Signature · 1 line
2.14.3
Quoted 2 lines · On Tue, 6 Feb 2018 15:17:43 +0100 David Hildenbrand <[email protected]> wrote:
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
Amusingly, we did have a switch/case in the past :)
Nice that we can get rid of the I/O interrupt special casing.
Quoted 5 lines
Signed-off-by David Hildenbrand <[email protected]>--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)
I see a minimal regression for uperf 1byte ping pong between two guests (~3%) Probably because the old code first handled IO interrupts and then did the remaing stuff. Not sure if its worth to keep the old io_ioirq hack.
Other than that this looks good.
Quoted 125 lines · David Hildenbrand
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
Signed-off-by David Hildenbrand <[email protected]>--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)arch/s390/kvm/interrupt.c +50
-34@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)return kvm_s390_get_cpu_timer (vcpu) >>63 ; } -static inline int is_ioirq (unsigned long irq_type) -{ -return ((irq_type >=IRQ_PEND_IO_ISC_7 ) && - (irq_type <=IRQ_PEND_IO_ISC_0 )); -} -static uint64_t isc_to_isc_bits (int isc) {return (0x80 >> isc) <<24 ;@@ -1011,24 +1005,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,return rc; } -typedef int (*deliver_irq_t )(struct kvm_vcpu *vcpu); - -static const deliver_irq_t deliver_irq_funcs[] = { - [IRQ_PEND_MCHK_EX ] = __deliver_machine_check, - [IRQ_PEND_MCHK_REP ] = __deliver_machine_check, - [IRQ_PEND_PROG ] = __deliver_prog, - [IRQ_PEND_EXT_EMERGENCY ] = __deliver_emergency_signal, - [IRQ_PEND_EXT_EXTERNAL ] = __deliver_external_call, - [IRQ_PEND_EXT_CLOCK_COMP ] = __deliver_ckc, - [IRQ_PEND_EXT_CPU_TIMER ] = __deliver_cpu_timer, - [IRQ_PEND_RESTART ] = __deliver_restart, - [IRQ_PEND_SET_PREFIX ] = __deliver_set_prefix, - [IRQ_PEND_PFAULT_INIT ] = __deliver_pfault_init, - [IRQ_PEND_EXT_SERVICE ] = __deliver_service, - [IRQ_PEND_PFAULT_DONE ] = __deliver_pfault_done, - [IRQ_PEND_VIRTIO ] = __deliver_virtio, -}; -/* Check whether an external call is pending (deliverable or not) */ int kvm_s390_ext_call_pending (struct kvm_vcpu *vcpu) {@@ -1192,7 +1168,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)int __must_check kvm_s390_deliver_pending_interrupts (struct kvm_vcpu *vcpu) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -deliver_irq_t func;int rc =0 ;unsigned long irq_type;unsigned long irqs;@@ -1212,16 +1187,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)while ((irqs =deliverable_irqs (vcpu)) && !rc) {/* bits are in the reverse order of interrupt priority */ irq_type =find_last_bit (&irqs,IRQ_PEND_COUNT ); -if (is_ioirq (irq_type)) { +switch (irq_type) { +case IRQ_PEND_IO_ISC_0 : +case IRQ_PEND_IO_ISC_1 : +case IRQ_PEND_IO_ISC_2 : +case IRQ_PEND_IO_ISC_3 : +case IRQ_PEND_IO_ISC_4 : +case IRQ_PEND_IO_ISC_5 : +case IRQ_PEND_IO_ISC_6 : +case IRQ_PEND_IO_ISC_7 : rc =__deliver_io (vcpu, irq_type); - }else { - func = deliver_irq_funcs[irq_type]; -if (!func) { -WARN_ON_ONCE (func ==NULL ); -clear_bit (irq_type, &li->pending_irqs); -continue ; - } - rc =func (vcpu); +break ; +case IRQ_PEND_MCHK_EX : +case IRQ_PEND_MCHK_REP : + rc =__deliver_machine_check (vcpu); +break ; +case IRQ_PEND_PROG : + rc =__deliver_prog (vcpu); +break ; +case IRQ_PEND_EXT_EMERGENCY : + rc =__deliver_emergency_signal (vcpu); +break ; +case IRQ_PEND_EXT_EXTERNAL : + rc =__deliver_external_call (vcpu); +break ; +case IRQ_PEND_EXT_CLOCK_COMP : + rc =__deliver_ckc (vcpu); +break ; +case IRQ_PEND_EXT_CPU_TIMER : + rc =__deliver_cpu_timer (vcpu); +break ; +case IRQ_PEND_RESTART : + rc =__deliver_restart (vcpu); +break ; +case IRQ_PEND_SET_PREFIX : + rc =__deliver_set_prefix (vcpu); +break ; +case IRQ_PEND_PFAULT_INIT : + rc =__deliver_pfault_init (vcpu); +break ; +case IRQ_PEND_EXT_SERVICE : + rc =__deliver_service (vcpu); +break ; +case IRQ_PEND_PFAULT_DONE : + rc =__deliver_pfault_done (vcpu); +break ; +case IRQ_PEND_VIRTIO : + rc =__deliver_virtio (vcpu); +break ; +default : +WARN_ONCE (1 ,"Unknown pending irq type %ld" , irq_type); +clear_bit (irq_type, &li->pending_irqs); } }
Quoted 3 lines · On Wed, 7 Feb 2018 19:28:04 +0100 Christian Borntraeger…
I see a minimal regression for uperf 1byte ping pong between two guests (~3%) Probably because the old code first handled IO interrupts and then did the remaing stuff. Not sure if its worth to keep the old
io_ioirqhack.
Hm, that confuses me a bit. We search the pending bit map, which should give us the irq with the highest priority, and the switch/case still starts out with I/O interrupts.
Quoted 131 lines
Other than that this looks good.
Quoted 125 lines · David Hildenbrand
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
Signed-off-by David Hildenbrand <[email protected]>--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)arch/s390/kvm/interrupt.c +50
-34@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)return kvm_s390_get_cpu_timer (vcpu) >>63 ; } -static inline int is_ioirq (unsigned long irq_type) -{ -return ((irq_type >=IRQ_PEND_IO_ISC_7 ) && - (irq_type <=IRQ_PEND_IO_ISC_0 )); -} -static uint64_t isc_to_isc_bits (int isc) {return (0x80 >> isc) <<24 ;@@ -1011,24 +1005,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,return rc; } -typedef int (*deliver_irq_t )(struct kvm_vcpu *vcpu); - -static const deliver_irq_t deliver_irq_funcs[] = { - [IRQ_PEND_MCHK_EX ] = __deliver_machine_check, - [IRQ_PEND_MCHK_REP ] = __deliver_machine_check, - [IRQ_PEND_PROG ] = __deliver_prog, - [IRQ_PEND_EXT_EMERGENCY ] = __deliver_emergency_signal, - [IRQ_PEND_EXT_EXTERNAL ] = __deliver_external_call, - [IRQ_PEND_EXT_CLOCK_COMP ] = __deliver_ckc, - [IRQ_PEND_EXT_CPU_TIMER ] = __deliver_cpu_timer, - [IRQ_PEND_RESTART ] = __deliver_restart, - [IRQ_PEND_SET_PREFIX ] = __deliver_set_prefix, - [IRQ_PEND_PFAULT_INIT ] = __deliver_pfault_init, - [IRQ_PEND_EXT_SERVICE ] = __deliver_service, - [IRQ_PEND_PFAULT_DONE ] = __deliver_pfault_done, - [IRQ_PEND_VIRTIO ] = __deliver_virtio, -}; -/* Check whether an external call is pending (deliverable or not) */ int kvm_s390_ext_call_pending (struct kvm_vcpu *vcpu) {@@ -1192,7 +1168,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)int __must_check kvm_s390_deliver_pending_interrupts (struct kvm_vcpu *vcpu) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -deliver_irq_t func;int rc =0 ;unsigned long irq_type;unsigned long irqs;@@ -1212,16 +1187,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)while ((irqs =deliverable_irqs (vcpu)) && !rc) {/* bits are in the reverse order of interrupt priority */ irq_type =find_last_bit (&irqs,IRQ_PEND_COUNT ); -if (is_ioirq (irq_type)) { +switch (irq_type) { +case IRQ_PEND_IO_ISC_0 : +case IRQ_PEND_IO_ISC_1 : +case IRQ_PEND_IO_ISC_2 : +case IRQ_PEND_IO_ISC_3 : +case IRQ_PEND_IO_ISC_4 : +case IRQ_PEND_IO_ISC_5 : +case IRQ_PEND_IO_ISC_6 : +case IRQ_PEND_IO_ISC_7 : rc =__deliver_io (vcpu, irq_type); - }else { - func = deliver_irq_funcs[irq_type]; -if (!func) { -WARN_ON_ONCE (func ==NULL ); -clear_bit (irq_type, &li->pending_irqs); -continue ; - } - rc =func (vcpu); +break ; +case IRQ_PEND_MCHK_EX : +case IRQ_PEND_MCHK_REP : + rc =__deliver_machine_check (vcpu); +break ; +case IRQ_PEND_PROG : + rc =__deliver_prog (vcpu); +break ; +case IRQ_PEND_EXT_EMERGENCY : + rc =__deliver_emergency_signal (vcpu); +break ; +case IRQ_PEND_EXT_EXTERNAL : + rc =__deliver_external_call (vcpu); +break ; +case IRQ_PEND_EXT_CLOCK_COMP : + rc =__deliver_ckc (vcpu); +break ; +case IRQ_PEND_EXT_CPU_TIMER : + rc =__deliver_cpu_timer (vcpu); +break ; +case IRQ_PEND_RESTART : + rc =__deliver_restart (vcpu); +break ; +case IRQ_PEND_SET_PREFIX : + rc =__deliver_set_prefix (vcpu); +break ; +case IRQ_PEND_PFAULT_INIT : + rc =__deliver_pfault_init (vcpu); +break ; +case IRQ_PEND_EXT_SERVICE : + rc =__deliver_service (vcpu); +break ; +case IRQ_PEND_PFAULT_DONE : + rc =__deliver_pfault_done (vcpu); +break ; +case IRQ_PEND_VIRTIO : + rc =__deliver_virtio (vcpu); +break ; +default : +WARN_ONCE (1 ,"Unknown pending irq type %ld" , irq_type); +clear_bit (irq_type, &li->pending_irqs); } }
Quoted 10 lines · Cornelia Huck
Quoted 3 lines · On Wed, 7 Feb 2018 19:28:04 +0100 Christian Borntraeger…
I see a minimal regression for uperf 1byte ping pong between two guests (~3%) Probably because the old code first handled IO interrupts and then did the remaing stuff. Not sure if its worth to keep the old
io_ioirqhack.Hm, that confuses me a bit. We search the pending bit map, which should give us the irq with the highest priority, and the switch/case still starts out with I/O interrupts.
gcc does not obey the order of the case statements. It uses several heuristics depending on the size and others. So gcc might fall back to jump tables for large switches, or it uses bisecting or it might even split the search into a jump table and several relative branches if there are strange distributions. Quite often the default case is evaulated first.
Quoted 12 lines · On Thu, 8 Feb 2018 10:53:00 +0100 Christian Borntraeger…
Quoted 10 lines · Cornelia Huck
Quoted 3 lines · On Wed, 7 Feb 2018 19:28:04 +0100 Christian Borntraeger…
I see a minimal regression for uperf 1byte ping pong between two guests (~3%) Probably because the old code first handled IO interrupts and then did the remaing stuff. Not sure if its worth to keep the old
io_ioirqhack.Hm, that confuses me a bit. We search the pending bit map, which should give us the irq with the highest priority, and the switch/case still starts out with I/O interrupts.
Quoted 5 lines
gcc does not obey the order of the case statements. It uses several heuristics depending on the size and others. So gcc might fall back to jump tables for large switches, or it uses bisecting or it might even split the search into a jump table and several relative branches if there are strange distributions. Quite often the default case is evaulated first.
But should we really try to optimize something that may change with a different compiler anyway? The important thing is the priority in the bitmap.
Quoted 21 lines · Cornelia Huck
Quoted 12 lines · On Thu, 8 Feb 2018 10:53:00 +0100 Christian Borntraeger…
Quoted 10 lines · Cornelia Huck
Quoted 3 lines · On Wed, 7 Feb 2018 19:28:04 +0100 Christian Borntraeger…
I see a minimal regression for uperf 1byte ping pong between two guests (~3%) Probably because the old code first handled IO interrupts and then did the remaing stuff. Not sure if its worth to keep the old
io_ioirqhack.Hm, that confuses me a bit. We search the pending bit map, which should give us the irq with the highest priority, and the switch/case still starts out with I/O interrupts.
Quoted 5 lines
gcc does not obey the order of the case statements. It uses several heuristics depending on the size and others. So gcc might fall back to jump tables for large switches, or it uses bisecting or it might even split the search into a jump table and several relative branches if there are strange distributions. Quite often the default case is evaulated first.
Quoted 3 lines
But should we really try to optimize something that may change with a different compiler anyway? The important thing is the priority in the bitmap.
An if before the switch would always prefer that condition. But I agree,we should probably not go down this path of micro optimization.
Quoted 4 lines · David Hildenbrand
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
Signed-off-by David Hildenbrand <[email protected]>
Quoted 121 lines
--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)arch/s390/kvm/interrupt.c +50
-34@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)return kvm_s390_get_cpu_timer (vcpu) >>63 ; } -static inline int is_ioirq (unsigned long irq_type) -{ -return ((irq_type >=IRQ_PEND_IO_ISC_7 ) && - (irq_type <=IRQ_PEND_IO_ISC_0 )); -} -static uint64_t isc_to_isc_bits (int isc) {return (0x80 >> isc) <<24 ;@@ -1011,24 +1005,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,return rc; } -typedef int (*deliver_irq_t )(struct kvm_vcpu *vcpu); - -static const deliver_irq_t deliver_irq_funcs[] = { - [IRQ_PEND_MCHK_EX ] = __deliver_machine_check, - [IRQ_PEND_MCHK_REP ] = __deliver_machine_check, - [IRQ_PEND_PROG ] = __deliver_prog, - [IRQ_PEND_EXT_EMERGENCY ] = __deliver_emergency_signal, - [IRQ_PEND_EXT_EXTERNAL ] = __deliver_external_call, - [IRQ_PEND_EXT_CLOCK_COMP ] = __deliver_ckc, - [IRQ_PEND_EXT_CPU_TIMER ] = __deliver_cpu_timer, - [IRQ_PEND_RESTART ] = __deliver_restart, - [IRQ_PEND_SET_PREFIX ] = __deliver_set_prefix, - [IRQ_PEND_PFAULT_INIT ] = __deliver_pfault_init, - [IRQ_PEND_EXT_SERVICE ] = __deliver_service, - [IRQ_PEND_PFAULT_DONE ] = __deliver_pfault_done, - [IRQ_PEND_VIRTIO ] = __deliver_virtio, -}; -/* Check whether an external call is pending (deliverable or not) */ int kvm_s390_ext_call_pending (struct kvm_vcpu *vcpu) {@@ -1192,7 +1168,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)int __must_check kvm_s390_deliver_pending_interrupts (struct kvm_vcpu *vcpu) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -deliver_irq_t func;int rc =0 ;unsigned long irq_type;unsigned long irqs;@@ -1212,16 +1187,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)while ((irqs =deliverable_irqs (vcpu)) && !rc) {/* bits are in the reverse order of interrupt priority */ irq_type =find_last_bit (&irqs,IRQ_PEND_COUNT ); -if (is_ioirq (irq_type)) { +switch (irq_type) { +case IRQ_PEND_IO_ISC_0 : +case IRQ_PEND_IO_ISC_1 : +case IRQ_PEND_IO_ISC_2 : +case IRQ_PEND_IO_ISC_3 : +case IRQ_PEND_IO_ISC_4 : +case IRQ_PEND_IO_ISC_5 : +case IRQ_PEND_IO_ISC_6 : +case IRQ_PEND_IO_ISC_7 : rc =__deliver_io (vcpu, irq_type); - }else { - func = deliver_irq_funcs[irq_type]; -if (!func) { -WARN_ON_ONCE (func ==NULL ); -clear_bit (irq_type, &li->pending_irqs); -continue ; - } - rc =func (vcpu); +break ; +case IRQ_PEND_MCHK_EX : +case IRQ_PEND_MCHK_REP : + rc =__deliver_machine_check (vcpu); +break ; +case IRQ_PEND_PROG : + rc =__deliver_prog (vcpu); +break ; +case IRQ_PEND_EXT_EMERGENCY : + rc =__deliver_emergency_signal (vcpu); +break ; +case IRQ_PEND_EXT_EXTERNAL : + rc =__deliver_external_call (vcpu); +break ; +case IRQ_PEND_EXT_CLOCK_COMP : + rc =__deliver_ckc (vcpu); +break ; +case IRQ_PEND_EXT_CPU_TIMER : + rc =__deliver_cpu_timer (vcpu); +break ; +case IRQ_PEND_RESTART : + rc =__deliver_restart (vcpu); +break ; +case IRQ_PEND_SET_PREFIX : + rc =__deliver_set_prefix (vcpu); +break ; +case IRQ_PEND_PFAULT_INIT : + rc =__deliver_pfault_init (vcpu); +break ; +case IRQ_PEND_EXT_SERVICE : + rc =__deliver_service (vcpu); +break ; +case IRQ_PEND_PFAULT_DONE : + rc =__deliver_pfault_done (vcpu); +break ; +case IRQ_PEND_VIRTIO : + rc =__deliver_virtio (vcpu); +break ; +default : +WARN_ONCE (1 ,"Unknown pending irq type %ld" , irq_type); +clear_bit (irq_type, &li->pending_irqs); } }
Christian Borntraeger
AppliedQuoted 4 lines · David Hildenbrand
Just like for the interception handlers, let's also use a switch-case in our interrupt delivery code.
Signed-off-by David Hildenbrand <[email protected]>
Thanks applied.
Quoted 121 lines
--- arch/s390/kvm/interrupt.c | 84 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 34 deletions(-)arch/s390/kvm/interrupt.c +50
-34@@ -187,12 +187,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)return kvm_s390_get_cpu_timer (vcpu) >>63 ; } -static inline int is_ioirq (unsigned long irq_type) -{ -return ((irq_type >=IRQ_PEND_IO_ISC_7 ) && - (irq_type <=IRQ_PEND_IO_ISC_0 )); -} -static uint64_t isc_to_isc_bits (int isc) {return (0x80 >> isc) <<24 ;@@ -1011,24 +1005,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,return rc; } -typedef int (*deliver_irq_t )(struct kvm_vcpu *vcpu); - -static const deliver_irq_t deliver_irq_funcs[] = { - [IRQ_PEND_MCHK_EX ] = __deliver_machine_check, - [IRQ_PEND_MCHK_REP ] = __deliver_machine_check, - [IRQ_PEND_PROG ] = __deliver_prog, - [IRQ_PEND_EXT_EMERGENCY ] = __deliver_emergency_signal, - [IRQ_PEND_EXT_EXTERNAL ] = __deliver_external_call, - [IRQ_PEND_EXT_CLOCK_COMP ] = __deliver_ckc, - [IRQ_PEND_EXT_CPU_TIMER ] = __deliver_cpu_timer, - [IRQ_PEND_RESTART ] = __deliver_restart, - [IRQ_PEND_SET_PREFIX ] = __deliver_set_prefix, - [IRQ_PEND_PFAULT_INIT ] = __deliver_pfault_init, - [IRQ_PEND_EXT_SERVICE ] = __deliver_service, - [IRQ_PEND_PFAULT_DONE ] = __deliver_pfault_done, - [IRQ_PEND_VIRTIO ] = __deliver_virtio, -}; -/* Check whether an external call is pending (deliverable or not) */ int kvm_s390_ext_call_pending (struct kvm_vcpu *vcpu) {@@ -1192,7 +1168,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)int __must_check kvm_s390_deliver_pending_interrupts (struct kvm_vcpu *vcpu) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -deliver_irq_t func;int rc =0 ;unsigned long irq_type;unsigned long irqs;@@ -1212,16 +1187,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)while ((irqs =deliverable_irqs (vcpu)) && !rc) {/* bits are in the reverse order of interrupt priority */ irq_type =find_last_bit (&irqs,IRQ_PEND_COUNT ); -if (is_ioirq (irq_type)) { +switch (irq_type) { +case IRQ_PEND_IO_ISC_0 : +case IRQ_PEND_IO_ISC_1 : +case IRQ_PEND_IO_ISC_2 : +case IRQ_PEND_IO_ISC_3 : +case IRQ_PEND_IO_ISC_4 : +case IRQ_PEND_IO_ISC_5 : +case IRQ_PEND_IO_ISC_6 : +case IRQ_PEND_IO_ISC_7 : rc =__deliver_io (vcpu, irq_type); - }else { - func = deliver_irq_funcs[irq_type]; -if (!func) { -WARN_ON_ONCE (func ==NULL ); -clear_bit (irq_type, &li->pending_irqs); -continue ; - } - rc =func (vcpu); +break ; +case IRQ_PEND_MCHK_EX : +case IRQ_PEND_MCHK_REP : + rc =__deliver_machine_check (vcpu); +break ; +case IRQ_PEND_PROG : + rc =__deliver_prog (vcpu); +break ; +case IRQ_PEND_EXT_EMERGENCY : + rc =__deliver_emergency_signal (vcpu); +break ; +case IRQ_PEND_EXT_EXTERNAL : + rc =__deliver_external_call (vcpu); +break ; +case IRQ_PEND_EXT_CLOCK_COMP : + rc =__deliver_ckc (vcpu); +break ; +case IRQ_PEND_EXT_CPU_TIMER : + rc =__deliver_cpu_timer (vcpu); +break ; +case IRQ_PEND_RESTART : + rc =__deliver_restart (vcpu); +break ; +case IRQ_PEND_SET_PREFIX : + rc =__deliver_set_prefix (vcpu); +break ; +case IRQ_PEND_PFAULT_INIT : + rc =__deliver_pfault_init (vcpu); +break ; +case IRQ_PEND_EXT_SERVICE : + rc =__deliver_service (vcpu); +break ; +case IRQ_PEND_PFAULT_DONE : + rc =__deliver_pfault_done (vcpu); +break ; +case IRQ_PEND_VIRTIO : + rc =__deliver_virtio (vcpu); +break ; +default : +WARN_ONCE (1 ,"Unknown pending irq type %ld" , irq_type); +clear_bit (irq_type, &li->pending_irqs); } }