# 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_powerpc-randconfig_powerpc-5.3 CROSS_COMPILE=/opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux- randconfig KCONFIG_SEED=0xAD136CAE # Added to kconfig CONFIG_STANDALONE=y # Added to kconfig CONFIG_BUILD_DOCSRC=n # Added to kconfig CONFIG_MODULE_SIG=n # Added to kconfig CONFIG_CPU_BIG_ENDIAN=y # Added to kconfig CONFIG_PPC64=y # Added to kconfig CONFIG_PPC_DISABLE_WERROR=y # Added to kconfig CONFIG_SECTION_MISMATCH_WARN_ONLY=y # Added to kconfig CONFIG_PREVENT_FIRMWARE_BUILD=y # Added to kconfig CONFIG_CC_STACKPROTECTOR_STRONG=n # Added to kconfig CONFIG_GCC_PLUGINS=n # Added to kconfig CONFIG_LD_HEAD_STUB_CATCH=y # Added to kconfig # yes \n | make -s -j 48 ARCH=powerpc O=/kisskb/build/powerpc-next_powerpc-randconfig_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_powerpc-randconfig_powerpc-5.3 CROSS_COMPILE=/opt/cross/kisskb/gcc-5.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux- Completed OK # rm -rf /kisskb/build/powerpc-next_powerpc-randconfig_powerpc-5.3 # Build took: 0:02:09.610586