Message ID | CAM_iQpVJ_Y5bB-RP2S2tK7sPNo6Atwcz5Ud8sG6bwDOSnq4NnA@mail.gmail.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
On 12/13/2016 12:51 AM, Cong Wang wrote: > On Mon, Dec 12, 2016 at 1:18 PM, Or Gerlitz <gerlitz.or@gmail.com> wrote: >> On Mon, Dec 12, 2016 at 3:28 PM, Daniel Borkmann <daniel@iogearbox.net> wrote: >> >>> Note that there's still the RCU fix missing for the deletion race that >>> Cong will still send out, but you say that the only thing you do is to >>> add a single rule, but no other operation in involved during that test? >> >> What's missing to have the deletion race fixed? making a patch or >> testing to a patch which was sent? > > If you think it would help for this problem, here is my patch rebased > on the latest net-next. > > Again, I don't see how it could help this case yet, especially I don't > see how we could have a loop in this singly linked list. > I've applied cong's patch and hit a different lockup(full log attached): [ 264.725414] RIP: 0010:fl_classify+0x1f1/0x2b0 [cls_flower] (gdb) list *(fl_classify+0x1f1) 0x1591 is in fl_classify (net/sched/cls_flower.c:187). 182 if (f && !tc_skip_sw(f->flags)) { 183 *res = f->res; 184 return tcf_exts_exec(skb, &f->exts, res); 185 } 186 return -1; 187 } 188 189 static int fl_init(struct tcf_proto *tp) 190 { 191 struct cls_fl_head *head; (gdb) Daniel suggested I'll add a print: case RTM_DELTFILTER: - err = tp->ops->delete(tp, fh); + printk(KERN_ERR "DEBUGG:SK %s:%d\n", __func__, __LINE__); + err = tp->ops->delete(tp, fh, &last); if (err == 0) { and I couldn't see this print in the output..... [ 238.507670] GACT probability on [ 264.573942] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [modprobe:4867] [ 264.582875] Modules linked in: act_gact act_mirred openvswitch nf_conntrack_ipv6 nf_nat_ipv6 nf_defrag_ipv6 vfio_pci vfio_virqfd vfio_iommu_type1 vfio cls_flower mlx5_ib mlx5_core devlink sch_ingress nfsv3 nfs fscache xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat libcrc32c nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun ebtable_filter ebtables ip6table_filter ip6_tables netconsole bridge stp llc rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi scsi_transport_iscsi ib_srpt ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm intel_rapl sb_edac edac_core x86_pkg_temp_thermal coretemp kvm_intel kvm ib_core irqbypass crct10dif_pclmul crc32_pclmul igb ptp iTCO_wdt pps_core crc32c_intel joydev i2c_algo_bit ghash_clmulni_intel iTCO_vendor_support pcspkr i2c_i801 mei_me ipmi_ssif ioatdma shpchp tpm_tis i2c_smbus tpm_tis_core dca tpm mei lpc_ich ipmi_si ipmi_msghandler wmi nfsd target_core_mod auth_rpcgss nfs_acl lockd grace sunrpc isci libsas serio_raw scsi_transport_sas [last unloaded: devlink] [ 264.703539] CPU: 0 PID: 4867 Comm: modprobe Not tainted 4.9.0+ #27 [ 264.710766] Hardware name: Supermicro X9DRW/X9DRW, BIOS 3.0a 08/08/2013 [ 264.718475] task: ffff89916ad09d80 task.stack: ffffa36f44510000 [ 264.725414] RIP: 0010:fl_classify+0x1f1/0x2b0 [cls_flower] [ 264.731863] RSP: 0018:ffff89916fa03ad8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 [ 264.740971] RAX: 00000000ffffffff RBX: ffff89913f522100 RCX: 0000000000000000 [ 264.749265] RDX: ffff89916fa03c98 RSI: ffff89915bd743c0 RDI: ffff89913f522100 [ 264.757558] RBP: ffff89916fa03c28 R08: 000000000000270f R09: 0000000000000000 [ 264.765852] R10: 0000000000000000 R11: 0000000000000004 R12: ffff89916fa03c98 [ 264.774144] R13: ffff89913ecc7c00 R14: ffff89915bd743c0 R15: 0000000000000001 [ 264.782440] FS: 00007f74f2f5e700(0000) GS:ffff89916fa00000(0000) knlGS:0000000000000000 [ 264.792066] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 264.798809] CR2: 00007f74f2491480 CR3: 000000043f3f8000 CR4: 00000000000426f0 [ 264.807102] Call Trace: [ 264.810151] <IRQ> [ 264.812717] ? handle_edge_irq+0x87/0x130 [ 264.817504] ? handle_irq+0xab/0x130 [ 264.821808] ? irq_exit+0x77/0xe0 [ 264.825828] ? irq_exit+0x77/0xe0 [ 264.829849] ? do_IRQ+0x51/0xd0 [ 264.833664] ? common_interrupt+0x93/0x93 [ 264.838462] tc_classify+0x78/0x120 [ 264.842679] __netif_receive_skb_core+0x623/0xa00 [ 264.848264] ? udp4_gro_receive+0x10b/0x2d0 [ 264.853253] __netif_receive_skb+0x18/0x60 [ 264.858150] netif_receive_skb_internal+0x40/0xb0 [ 264.863723] napi_gro_receive+0xcd/0x120 [ 264.868437] mlx5e_handle_rx_cqe_rep+0x61b/0x890 [mlx5_core] [ 264.875105] ? kvm_irq_delivery_to_apic+0x2c0/0x2c0 [kvm] [ 264.881462] mlx5e_poll_rx_cq+0x83/0x840 [mlx5_core] [ 264.887333] mlx5e_napi_poll+0x89/0x480 [mlx5_core] [ 264.893102] net_rx_action+0x260/0x3c0 [ 264.897610] __do_softirq+0xc9/0x28c [ 264.901922] irq_exit+0xd7/0xe0 [ 264.905748] do_IRQ+0x51/0xd0 [ 264.909380] common_interrupt+0x93/0x93 [ 264.913984] RIP: 0010:mpihelp_submul_1+0x91/0xe0 [ 264.919460] RSP: 0018:ffffa36f44513940 EFLAGS: 00000206 ORIG_RAX: ffffffffffffffa2 [ 264.928565] RAX: 5414d8fd4127cc59 RBX: 0000000100000000 RCX: ffffffffffffff50 [ 264.936860] RDX: 00000000ffffffea RSI: 0000000019ba7e4d RDI: 0000000068ef6b86 [ 264.945146] RBP: ffffa36f44513960 R08: 352cbbd4573982a8 R09: 64589019128fea22 [ 264.953440] R10: 128fea2200000000 R11: 352cbbd5573982a8 R12: ffff89955c585c00 [ 264.961732] R13: ffff899134dbfbd0 R14: 66a4c31fb80cf128 R15: d7554d389539f6c8 [ 264.970028] </IRQ> [ 264.972688] mpihelp_divrem+0x23b/0x740 [ 264.977291] mpi_powm+0x471/0xa10 [ 264.981312] rsa_verify+0xa5/0x130 [ 264.985421] pkcs1pad_verify+0xb9/0xf0 [ 264.989925] public_key_verify_signature+0x1f7/0x280 [ 264.995790] public_key_verify_signature_2+0x15/0x20 [ 265.001656] verify_signature+0x3c/0x50 [ 265.006259] pkcs7_validate_trust+0xa1/0x200 [ 265.011352] verify_pkcs7_signature+0x9a/0x140 [ 265.016636] mod_verify_sig+0x92/0xe0 [ 265.021046] load_module+0x171/0x2810 [ 265.025456] ? vfs_read+0x113/0x130 [ 265.029668] ? kernel_read_file+0x158/0x190 [ 265.034659] ? kernel_read_file_from_fd+0x49/0x80 [ 265.040248] SYSC_finit_module+0xa6/0xf0 [ 265.044947] SyS_finit_module+0xe/0x10 [ 265.049452] entry_SYSCALL_64_fastpath+0x1a/0xa9 [ 265.054931] RIP: 0033:0x7f74f2439239 [ 265.059241] RSP: 002b:00007ffeb8b23218 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 265.068373] RAX: ffffffffffffffda RBX: 00007ffeb8b21f10 RCX: 00007f74f2439239 [ 265.076665] RDX: 0000000000000000 RSI: 00005578b61d02a6 RDI: 0000000000000000 [ 265.084958] RBP: 00007ffeb8b21f00 R08: 0000000000000000 R09: 0000000000000000 [ 265.098996] R10: 0000000000000000 R11: 0000000000000246 R12: 00005578b61d1be7 [ 265.107289] R13: 00007ffeb8b22088 R14: 0000000000000000 R15: 00005578b61d1bf3 [ 265.115582] Code: 02 75 e2 48 8b 81 98 00 00 00 48 8b 91 a0 00 00 00 48 8b 7c 24 18 48 89 07 48 89 57 08 8b 81 84 00 00 00 85 c0 0f 85 86 00 00 00 <48> 8b 9c 24 20 01 00 00 65 48 33 1c 25 28 00 00 00 0f 85 a1 00 [ 265.143394] Kernel panic - not syncing: softlockup: hung tasks [ 265.150231] CPU: 0 PID: 4867 Comm: modprobe Tainted: G L 4.9.0+ #27 [ 265.159057] Hardware name: Supermicro X9DRW/X9DRW, BIOS 3.0a 08/08/2013 [ 265.166766] Call Trace: [ 265.169811] <IRQ> [ 265.172374] dump_stack+0x63/0x8c [ 265.176393] panic+0xeb/0x239 [ 265.180047] watchdog_timer_fn+0x1e5/0x1f0 [ 265.184941] ? watchdog+0x40/0x40 [ 265.188960] __hrtimer_run_queues+0xee/0x270 [ 265.194050] hrtimer_interrupt+0xa8/0x190 [ 265.198849] local_apic_timer_interrupt+0x35/0x60 [ 265.204422] smp_apic_timer_interrupt+0x38/0x50 [ 265.209802] apic_timer_interrupt+0x93/0xa0 [ 265.214794] RIP: 0010:fl_classify+0x1f1/0x2b0 [cls_flower] [ 265.221242] RSP: 0018:ffff89916fa03ad8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 [ 265.230339] RAX: 00000000ffffffff RBX: ffff89913f522100 RCX: 0000000000000000 [ 265.238635] RDX: ffff89916fa03c98 RSI: ffff89915bd743c0 RDI: ffff89913f522100 [ 265.246929] RBP: ffff89916fa03c28 R08: 000000000000270f R09: 0000000000000000 [ 265.255223] R10: 0000000000000000 R11: 0000000000000004 R12: ffff89916fa03c98 [ 265.263516] R13: ffff89913ecc7c00 R14: ffff89915bd743c0 R15: 0000000000000001 [ 265.271812] ? handle_edge_irq+0x87/0x130 [ 265.276599] ? handle_irq+0xab/0x130 [ 265.280902] ? irq_exit+0x77/0xe0 [ 265.284911] ? irq_exit+0x77/0xe0 [ 265.288927] ? do_IRQ+0x51/0xd0 [ 265.292752] ? common_interrupt+0x93/0x93 [ 265.297549] tc_classify+0x78/0x120 [ 265.301762] __netif_receive_skb_core+0x623/0xa00 [ 265.307336] ? udp4_gro_receive+0x10b/0x2d0 [ 265.312328] __netif_receive_skb+0x18/0x60 [ 265.317221] netif_receive_skb_internal+0x40/0xb0 [ 265.322795] napi_gro_receive+0xcd/0x120 [ 265.327502] mlx5e_handle_rx_cqe_rep+0x61b/0x890 [mlx5_core] [ 265.334153] ? kvm_irq_delivery_to_apic+0x2c0/0x2c0 [kvm] [ 265.340510] mlx5e_poll_rx_cq+0x83/0x840 [mlx5_core] [ 265.346379] mlx5e_napi_poll+0x89/0x480 [mlx5_core] [ 265.352170] net_rx_action+0x260/0x3c0 [ 265.356675] __do_softirq+0xc9/0x28c [ 265.360987] irq_exit+0xd7/0xe0 [ 265.364814] do_IRQ+0x51/0xd0 [ 265.368440] common_interrupt+0x93/0x93 [ 265.373041] RIP: 0010:mpihelp_submul_1+0x91/0xe0 [ 265.378516] RSP: 0018:ffffa36f44513940 EFLAGS: 00000206 ORIG_RAX: ffffffffffffffa2 [ 265.387614] RAX: 5414d8fd4127cc59 RBX: 0000000100000000 RCX: ffffffffffffff50 [ 265.395921] RDX: 00000000ffffffea RSI: 0000000019ba7e4d RDI: 0000000068ef6b86 [ 265.404235] RBP: ffffa36f44513960 R08: 352cbbd4573982a8 R09: 64589019128fea22 [ 265.412526] R10: 128fea2200000000 R11: 352cbbd5573982a8 R12: ffff89955c585c00 [ 265.420819] R13: ffff899134dbfbd0 R14: 66a4c31fb80cf128 R15: d7554d389539f6c8 [ 265.429113] </IRQ> [ 265.431769] mpihelp_divrem+0x23b/0x740 [ 265.436373] mpi_powm+0x471/0xa10 [ 265.440394] rsa_verify+0xa5/0x130 [ 265.444508] pkcs1pad_verify+0xb9/0xf0 [ 265.449014] public_key_verify_signature+0x1f7/0x280 [ 265.454878] public_key_verify_signature_2+0x15/0x20 [ 265.460741] verify_signature+0x3c/0x50 [ 265.465343] pkcs7_validate_trust+0xa1/0x200 [ 265.470430] verify_pkcs7_signature+0x9a/0x140 [ 265.475715] mod_verify_sig+0x92/0xe0 [ 265.480147] load_module+0x171/0x2810 [ 265.484555] ? vfs_read+0x113/0x130 [ 265.488758] ? kernel_read_file+0x158/0x190 [ 265.493751] ? kernel_read_file_from_fd+0x49/0x80 [ 265.499328] SYSC_finit_module+0xa6/0xf0 [ 265.504051] SyS_finit_module+0xe/0x10 [ 265.508555] entry_SYSCALL_64_fastpath+0x1a/0xa9 [ 265.514030] RIP: 0033:0x7f74f2439239 [ 265.518340] RSP: 002b:00007ffeb8b23218 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 265.527446] RAX: ffffffffffffffda RBX: 00007ffeb8b21f10 RCX: 00007f74f2439239 [ 265.535740] RDX: 0000000000000000 RSI: 00005578b61d02a6 RDI: 0000000000000000 [ 265.544056] RBP: 00007ffeb8b21f00 R08: 0000000000000000 R09: 0000000000000000 [ 265.552354] R10: 0000000000000000 R11: 0000000000000246 R12: 00005578b61d1be7 [ 265.560648] R13: 00007ffeb8b22088 R14: 0000000000000000 R15: 00005578b61d1bf3 [ 265.568994] Kernel Offset: 0x3b000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 266.845267] ---[ end Kernel panic - not syncing: softlockup: hung tasks [ 266.853000] ------------[ cut here ]------------ [ 266.858490] WARNING: CPU: 0 PID: 4867 at arch/x86/kernel/smp.c:127 native_smp_send_reschedule+0x3f/0x50 [ 266.869551] Modules linked in: act_gact act_mirred openvswitch nf_conntrack_ipv6 nf_nat_ipv6 nf_defrag_ipv6 vfio_pci vfio_virqfd vfio_iommu_type1 vfio cls_flower mlx5_ib mlx5_core devlink sch_ingress nfsv3 nfs fscache xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat libcrc32c nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun ebtable_filter ebtables ip6table_filter ip6_tables netconsole bridge stp llc rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi scsi_transport_iscsi ib_srpt ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm intel_rapl sb_edac edac_core x86_pkg_temp_thermal coretemp kvm_intel kvm ib_core irqbypass crct10dif_pclmul crc32_pclmul igb ptp iTCO_wdt pps_core crc32c_intel joydev i2c_algo_bit ghash_clmulni_intel iTCO_vendor_support pcspkr i2c_i801 mei_me ipmi_ssif ioatdma shpchp tpm_tis i2c_smbus tpm_tis_core dca tpm mei lpc_ich ipmi_si ipmi_msghandler wmi nfsd target_core_mod auth_rpcgss nfs_acl lockd grace sunrpc isci libsas serio_raw scsi_transport_sas [last unloaded: devlink] [ 266.990566] CPU: 0 PID: 4867 Comm: modprobe Tainted: G L 4.9.0+ #27 [ 266.999401] Hardware name: Supermicro X9DRW/X9DRW, BIOS 3.0a 08/08/2013 [ 267.007118] Call Trace: [ 267.010179] <IRQ> [ 267.012748] dump_stack+0x63/0x8c [ 267.016783] __warn+0xd1/0xf0 [ 267.020420] warn_slowpath_null+0x1d/0x20 [ 267.025314] native_smp_send_reschedule+0x3f/0x50 [ 267.030895] try_to_wake_up+0x312/0x390 [ 267.035501] wake_up_process+0x15/0x20 [ 267.040009] swake_up_locked+0x24/0x50 [ 267.044519] swake_up+0x2c/0x40 [ 267.048364] kvm_vcpu_kick+0x32/0x80 [kvm] [ 267.053276] __apic_accept_irq+0x1b6/0x330 [kvm] [ 267.058774] kvm_apic_set_irq+0x2a/0x30 [kvm] [ 267.063978] kvm_irq_delivery_to_apic_fast+0xf5/0x3c0 [kvm] [ 267.070544] kvm_arch_set_irq_inatomic+0x99/0xb0 [kvm] [ 267.076621] irqfd_wakeup+0x111/0x160 [kvm] [ 267.081628] ? kvm_irq_delivery_to_apic+0x2c0/0x2c0 [kvm] [ 267.087984] __wake_up_common+0x55/0x90 [ 267.092583] __wake_up_locked_key+0x18/0x20 [ 267.097580] eventfd_signal+0x5c/0x80 [ 267.102001] vfio_msihandler+0x16/0x20 [vfio_pci] [ 267.107578] __handle_irq_event_percpu+0x3c/0x1a0 [ 267.113164] handle_irq_event_percpu+0x32/0x80 [ 267.118453] handle_irq_event+0x2c/0x50 [ 267.123068] handle_edge_irq+0x87/0x130 [ 267.127677] handle_irq+0xab/0x130 [ 267.131801] do_IRQ+0x48/0xd0 [ 267.135435] common_interrupt+0x93/0x93 [ 267.140042] RIP: 0010:panic+0x1f5/0x239 [ 267.144647] RSP: 0018:ffff89916fa03898 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff73 [ 267.153760] RAX: 000000000000003b RBX: 0000000000000000 RCX: 0000000000000006 [ 267.162062] RDX: 0000000000000000 RSI: 0000000000000046 RDI: ffff89916fa0e060 [ 267.170362] RBP: ffff89916fa03908 R08: 0000000000000691 R09: ffff898d000bc4c0 [ 267.178659] R10: 000000000000010a R11: 0000000000000198 R12: ffffffffbcc4a459 [ 267.186964] R13: 0000000000000000 R14: 0000000000000000 R15: ffff89916fa03a28 [ 267.195266] ? panic+0x1f1/0x239 [ 267.199201] watchdog_timer_fn+0x1e5/0x1f0 [ 267.204104] ? watchdog+0x40/0x40 [ 267.208130] __hrtimer_run_queues+0xee/0x270 [ 267.213224] hrtimer_interrupt+0xa8/0x190 [ 267.218036] local_apic_timer_interrupt+0x35/0x60 [ 267.223612] smp_apic_timer_interrupt+0x38/0x50 [ 267.228999] apic_timer_interrupt+0x93/0xa0 [ 267.233987] RIP: 0010:fl_classify+0x1f1/0x2b0 [cls_flower] [ 267.240440] RSP: 0018:ffff89916fa03ad8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 [ 267.249539] RAX: 00000000ffffffff RBX: ffff89913f522100 RCX: 0000000000000000 [ 267.257829] RDX: ffff89916fa03c98 RSI: ffff89915bd743c0 RDI: ffff89913f522100 [ 267.266128] RBP: ffff89916fa03c28 R08: 000000000000270f R09: 0000000000000000 [ 267.274425] R10: 0000000000000000 R11: 0000000000000004 R12: ffff89916fa03c98 [ 267.282721] R13: ffff89913ecc7c00 R14: ffff89915bd743c0 R15: 0000000000000001 [ 267.291019] ? handle_edge_irq+0x87/0x130 [ 267.295818] ? handle_irq+0xab/0x130 [ 267.300133] ? irq_exit+0x77/0xe0 [ 267.304160] ? irq_exit+0x77/0xe0 [ 267.308184] ? do_IRQ+0x51/0xd0 [ 267.312015] ? common_interrupt+0x93/0x93 [ 267.316818] tc_classify+0x78/0x120 [ 267.321038] __netif_receive_skb_core+0x623/0xa00 [ 267.326618] ? udp4_gro_receive+0x10b/0x2d0 [ 267.331616] __netif_receive_skb+0x18/0x60 [ 267.336514] netif_receive_skb_internal+0x40/0xb0 [ 267.342091] napi_gro_receive+0xcd/0x120 [ 267.346809] mlx5e_handle_rx_cqe_rep+0x61b/0x890 [mlx5_core] [ 267.353467] ? kvm_irq_delivery_to_apic+0x2c0/0x2c0 [kvm] [ 267.359837] mlx5e_poll_rx_cq+0x83/0x840 [mlx5_core] [ 267.365716] mlx5e_napi_poll+0x89/0x480 [mlx5_core] [ 267.371500] net_rx_action+0x260/0x3c0 [ 267.376008] __do_softirq+0xc9/0x28c [ 267.380330] irq_exit+0xd7/0xe0 [ 267.384168] do_IRQ+0x51/0xd0 [ 267.387810] common_interrupt+0x93/0x93 [ 267.392426] RIP: 0010:mpihelp_submul_1+0x91/0xe0 [ 267.403605] RSP: 0018:ffffa36f44513940 EFLAGS: 00000206 ORIG_RAX: ffffffffffffffa2 [ 267.412818] RAX: 5414d8fd4127cc59 RBX: 0000000100000000 RCX: ffffffffffffff50 [ 267.421114] RDX: 00000000ffffffea RSI: 0000000019ba7e4d RDI: 0000000068ef6b86 [ 267.429418] RBP: ffffa36f44513960 R08: 352cbbd4573982a8 R09: 64589019128fea22 [ 267.437713] R10: 128fea2200000000 R11: 352cbbd5573982a8 R12: ffff89955c585c00 [ 267.446014] R13: ffff899134dbfbd0 R14: 66a4c31fb80cf128 R15: d7554d389539f6c8 [ 267.454311] </IRQ> [ 267.456981] mpihelp_divrem+0x23b/0x740 [ 267.461598] mpi_powm+0x471/0xa10 [ 267.465630] rsa_verify+0xa5/0x130 [ 267.469759] pkcs1pad_verify+0xb9/0xf0 [ 267.474277] public_key_verify_signature+0x1f7/0x280 [ 267.480148] public_key_verify_signature_2+0x15/0x20 [ 267.486011] verify_signature+0x3c/0x50 [ 267.490619] pkcs7_validate_trust+0xa1/0x200 [ 267.495710] verify_pkcs7_signature+0x9a/0x140 [ 267.501000] mod_verify_sig+0x92/0xe0 [ 267.505404] load_module+0x171/0x2810 [ 267.509822] ? vfs_read+0x113/0x130 [ 267.514047] ? kernel_read_file+0x158/0x190 [ 267.519041] ? kernel_read_file_from_fd+0x49/0x80 [ 267.524620] SYSC_finit_module+0xa6/0xf0 [ 267.529325] SyS_finit_module+0xe/0x10 [ 267.533844] entry_SYSCALL_64_fastpath+0x1a/0xa9 [ 267.539325] RIP: 0033:0x7f74f2439239 [ 267.543639] RSP: 002b:00007ffeb8b23218 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 267.552740] RAX: ffffffffffffffda RBX: 00007ffeb8b21f10 RCX: 00007f74f2439239 [ 267.561042] RDX: 0000000000000000 RSI: 00005578b61d02a6 RDI: 0000000000000000 [ 267.569341] RBP: 00007ffeb8b21f00 R08: 0000000000000000 R09: 0000000000000000 [ 267.577638] R10: 0000000000000000 R11: 0000000000000246 R12: 00005578b61d1be7 [ 267.585935] R13: 00007ffeb8b22088 R14: 0000000000000000 R15: 00005578b61d1bf3 [ 267.594231] ---[ end trace 2eb46a584b6ba420 ]---
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 498f81b..b5eda3f 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -203,14 +203,14 @@ struct tcf_proto_ops { const struct tcf_proto *, struct tcf_result *); int (*init)(struct tcf_proto*); - bool (*destroy)(struct tcf_proto*, bool); + void (*destroy)(struct tcf_proto*); unsigned long (*get)(struct tcf_proto*, u32 handle); int (*change)(struct net *net, struct sk_buff *, struct tcf_proto*, unsigned long, u32 handle, struct nlattr **, unsigned long *, bool); - int (*delete)(struct tcf_proto*, unsigned long); + int (*delete)(struct tcf_proto*, unsigned long, bool*); void (*walk)(struct tcf_proto*, struct tcf_walker *arg); /* rtnetlink specific */ @@ -405,7 +405,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, const struct Qdisc_ops *ops, u32 parentid); void __qdisc_calculate_pkt_len(struct sk_buff *skb, const struct qdisc_size_table *stab); -bool tcf_destroy(struct tcf_proto *tp, bool force); +void tcf_destroy(struct tcf_proto *tp); void tcf_destroy_chain(struct tcf_proto __rcu **fl); int skb_do_redirect(struct sk_buff *); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 3fbba79..f9179e0 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -321,7 +321,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER, false); - tcf_destroy(tp, true); + tcf_destroy(tp); err = 0; goto errout; } @@ -331,25 +331,29 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) !(n->nlmsg_flags & NLM_F_CREATE)) goto errout; } else { + bool last; + switch (n->nlmsg_type) { case RTM_NEWTFILTER: err = -EEXIST; if (n->nlmsg_flags & NLM_F_EXCL) { if (tp_created) - tcf_destroy(tp, true); + tcf_destroy(tp); goto errout; } break; case RTM_DELTFILTER: - err = tp->ops->delete(tp, fh); + err = tp->ops->delete(tp, fh, &last); if (err == 0) { - struct tcf_proto *next = rtnl_dereference(tp->next); - tfilter_notify(net, skb, n, tp, t->tcm_handle, RTM_DELTFILTER, false); - if (tcf_destroy(tp, false)) + if (last) { + struct tcf_proto *next = rtnl_dereference(tp->next); + RCU_INIT_POINTER(*back, next); + tcf_destroy(tp); + } } goto errout; case RTM_GETTFILTER: @@ -372,7 +376,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false); } else { if (tp_created) - tcf_destroy(tp, true); + tcf_destroy(tp); } errout: diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 5877f60..8d822e5 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -93,30 +93,28 @@ static void basic_delete_filter(struct rcu_head *head) kfree(f); } -static bool basic_destroy(struct tcf_proto *tp, bool force) +static void basic_destroy(struct tcf_proto *tp) { struct basic_head *head = rtnl_dereference(tp->root); struct basic_filter *f, *n; - if (!force && !list_empty(&head->flist)) - return false; - list_for_each_entry_safe(f, n, &head->flist, link) { list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); call_rcu(&f->rcu, basic_delete_filter); } kfree_rcu(head, rcu); - return true; } -static int basic_delete(struct tcf_proto *tp, unsigned long arg) +static int basic_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { + struct basic_head *head = rtnl_dereference(tp->root); struct basic_filter *f = (struct basic_filter *) arg; list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); call_rcu(&f->rcu, basic_delete_filter); + *last = list_empty(&head->flist); return 0; } diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index adc7760..55c9961 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -268,25 +268,24 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog) call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu); } -static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg) +static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { + struct cls_bpf_head *head = rtnl_dereference(tp->root); + __cls_bpf_delete(tp, (struct cls_bpf_prog *) arg); + *last = list_empty(&head->plist); return 0; } -static bool cls_bpf_destroy(struct tcf_proto *tp, bool force) +static void cls_bpf_destroy(struct tcf_proto *tp) { struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_prog *prog, *tmp; - if (!force && !list_empty(&head->plist)) - return false; - list_for_each_entry_safe(prog, tmp, &head->plist, link) __cls_bpf_delete(tp, prog); kfree_rcu(head, rcu); - return true; } static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index c1f2007..51c822d 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -131,20 +131,16 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, return err; } -static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force) +static void cls_cgroup_destroy(struct tcf_proto *tp) { struct cls_cgroup_head *head = rtnl_dereference(tp->root); - if (!force) - return false; /* Head can still be NULL due to cls_cgroup_init(). */ if (head) call_rcu(&head->rcu, cls_cgroup_destroy_rcu); - - return true; } -static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg) +static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { return -EOPNOTSUPP; } diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 6575aba..ea2be75 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -563,12 +563,14 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, return err; } -static int flow_delete(struct tcf_proto *tp, unsigned long arg) +static int flow_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { + struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f = (struct flow_filter *)arg; list_del_rcu(&f->list); call_rcu(&f->rcu, flow_destroy_filter); + *last = list_empty(&head->filters); return 0; } @@ -584,20 +586,16 @@ static int flow_init(struct tcf_proto *tp) return 0; } -static bool flow_destroy(struct tcf_proto *tp, bool force) +static void flow_destroy(struct tcf_proto *tp) { struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f, *next; - if (!force && !list_empty(&head->filters)) - return false; - list_for_each_entry_safe(f, next, &head->filters, list) { list_del_rcu(&f->list); call_rcu(&f->rcu, flow_destroy_filter); } kfree_rcu(head, rcu); - return true; } static unsigned long flow_get(struct tcf_proto *tp, u32 handle) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index e040c51..328938b 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -312,21 +312,16 @@ static void fl_destroy_rcu(struct rcu_head *rcu) schedule_work(&head->work); } -static bool fl_destroy(struct tcf_proto *tp, bool force) +static void fl_destroy(struct tcf_proto *tp) { struct cls_fl_head *head = rtnl_dereference(tp->root); struct cls_fl_filter *f, *next; - if (!force && !list_empty(&head->filters)) - return false; - list_for_each_entry_safe(f, next, &head->filters, list) __fl_delete(tp, f); __module_get(THIS_MODULE); call_rcu(&head->rcu, fl_destroy_rcu); - - return true; } static unsigned long fl_get(struct tcf_proto *tp, u32 handle) @@ -877,7 +872,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, return err; } -static int fl_delete(struct tcf_proto *tp, unsigned long arg) +static int fl_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct cls_fl_head *head = rtnl_dereference(tp->root); struct cls_fl_filter *f = (struct cls_fl_filter *) arg; @@ -886,6 +881,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg) rhashtable_remove_fast(&head->ht, &f->ht_node, head->ht_params); __fl_delete(tp, f); + *last = list_empty(&head->filters); return 0; } diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 9dc63d5..bc8ceb7 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -127,20 +127,14 @@ static void fw_delete_filter(struct rcu_head *head) kfree(f); } -static bool fw_destroy(struct tcf_proto *tp, bool force) +static void fw_destroy(struct tcf_proto *tp) { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f; int h; if (head == NULL) - return true; - - if (!force) { - for (h = 0; h < HTSIZE; h++) - if (rcu_access_pointer(head->ht[h])) - return false; - } + return; for (h = 0; h < HTSIZE; h++) { while ((f = rtnl_dereference(head->ht[h])) != NULL) { @@ -150,17 +144,17 @@ static bool fw_destroy(struct tcf_proto *tp, bool force) call_rcu(&f->rcu, fw_delete_filter); } } - RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); - return true; } -static int fw_delete(struct tcf_proto *tp, unsigned long arg) +static int fw_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f = (struct fw_filter *)arg; struct fw_filter __rcu **fp; struct fw_filter *pfp; + int ret = -EINVAL; + int h; if (head == NULL || f == NULL) goto out; @@ -173,11 +167,21 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg) RCU_INIT_POINTER(*fp, rtnl_dereference(f->next)); tcf_unbind_filter(tp, &f->res); call_rcu(&f->rcu, fw_delete_filter); - return 0; + ret = 0; + break; } } + + *last = true; + for (h = 0; h < HTSIZE; h++) { + if (rcu_access_pointer(head->ht[h])) { + *last = false; + break; + } + } + out: - return -EINVAL; + return ret; } static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = { diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index f935429..7d54805 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -99,15 +99,12 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp, &offload); } -static bool mall_destroy(struct tcf_proto *tp, bool force) +static void mall_destroy(struct tcf_proto *tp) { struct cls_mall_head *head = rtnl_dereference(tp->root); struct net_device *dev = tp->q->dev_queue->dev; struct cls_mall_filter *f = head->filter; - if (!force && f) - return false; - if (f) { if (tc_should_offload(dev, tp, f->flags)) mall_destroy_hw_filter(tp, f, (unsigned long) f); @@ -115,7 +112,6 @@ static bool mall_destroy(struct tcf_proto *tp, bool force) call_rcu(&f->rcu, mall_destroy_filter); } kfree_rcu(head, rcu); - return true; } static unsigned long mall_get(struct tcf_proto *tp, u32 handle) @@ -224,7 +220,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, return err; } -static int mall_delete(struct tcf_proto *tp, unsigned long arg) +static int mall_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct cls_mall_head *head = rtnl_dereference(tp->root); struct cls_mall_filter *f = (struct cls_mall_filter *) arg; @@ -236,6 +232,7 @@ static int mall_delete(struct tcf_proto *tp, unsigned long arg) RCU_INIT_POINTER(head->filter, NULL); tcf_unbind_filter(tp, &f->res); call_rcu(&f->rcu, mall_destroy_filter); + *last = true; return 0; } diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 455fc8f..1a38e41 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -276,20 +276,13 @@ static void route4_delete_filter(struct rcu_head *head) kfree(f); } -static bool route4_destroy(struct tcf_proto *tp, bool force) +static void route4_destroy(struct tcf_proto *tp) { struct route4_head *head = rtnl_dereference(tp->root); int h1, h2; if (head == NULL) - return true; - - if (!force) { - for (h1 = 0; h1 <= 256; h1++) { - if (rcu_access_pointer(head->table[h1])) - return false; - } - } + return; for (h1 = 0; h1 <= 256; h1++) { struct route4_bucket *b; @@ -312,12 +305,10 @@ static bool route4_destroy(struct tcf_proto *tp, bool force) kfree_rcu(b, rcu); } } - RCU_INIT_POINTER(tp->root, NULL); kfree_rcu(head, rcu); - return true; } -static int route4_delete(struct tcf_proto *tp, unsigned long arg) +static int route4_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct route4_head *head = rtnl_dereference(tp->root); struct route4_filter *f = (struct route4_filter *)arg; @@ -325,7 +316,7 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) struct route4_filter *nf; struct route4_bucket *b; unsigned int h = 0; - int i; + int i, h1; if (!head || !f) return -EINVAL; @@ -356,16 +347,25 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) rt = rtnl_dereference(b->ht[i]); if (rt) - return 0; + goto out; } /* OK, session has no flows */ RCU_INIT_POINTER(head->table[to_hash(h)], NULL); kfree_rcu(b, rcu); + break; + } + } - return 0; +out: + *last = true; + for (h1 = 0; h1 <= 256; h1++) { + if (rcu_access_pointer(head->table[h1])) { + *last = false; + break; } } + return 0; } diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 322438f..1aaff10 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -302,22 +302,13 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) call_rcu(&f->rcu, rsvp_delete_filter_rcu); } -static bool rsvp_destroy(struct tcf_proto *tp, bool force) +static void rsvp_destroy(struct tcf_proto *tp) { struct rsvp_head *data = rtnl_dereference(tp->root); int h1, h2; if (data == NULL) - return true; - - if (!force) { - for (h1 = 0; h1 < 256; h1++) { - if (rcu_access_pointer(data->ht[h1])) - return false; - } - } - - RCU_INIT_POINTER(tp->root, NULL); + return; for (h1 = 0; h1 < 256; h1++) { struct rsvp_session *s; @@ -337,10 +328,9 @@ static bool rsvp_destroy(struct tcf_proto *tp, bool force) } } kfree_rcu(data, rcu); - return true; } -static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) +static int rsvp_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct rsvp_head *head = rtnl_dereference(tp->root); struct rsvp_filter *nfp, *f = (struct rsvp_filter *)arg; @@ -348,7 +338,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) unsigned int h = f->handle; struct rsvp_session __rcu **sp; struct rsvp_session *nsp, *s = f->sess; - int i; + int i, h1; fp = &s->ht[(h >> 8) & 0xFF]; for (nfp = rtnl_dereference(*fp); nfp; @@ -361,7 +351,7 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) for (i = 0; i <= 16; i++) if (s->ht[i]) - return 0; + goto out; /* OK, session has no flows */ sp = &head->ht[h & 0xFF]; @@ -370,13 +360,23 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg) if (nsp == s) { RCU_INIT_POINTER(*sp, s->next); kfree_rcu(s, rcu); - return 0; + goto out; } } - return 0; + break; } } + +out: + *last = true; + for (h1 = 0; h1 < 256; h1++) { + if (rcu_access_pointer(head->ht[h1])) { + *last = false; + break; + } + } + return 0; } diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 0751245..9149a03 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -150,7 +150,7 @@ static void tcindex_destroy_fexts(struct rcu_head *head) kfree(f); } -static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) +static int tcindex_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct tcindex_data *p = rtnl_dereference(tp->root); struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; @@ -186,6 +186,8 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) call_rcu(&f->rcu, tcindex_destroy_fexts); else call_rcu(&r->rcu, tcindex_destroy_rexts); + + *last = false; return 0; } @@ -193,7 +195,9 @@ static int tcindex_destroy_element(struct tcf_proto *tp, unsigned long arg, struct tcf_walker *walker) { - return tcindex_delete(tp, arg); + bool last; + + return tcindex_delete(tp, arg, &last); } static void __tcindex_destroy(struct rcu_head *head) @@ -529,14 +533,11 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) } } -static bool tcindex_destroy(struct tcf_proto *tp, bool force) +static void tcindex_destroy(struct tcf_proto *tp) { struct tcindex_data *p = rtnl_dereference(tp->root); struct tcf_walker walker; - if (!force) - return false; - pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p); walker.count = 0; walker.skip = 0; @@ -544,7 +545,6 @@ static bool tcindex_destroy(struct tcf_proto *tp, bool force) tcindex_walk(tp, &walker); call_rcu(&p->rcu, __tcindex_destroy); - return true; } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index ae83c3ae..787573b 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -582,37 +582,13 @@ static bool ht_empty(struct tc_u_hnode *ht) return true; } -static bool u32_destroy(struct tcf_proto *tp, bool force) +static void u32_destroy(struct tcf_proto *tp) { struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *root_ht = rtnl_dereference(tp->root); WARN_ON(root_ht == NULL); - if (!force) { - if (root_ht) { - if (root_ht->refcnt > 1) - return false; - if (root_ht->refcnt == 1) { - if (!ht_empty(root_ht)) - return false; - } - } - - if (tp_c->refcnt > 1) - return false; - - if (tp_c->refcnt == 1) { - struct tc_u_hnode *ht; - - for (ht = rtnl_dereference(tp_c->hlist); - ht; - ht = rtnl_dereference(ht->next)) - if (!ht_empty(ht)) - return false; - } - } - if (root_ht && --root_ht->refcnt == 0) u32_destroy_hnode(tp, root_ht); @@ -637,20 +613,22 @@ static bool u32_destroy(struct tcf_proto *tp, bool force) } tp->data = NULL; - return true; } -static int u32_delete(struct tcf_proto *tp, unsigned long arg) +static int u32_delete(struct tcf_proto *tp, unsigned long arg, bool *last) { struct tc_u_hnode *ht = (struct tc_u_hnode *)arg; struct tc_u_hnode *root_ht = rtnl_dereference(tp->root); + struct tc_u_common *tp_c = tp->data; + int ret = 0; if (ht == NULL) - return 0; + goto out; if (TC_U32_KEY(ht->handle)) { u32_remove_hw_knode(tp, ht->handle); - return u32_delete_key(tp, (struct tc_u_knode *)ht); + ret = u32_delete_key(tp, (struct tc_u_knode *)ht); + goto out; } if (root_ht == ht) @@ -663,7 +641,40 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg) return -EBUSY; } - return 0; +out: + *last = true; + if (root_ht) { + if (root_ht->refcnt > 1) { + *last = false; + goto ret; + } + if (root_ht->refcnt == 1) { + if (!ht_empty(root_ht)) { + *last = false; + goto ret; + } + } + } + + if (tp_c->refcnt > 1) { + *last = false; + goto ret; + } + + if (tp_c->refcnt == 1) { + struct tc_u_hnode *ht; + + for (ht = rtnl_dereference(tp_c->hlist); + ht; + ht = rtnl_dereference(ht->next)) + if (!ht_empty(ht)) { + *last = false; + break; + } + } + +ret: + return ret; } #define NR_U32_NODE (1<<12) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index d7b9342..20293ee 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1899,15 +1899,11 @@ int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp, } EXPORT_SYMBOL(tc_classify); -bool tcf_destroy(struct tcf_proto *tp, bool force) +void tcf_destroy(struct tcf_proto *tp) { - if (tp->ops->destroy(tp, force)) { - module_put(tp->ops->owner); - kfree_rcu(tp, rcu); - return true; - } - - return false; + tp->ops->destroy(tp); + module_put(tp->ops->owner); + kfree_rcu(tp, rcu); } void tcf_destroy_chain(struct tcf_proto __rcu **fl) @@ -1916,7 +1912,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl) while ((tp = rtnl_dereference(*fl)) != NULL) { RCU_INIT_POINTER(*fl, tp->next); - tcf_destroy(tp, true); + tcf_destroy(tp); } } EXPORT_SYMBOL(tcf_destroy_chain);