• David S. Miller's avatar
    [SPARC64]: Fix bugs in SUN4V cpu mondo dispatch. · b830ab66
    David S. Miller authored
    There were several bugs in the SUN4V cpu mondo dispatch code.
    
    In fact, if we ever got a EWOULDBLOCK or other error from
    the hypervisor call, we'd potentially send a cpu mondo multiple
    times to the same cpu and even worse we could loop until the
    timeout resending the same mondo over and over to such cpus.
    
    So let's bulletproof this thing as follows:
    
    1) Implement cpu_mondo_send() and cpu_state() hypervisor calls
       in arch/sparc64/kernel/entry.S, add prototypes to asm/hypervisor.h
    
    2) Don't build and update the cpulist using inline functions, this
       was causing the cpu mask to not get updated in the caller.
    
    3) Disable interrupts during the entire mondo send, otherwise our
       cpu list and/or mondo block could get overwritten if we take
       an interrupt and do a cpu mondo send on the current cpu.
    
    4) Check for all possible error return types from the cpu_mondo_send()
       hypervisor call.  In particular:
    
       HV_EOK) Our work is done, all cpus have received the mondo.
       HV_CPUERROR) One or more of the cpus in the cpu list we passed
                    to the hypervisor are in error state.  Use cpu_state()
                    calls over the entries in the cpu list to see which
    		ones.  Record them in "error_mask" and report this
    		after we are done sending the mondo to cpus which are
    		not in error state.
       HV_EWOULDBLOCK) We need to keep trying.
    
       Any other error we consider fatal, we report the event and exit
       immediately.
    
    5) We only timeout if forward progress is not made.  Forward progress
       is defined as having at least one cpu get the mondo successfully
       in a given cpu_mondo_send() call.  Otherwise we bump a counter
       and delay a little.  If the counter hits a limit, we signal an
       error and report the event.
    
    Also, smp_call_function_mask() error handling reports the number
    of cpus incorrectly.
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b830ab66
hypervisor.h 70.2 KB