mirror of https://github.com/torvalds/linux.git
We have been observing hangs, both of KVM guest vcpu tasks and more generally, where a process that is woken doesn't properly wake up and continue to run, but instead sticks in TASK_WAKING state. This happens because the update of rq->wake_list in ttwu_queue_remote() is not ordered with the update of ipi_message in smp_muxed_ipi_message_pass(), and the reading of rq->wake_list in scheduler_ipi() is not ordered with the reading of ipi_message in smp_ipi_demux(). Thus it is possible for the IPI receiver not to see the updated rq->wake_list and therefore conclude that there is nothing for it to do. In order to make sure that anything done before smp_send_reschedule() is ordered before anything done in the resulting call to scheduler_ipi(), this adds barriers in smp_muxed_message_pass() and smp_ipi_demux(). The barrier in smp_muxed_message_pass() is a full barrier to ensure that there is a full ordering between the smp_send_reschedule() caller and scheduler_ipi(). In smp_ipi_demux(), we use xchg() rather than xchg_local() because xchg() includes release and acquire barriers. Using xchg() rather than xchg_local() makes sense given that ipi_message is not just accessed locally. This moves the barrier between setting the message and calling the cause_ipi() function into the individual cause_ipi implementations. Most of them -- those that used outb, out_8 or similar -- already had a full barrier because out_8 etc. include a sync before the MMIO store. This adds an explicit barrier in the two remaining cases. These changes made no measurable difference to the speed of IPIs as measured using a simple ping-pong latency test across two CPUs on different cores of a POWER7 machine. The analysis of the reason why processes were not waking up properly is due to Milton Miller. Cc: stable@vger.kernel.org # v3.0+ Reported-by: Milton Miller <miltonm@bga.com> Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
||
|---|---|---|
| .. | ||
| bestcomm | ||
| ge | ||
| qe_lib | ||
| xics | ||
| 6xx-suspend.S | ||
| Kconfig | ||
| Makefile | ||
| axonram.c | ||
| cpm1.c | ||
| cpm2.c | ||
| cpm2_pic.c | ||
| cpm2_pic.h | ||
| cpm_common.c | ||
| dart.h | ||
| dart_iommu.c | ||
| dcr-low.S | ||
| dcr.c | ||
| ehv_pic.c | ||
| fsl_85xx_cache_ctlr.h | ||
| fsl_85xx_cache_sram.c | ||
| fsl_85xx_l2ctlr.c | ||
| fsl_gtm.c | ||
| fsl_ifc.c | ||
| fsl_lbc.c | ||
| fsl_msi.c | ||
| fsl_msi.h | ||
| fsl_pci.c | ||
| fsl_pci.h | ||
| fsl_pmc.c | ||
| fsl_rio.c | ||
| fsl_rio.h | ||
| fsl_rmu.c | ||
| fsl_soc.c | ||
| fsl_soc.h | ||
| grackle.c | ||
| i8259.c | ||
| indirect_pci.c | ||
| ipic.c | ||
| ipic.h | ||
| micropatch.c | ||
| mmio_nvram.c | ||
| mpc5xxx_clocks.c | ||
| mpc8xx_pic.c | ||
| mpc8xx_pic.h | ||
| mpic.c | ||
| mpic.h | ||
| mpic_msgr.c | ||
| mpic_msi.c | ||
| mpic_pasemi_msi.c | ||
| mpic_u3msi.c | ||
| msi_bitmap.c | ||
| mv64x60.h | ||
| mv64x60_dev.c | ||
| mv64x60_pci.c | ||
| mv64x60_pic.c | ||
| mv64x60_udbg.c | ||
| of_rtc.c | ||
| pmi.c | ||
| ppc4xx_cpm.c | ||
| ppc4xx_gpio.c | ||
| ppc4xx_msi.c | ||
| ppc4xx_pci.c | ||
| ppc4xx_pci.h | ||
| ppc4xx_soc.c | ||
| rtc_cmos_setup.c | ||
| scom.c | ||
| simple_gpio.c | ||
| simple_gpio.h | ||
| tsi108_dev.c | ||
| tsi108_pci.c | ||
| uic.c | ||
| xilinx_intc.c | ||
| xilinx_pci.c | ||