From: gaoxingwang <gaoxingwang1@xxxxxxxxxx> After the call stack reaches the __local_bh_enable_ip function to start a soft interrupt, the system crashes. Call trace: virtqueue_add_outbuf+0x3d0/0x7e0 [virtio_ring] xmit_skb+0x174/0x280 [virtio_net] start_xmit+0xa4/0x2a0 [virtio_net] xmit_one.constprop.0+0xc0/0x1d0 dev_hard_start_xmit+0x54/0xd4 sch_direct_xmit+0xe4/0x5a0 __dev_queue_xmit+0x200/0xad0 dev_queue_xmit+0x1c/0x30 ip6_finish_output2+0x23c/0x6d0 __ip6_finish_output.part.0+0xb8/0x1b0 ip6_finish_output+0xec/0x12c ip6_output+0x78/0x170 xfrm_output_resume+0x1ec/0x1fc xfrm_output+0xac/0x3c0 __xfrm6_output+0x118/0x270 xfrm6_output+0x54/0xfc ip6_xmit+0x2dc/0x5a4 inet6_csk_xmit+0x9c/0xfc __tcp_transmit_skb+0x47c/0x79c tcp_write_xmit+0x258/0x690 tcp_tsq_write+0x60/0xd0 tcp_tsq_handler+0xfc/0x150 tcp_tasklet_func+0xf4/0x164 tasklet_action_common.constprop.0+0x194/0x1b4 tasklet_action+0x30/0x3c __do_softirq+0x130/0x358 do_softirq.part.0+0x84/0xa0 __local_bh_enable_ip+0xa4/0xb0 kernel_neon_end+0x30/0x50 sha1_ce_finup+0x324/0x378 [sha1_ce] crypto_shash_finup+0x34/0xc0 hmac_finup+0x48/0xe0 crypto_shash_finup+0x34/0xc0 shash_digest_unaligned+0x74/0x90 crypto_shash_digest+0x4c/0x9c shash_ahash_digest+0xdc/0x104 shash_async_digest+0x28/0x3c crypto_ahash_digest+0x48/0xcc ah6_output+0x2f0/0x3b0 [ah6] xfrm_output_one+0x25c/0x4d4 xfrm_output_resume+0x6c/0x1fc xfrm_output+0xac/0x3c0 __xfrm6_output+0x118/0x270 xfrm6_output+0x54/0xfc ip6_xmit+0x2dc/0x5a4 inet6_csk_xmit+0x9c/0xfc __tcp_transmit_skb+0x47c/0x79c tcp_write_xmit+0x258/0x690 __tcp_push_pending_frames+0x44/0x104 tcp_push+0xe8/0x140 tcp_sendmsg_locked+0xb98/0xca0 tcp_sendmsg+0x40/0x70 inet6_sendmsg+0x4c/0x80 sock_sendmsg+0x48/0x70 __sys_sendto+0x120/0x14c __arm64_sys_sendto+0x30/0x40 el0_svc_common.constprop.0+0x7c/0x1bc do_el0_svc+0x2c/0x94 el0_svc+0x20/0x30 el0_sync_handler+0xb0/0xb4 el0_sync+0x160/0x180 Try to revert commit 13150149aa6d that added local_bh_enable in crypto to avoid scheduling soft interrupts frequently when using ipsec in a non-preemptible kernel. It works for some cases, but still have one faild, which is tcp4-multi-diffport11.I don't know how to figure it. Call trace like this: [ 4490.908551] watchdog: BUG: soft lockup - CPU#3 stuck for 22s! [ns-tcpserver:179956] [ 4490.909804] Modules linked in: ah6 nfsv3 xfrm4_tunnel tunnel4 ipcomp xfrm_ipcomp sctp aes_ce_ccm ccm esp6 ah4 rpcsec_gss_krb5 nfsv4 dns_resolver nfs fscache authenc echainiv esp4 sm4_generic libsm4 twofish_generic twofish_common camellia_generic serpent_generic blowfish_generic blowfish_common cast5_generic cast_common des_generic libdes sm3_generic rmd160 sha512_generic sha512_arm64 af_key rpcrdma rdma_cm iw_cm ib_cm ib_core nfsd auth_rpcgss nfs_acl lockd grace nfs_ssc nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_tables ebtable_nat ebtable_broute ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c iptable_mangle iptable_raw iptable_security ip_set rfkill nfnetlink ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables kbox(O) sysmonitor(O) kboxdriver(O) sunrpc vfat sg fat sch_fq_codel fuse [ 4490.909938] ksecurec(O) ext4 mbcache jbd2 sd_mod t10_pi virtio_gpu ghash_ce virtio_scsi virtio_console virtio_dma_buf sha2_ce virtio_net net_failover failover sha256_arm64 sha1_ce virtio_pci virtio_mmio virtio_ring virtio dm_mirror dm_region_hash dm_log dm_mod aes_neon_bs aes_neon_blk aes_ce_blk crypto_simd cryptd aes_ce_cipher [ 4490.909989] Sample time: 4490524888320 ns(HZ: 250) [ 4490.909990] Sample stat: [ 4490.909995] curr: user: 217254140760, nice: 293968560, sys: 536817552400, idle: 3322823533580, iowait: 76154397960, irq: 26827662860, softirq: 308879528700, st: 0 [ 4490.909998] deta: user: 217254140760, nice: 293968560, sys: 536817552400, idle: 3322823533580, iowait: 76154397960, irq: 26827662860, softirq: 308879528700, st: 0 [ 4490.909999] Sample softirq: [ 4490.910002] TIMER: 101755 [ 4490.910004] NET_TX: 9 [ 4490.910006] NET_RX: 10877748 [ 4490.910008] TASKLET: 10808 [ 4490.910009] SCHED: 455852 [ 4490.910011] HRTIMER: 111 [ 4490.910012] RCU: 551796 [ 4490.910013] Sample irqstat: [ 4490.910017] irq 1: delta 155028, curr: 155028, IPI [ 4490.910019] irq 2: delta 12421, curr: 12421, IPI [ 4490.910024] irq 12: delta 1145220, curr: 1145220, arch_timer [ 4490.910055] irq 79: delta 4344, curr: 4344, virtio2-input.0 [ 4490.910058] irq 80: delta 40040, curr: 40040, virtio2-output.0 [ 4490.910061] irq 82: delta 3404649, curr: 3404649, virtio3-input.0 [ 4490.910064] irq 83: delta 4149166, curr: 4149166, virtio3-output.0 [ 4490.910068] irq 88: delta 3, curr: 3, virtio0-virtqueues [ 4490.910072] irq 94: delta 7262, curr: 7262, virtio1-control [ 4490.910076] irq 97: delta 344611, curr: 344611, virtio6-input.0 [ 4490.910082] CPU: 3 PID: 179956 Comm: ns-tcpserver Kdump: loaded Tainted: G O 5.10.0-60.18.0.50.h459.eulerosv2r11.aarch64 #1 [ 4490.910084] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 [ 4490.910088] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) [ 4490.910100] pc : dev_shutdown+0x538/0x6a0 [ 4490.910102] lr : sch_direct_xmit+0x184/0x5a0 [ 4490.910104] sp : ffff800102ff2d90 [ 4490.910106] x29: ffff800102ff2d90 x28: ffff0000370533e8 [ 4490.910109] x27: 0000000000000026 x26: ffff0000370533c0 [ 4490.910113] x25: ffff0000f4f59000 x24: 0000000000000001 [ 4490.910116] x23: 0000000000000003 x22: ffff0000f4f92200 [ 4490.910120] x21: ffff0000c09a70ac x20: ffff0000370534c0 [ 4490.910123] x19: ffff0000c09a7000 x18: 0000000000002081 [ 4490.910126] x17: 0000000008020208 x16: ffff8001000bd7b0 [ 4490.910129] x15: ffff80008145b960 x14: ffff000000281800 [ 4490.910133] x13: ffff0000d1fd5710 x12: ffff80008145b260 [ 4490.910136] x11: ffff80008145b360 x10: ffff8000811263e0 [ 4490.910140] x9 : ffff800100b25604 x8 : 0000000000000000 [ 4490.910143] x7 : 0000000000000010 x6 : ffff0000c0cbcd00 [ 4490.910146] x5 : ffff0000f4f922c0 x4 : 0000000000000000 [ 4490.910149] x3 : ffff0000f4f922c0 x2 : 0000000000000001 [ 4490.910153] x1 : 0000000000000000 x0 : ffff8001013f1008 [ 4490.910157] Call trace: [ 4490.910164] dev_shutdown+0x538/0x6a0 [ 4490.910167] __dev_queue_xmit+0x200/0xac0 [ 4490.910170] dev_queue_xmit+0x1c/0x30 [ 4490.910174] ip_finish_output2+0x248/0x550 [ 4490.910176] __ip_finish_output+0x16c/0x1c4 [ 4490.910178] ip_finish_output+0x3c/0xdc [ 4490.910180] ip_output+0xb8/0x144 [ 4490.910184] xfrm_output_resume+0x1ec/0x1fc [ 4490.910186] xfrm_output+0xac/0x3c0 [ 4490.910189] xfrm4_output+0x64/0x130 [ 4490.910192] __ip_queue_xmit+0x168/0x3d0 [ 4490.910194] ip_queue_xmit+0x1c/0x30 [ 4490.910197] __tcp_transmit_skb+0x498/0x770 [ 4490.910200] __tcp_retransmit_skb+0x1bc/0x58c [ 4490.910202] tcp_retransmit_skb+0x2c/0xf0 [ 4490.910204] tcp_xmit_retransmit_queue.part.0+0x154/0x2b0 [ 4490.910207] tcp_xmit_retransmit_queue+0x24/0x30 [ 4490.910209] tcp_xmit_recovery+0x40/0x8c [ 4490.910212] tcp_ack+0x3cc/0x720 [ 4490.910214] tcp_rcv_established+0x1c8/0x77c [ 4490.910217] tcp_v4_do_rcv+0x184/0x2a0 [ 4490.910219] tcp_v4_rcv+0xcac/0x10f0 [ 4490.910221] ip_protocol_deliver_rcu+0xf4/0x200 [ 4490.910224] ip_local_deliver_finish+0x58/0x70 [ 4490.910225] ip_local_deliver+0x68/0x120 [ 4490.910228] xfrm4_rcv_encap_finish2+0x28/0x34 [ 4490.910231] xfrm_trans_reinject+0xb8/0xf0 [ 4490.910235] tasklet_action_common.constprop.0+0x194/0x1b4 [ 4490.910237] tasklet_action+0x30/0x3c [ 4490.910240] __do_softirq+0x130/0x358 [ 4490.910242] do_softirq.part.0+0x84/0xa0 [ 4490.910244] __local_bh_enable_ip+0xa4/0xb0 [ 4490.910254] ipt_do_table+0x350/0x4d0 [ip_tables] [ 4490.910257] ipt_mangle_out+0x50/0xe0 [iptable_mangle] [ 4490.910260] iptable_mangle_hook+0x48/0x54 [iptable_mangle] [ 4490.910263] nf_hook_slow+0x54/0xf0 [ 4490.910266] __ip_local_out+0xf8/0x140 [ 4490.910268] __ip_queue_xmit+0x140/0x3d0 [ 4490.910270] ip_queue_xmit+0x1c/0x30 [ 4490.910273] __tcp_transmit_skb+0x498/0x770 [ 4490.910275] tcp_write_xmit+0x284/0x6f0 [ 4490.910278] __tcp_push_pending_frames+0x44/0x104 [ 4490.910280] tcp_push+0xe8/0x140 [ 4490.910282] tcp_sendmsg_locked+0xba8/0xd40 [ 4490.910284] tcp_sendmsg+0x40/0x70 [ 4490.910287] inet_sendmsg+0x4c/0x80 [ 4490.910290] sock_sendmsg+0x48/0x70 [ 4490.910293] __sys_sendto+0x120/0x14c [ 4490.910295] __arm64_sys_sendto+0x30/0x40 [ 4490.910298] el0_svc_common.constprop.0+0x7c/0x1bc [ 4490.910300] do_el0_svc+0x2c/0x94 [ 4490.910304] el0_svc+0x20/0x30 [ 4490.910307] el0_sync_handler+0xb0/0xb4 [ 4490.910309] el0_sync+0x160/0x180 Signed-off-by: gaoxingwang <gaoxingwang1@xxxxxxxxxx> --- arch/arm64/crypto/aes-modes.S | 2 +- arch/arm64/crypto/sha1-ce-core.S | 2 +- arch/arm64/crypto/sha2-ce-core.S | 2 +- arch/arm64/crypto/sha3-ce-core.S | 4 ++-- arch/arm64/crypto/sha512-ce-core.S | 2 +- arch/arm64/include/asm/assembler.h | 28 +++++++--------------------- arch/arm64/kernel/asm-offsets.c | 2 -- arch/arm64/kernel/fpsimd.c | 4 ++-- 8 files changed, 15 insertions(+), 31 deletions(-) diff --git a/arch/arm64/crypto/aes-modes.S b/arch/arm64/crypto/aes-modes.S index 503d9b317..ab570aa86 100644 --- a/arch/arm64/crypto/aes-modes.S +++ b/arch/arm64/crypto/aes-modes.S @@ -641,7 +641,7 @@ AES_FUNC_START(aes_mac_update) cbz w5, .Lmacout encrypt_block v0, w2, x1, x7, w8 st1 {v0.16b}, [x4] /* return dg */ - cond_yield .Lmacout, x7, x8 + cond_yield .Lmacout, x7 b .Lmacloop4x .Lmac1x: add w3, w3, #4 diff --git a/arch/arm64/crypto/sha1-ce-core.S b/arch/arm64/crypto/sha1-ce-core.S index 889ca0f89..8c02bbc26 100644 --- a/arch/arm64/crypto/sha1-ce-core.S +++ b/arch/arm64/crypto/sha1-ce-core.S @@ -121,7 +121,7 @@ CPU_LE( rev32 v11.16b, v11.16b ) add dgav.4s, dgav.4s, dg0v.4s cbz w2, 2f - cond_yield 3f, x5, x6 + cond_yield 3f, x5 b 0b /* diff --git a/arch/arm64/crypto/sha2-ce-core.S b/arch/arm64/crypto/sha2-ce-core.S index 491179922..6cdea7d56 100644 --- a/arch/arm64/crypto/sha2-ce-core.S +++ b/arch/arm64/crypto/sha2-ce-core.S @@ -129,7 +129,7 @@ CPU_LE( rev32 v19.16b, v19.16b ) /* handled all input blocks? */ cbz w2, 2f - cond_yield 3f, x5, x6 + cond_yield 3f, x5 b 0b /* diff --git a/arch/arm64/crypto/sha3-ce-core.S b/arch/arm64/crypto/sha3-ce-core.S index 9c77313f5..6f5208414 100644 --- a/arch/arm64/crypto/sha3-ce-core.S +++ b/arch/arm64/crypto/sha3-ce-core.S @@ -184,11 +184,11 @@ SYM_FUNC_START(sha3_ce_transform) eor v0.16b, v0.16b, v31.16b cbnz w8, 3b - cond_yield 4f, x8, x9 + cond_yield 3f, x8 cbnz w2, 0b /* save state */ -4: st1 { v0.1d- v3.1d}, [x0], #32 +3: st1 { v0.1d- v3.1d}, [x0], #32 st1 { v4.1d- v7.1d}, [x0], #32 st1 { v8.1d-v11.1d}, [x0], #32 st1 {v12.1d-v15.1d}, [x0], #32 diff --git a/arch/arm64/crypto/sha512-ce-core.S b/arch/arm64/crypto/sha512-ce-core.S index b6a3a36e1..d6e7f6c95 100644 --- a/arch/arm64/crypto/sha512-ce-core.S +++ b/arch/arm64/crypto/sha512-ce-core.S @@ -195,7 +195,7 @@ CPU_LE( rev64 v19.16b, v19.16b ) add v10.2d, v10.2d, v2.2d add v11.2d, v11.2d, v3.2d - cond_yield 3f, x4, x5 + cond_yield 3f, x4 /* handled all input blocks? */ cbnz w2, 0b diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index ef5e60d6d..c447dbbde 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -15,7 +15,6 @@ #include <asm-generic/export.h> #include <asm/asm-offsets.h> -#include <asm/alternative.h> #include <asm/cpufeature.h> #include <asm/cputype.h> #include <asm/debug-monitors.h> @@ -692,32 +691,19 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU .endm /* - * Check whether preempt/bh-disabled asm code should yield as soon as - * it is able. This is the case if we are currently running in task - * context, and either a softirq is pending, or the TIF_NEED_RESCHED - * flag is set and re-enabling preemption a single time would result in - * a preempt count of zero. (Note that the TIF_NEED_RESCHED flag is - * stored negated in the top word of the thread_info::preempt_count - * field) + * Check whether preempt-disabled code should yield as soon as it + * is able. This is the case if re-enabling preemption a single + * time results in a preempt count of zero, and the TIF_NEED_RESCHED + * flag is set. (Note that the latter is stored negated in the) + * top word of the thread_info::preempt_count field) */ - .macro cond_yield, lbl:req, tmp:req, tmp2:req + .macro cond_yield, lbl:req, tmp:req +#ifdef CONFIG_PREEMPTION get_current_task \tmp ldr \tmp, [\tmp, #TSK_TI_PREEMPT] - /* - * If we are serving a softirq, there is no point in yielding: the - * softirq will not be preempted no matter what we do, so we should - * run to completion as quickly as we can. - */ - tbnz \tmp, #SOFTIRQ_SHIFT, .Lnoyield_\@ -#ifdef CONFIG_PREEMPTION sub \tmp, \tmp, #PREEMPT_DISABLE_OFFSET cbz \tmp, \lbl #endif - adr_l \tmp, irq_stat + IRQ_CPUSTAT_SOFTIRQ_PENDING - this_cpu_offset \tmp2 - ldr w\tmp, [\tmp, \tmp2] - cbnz w\tmp, \lbl // yield on pending softirq in task context -.Lnoyield_\@: .endm /* diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 5f59e24c9..3ddfe6703 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -93,8 +93,6 @@ int main(void) DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); BLANK(); DEFINE(PREEMPT_DISABLE_OFFSET, PREEMPT_DISABLE_OFFSET); - DEFINE(SOFTIRQ_SHIFT, SOFTIRQ_SHIFT); - DEFINE(IRQ_CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); BLANK(); #ifdef CONFIG_COMPAT DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct old_timeval32, tv_sec)); diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 5335a6bd1..a9bbfb800 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -180,7 +180,7 @@ static void __get_cpu_fpsimd_context(void) */ static void get_cpu_fpsimd_context(void) { - local_bh_disable(); + preempt_disable(); __get_cpu_fpsimd_context(); } @@ -201,7 +201,7 @@ static void __put_cpu_fpsimd_context(void) static void put_cpu_fpsimd_context(void) { __put_cpu_fpsimd_context(); - local_bh_enable(); + preempt_enable(); } static bool have_cpu_fpsimd_context(void) -- 2.27.0