cpu-exec: fix missed CPU kick during interrupt injection
The conditional memory barrier not only looks strange but actually is wrong. On s390x, I can reproduce interrupts via cpu_interrupt() not leading to a proper kick out of emulation every now and then. cpu_interrupt() is especially used for inter CPU communication via SIGP (esp. external calls and emergency interrupts). With this patch, I was not able to reproduce. (esp. no stalls or hangs in the guest). My setup is s390x MTTCG with 16 VCPUs on 8 CPU host, running make -j16. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20171129191319.11483-1-david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									ebd05fea9b
								
							
						
					
					
						commit
						d84be02d69
					
				@ -525,19 +525,13 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
 | 
				
			|||||||
                                        TranslationBlock **last_tb)
 | 
					                                        TranslationBlock **last_tb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUClass *cc = CPU_GET_CLASS(cpu);
 | 
					    CPUClass *cc = CPU_GET_CLASS(cpu);
 | 
				
			||||||
    int32_t insns_left;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Clear the interrupt flag now since we're processing
 | 
					    /* Clear the interrupt flag now since we're processing
 | 
				
			||||||
     * cpu->interrupt_request and cpu->exit_request.
 | 
					     * cpu->interrupt_request and cpu->exit_request.
 | 
				
			||||||
 | 
					     * Ensure zeroing happens before reading cpu->exit_request or
 | 
				
			||||||
 | 
					     * cpu->interrupt_request (see also smp_wmb in cpu_exit())
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    insns_left = atomic_read(&cpu->icount_decr.u32);
 | 
					    atomic_mb_set(&cpu->icount_decr.u16.high, 0);
 | 
				
			||||||
    atomic_set(&cpu->icount_decr.u16.high, 0);
 | 
					 | 
				
			||||||
    if (unlikely(insns_left < 0)) {
 | 
					 | 
				
			||||||
        /* Ensure the zeroing of icount_decr comes before the next read
 | 
					 | 
				
			||||||
         * of cpu->exit_request or cpu->interrupt_request.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        smp_mb();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (unlikely(atomic_read(&cpu->interrupt_request))) {
 | 
					    if (unlikely(atomic_read(&cpu->interrupt_request))) {
 | 
				
			||||||
        int interrupt_request;
 | 
					        int interrupt_request;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user