# git rev-parse -q --verify b6fbf9e64995137a57c19b0aa7f6c76c727439dc^{commit} b6fbf9e64995137a57c19b0aa7f6c76c727439dc already have revision, skipping fetch # git checkout -q -f -B kisskb b6fbf9e64995137a57c19b0aa7f6c76c727439dc # git clean -qxdf # git log -1 commit b6fbf9e64995137a57c19b0aa7f6c76c727439dc Author: Alistair Popple Date: Fri Mar 2 16:18:45 2018 +1100 powerpc/powernv/npu: Fix deadlock in mmio_invalidate() When sending TLB invalidates to the NPU we need to send extra flushes due to a hardware issue. The original implementation would lock the all the ATSD MMIO registers sequentially before unlocking and relocking each of them sequentially to do the extra flush. This introduced a deadlock as it is possible for one thread to hold one ATSD register whilst waiting for another register to be freed while the other thread is holding that register waiting for the one in the first thread to be freed. For example if there are two threads and two ATSD registers: Thread A Thread B ---------------------- Acquire 1 Acquire 2 Release 1 Acquire 1 Wait 1 Wait 2 Both threads will be stuck waiting to acquire a register resulting in an RCU stall warning or soft lockup. This patch solves the deadlock by refactoring the code to ensure registers are not released between flushes and to ensure all registers are either acquired or released together and in order. Fixes: bbd5ff50afff ("powerpc/powernv/npu-dma: Add explicit flush when sending an ATSD") Signed-off-by: Alistair Popple Signed-off-by: Michael Ellerman # < /opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-gcc --version # < git log --format=%s --max-count=1 b6fbf9e64995137a57c19b0aa7f6c76c727439dc # < make -s -j 48 ARCH=powerpc O=/kisskb/build/powerpc-next_allmodconfig+64K_PAGES_powerpc-5.3 CROSS_COMPILE=/opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux- allmodconfig # Added to kconfig CONFIG_BUILD_DOCSRC=n # Added to kconfig CONFIG_MODULE_SIG=n # Added to kconfig CONFIG_SAMPLES=n # Added to kconfig CONFIG_PPC_4K_PAGES=n # Added to kconfig CONFIG_PPC_64K_PAGES=y # yes \n | make -s -j 48 ARCH=powerpc O=/kisskb/build/powerpc-next_allmodconfig+64K_PAGES_powerpc-5.3 CROSS_COMPILE=/opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux- oldconfig yes: standard output: Broken pipe yes: write error # make -s -j 48 ARCH=powerpc O=/kisskb/build/powerpc-next_allmodconfig+64K_PAGES_powerpc-5.3 CROSS_COMPILE=/opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux- /kisskb/src/sound/aoa/codecs/onyx.c: In function 'onyx_snd_single_bit_get': /kisskb/src/sound/aoa/codecs/onyx.c:380:37: warning: 'c' may be used uninitialized in this function [-Wmaybe-uninitialized] ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity; ^ In file included from /kisskb/src/include/linux/io.h:25:0, from /kisskb/src/include/linux/of_address.h:7, from /kisskb/src/drivers/ata/ahci_qoriq.c:18: /kisskb/src/drivers/ata/ahci_qoriq.c: In function 'ahci_qoriq_hardreset': /kisskb/src/arch/powerpc/include/asm/io.h:625:3: warning: 'px_is' may be used uninitialized in this function [-Wmaybe-uninitialized] ppc_pci_io.name al; \ ^ /kisskb/src/drivers/ata/ahci_qoriq.c:86:14: note: 'px_is' was declared here u32 px_cmd, px_is, px_val; ^ In file included from /kisskb/src/include/linux/io.h:25:0, from /kisskb/src/include/linux/of_address.h:7, from /kisskb/src/drivers/ata/ahci_qoriq.c:18: /kisskb/src/arch/powerpc/include/asm/io.h:144:2: warning: 'px_cmd' may be used uninitialized in this function [-Wmaybe-uninitialized] __asm__ __volatile__("sync;"#insn" %1,%y0" \ ^ /kisskb/src/drivers/ata/ahci_qoriq.c:86:6: note: 'px_cmd' was declared here u32 px_cmd, px_is, px_val; ^ /kisskb/src/drivers/input/joystick/analog.c:176:2: warning: #warning Precise timer not defined for this architecture. [-Wcpp] #warning Precise timer not defined for this architecture. ^ WARNING: vmlinux.o(.text+0x7c144): Section mismatch in reference from the function .stop_machine_change_mapping() to the function .meminit.text:.create_physical_mapping() The function .stop_machine_change_mapping() references the function __meminit .create_physical_mapping(). This is often because .stop_machine_change_mapping lacks a __meminit annotation or the annotation of .create_physical_mapping is wrong. WARNING: vmlinux.o(.text+0x7c150): Section mismatch in reference from the function .stop_machine_change_mapping() to the function .meminit.text:.create_physical_mapping() The function .stop_machine_change_mapping() references the function __meminit .create_physical_mapping(). This is often because .stop_machine_change_mapping lacks a __meminit annotation or the annotation of .create_physical_mapping is wrong. Completed OK # rm -rf /kisskb/build/powerpc-next_allmodconfig+64K_PAGES_powerpc-5.3 # Build took: 0:12:55.878043