linux/net/core
Xin Long 5213efec90 net: sched: refine software bypass handling in tc_run
[ Upstream commit a12c76a033 ]

This patch addresses issues with filter counting in block (tcf_block),
particularly for software bypass scenarios, by introducing a more
accurate mechanism using useswcnt.

Previously, filtercnt and skipswcnt were introduced by:

  Commit 2081fd3445 ("net: sched: cls_api: add filter counter") and
  Commit f631ef39d8 ("net: sched: cls_api: add skip_sw counter")

  filtercnt tracked all tp (tcf_proto) objects added to a block, and
  skipswcnt counted tp objects with the skipsw attribute set.

The problem is: a single tp can contain multiple filters, some with skipsw
and others without. The current implementation fails in the case:

  When the first filter in a tp has skipsw, both skipswcnt and filtercnt
  are incremented, then adding a second filter without skipsw to the same
  tp does not modify these counters because tp->counted is already set.

  This results in bypass software behavior based solely on skipswcnt
  equaling filtercnt, even when the block includes filters without
  skipsw. Consequently, filters without skipsw are inadvertently bypassed.

To address this, the patch introduces useswcnt in block to explicitly count
tp objects containing at least one filter without skipsw. Key changes
include:

  Whenever a filter without skipsw is added, its tp is marked with usesw
  and counted in useswcnt. tc_run() now uses useswcnt to determine software
  bypass, eliminating reliance on filtercnt and skipswcnt.

  This refined approach prevents software bypass for blocks containing
  mixed filters, ensuring correct behavior in tc_run().

Additionally, as atomic operations on useswcnt ensure thread safety and
tp->lock guards access to tp->usesw and tp->counted, the broader lock
down_write(&block->cb_lock) is no longer required in tc_new_tfilter(),
and this resolves a performance regression caused by the filter counting
mechanism during parallel filter insertions.

  The improvement can be demonstrated using the following script:

  # cat insert_tc_rules.sh

    tc qdisc add dev ens1f0np0 ingress
    for i in $(seq 16); do
        taskset -c $i tc -b rules_$i.txt &
    done
    wait

  Each of rules_$i.txt files above includes 100000 tc filter rules to a
  mlx5 driver NIC ens1f0np0.

  Without this patch:

  # time sh insert_tc_rules.sh

    real    0m50.780s
    user    0m23.556s
    sys	    4m13.032s

  With this patch:

  # time sh insert_tc_rules.sh

    real    0m17.718s
    user    0m7.807s
    sys     3m45.050s

Fixes: 047f340b36 ("net: sched: make skip_sw actually skip software")
Reported-by: Shuang Li <shuali@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Reviewed-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Tested-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-02-08 09:57:25 +01:00
..
bpf_sk_storage.c netlink: introduce type-checking attribute iteration 2024-03-29 15:06:02 -07:00
datagram.c net: add support for skbs with unreadable frags 2024-09-11 20:44:31 -07:00
dev.c net: sched: refine software bypass handling in tc_run 2025-02-08 09:57:25 +01:00
dev.h netdev: prevent accessing NAPI instances from another namespace 2025-01-17 13:41:00 +01:00
dev_addr_lists.c net: Correct spelling in net/core 2024-08-26 09:37:23 -07:00
dev_addr_lists_test.c net: dev_addr_lists: move locking out of init/exit in kunit 2024-04-15 10:26:35 +01:00
dev_ioctl.c netdevice: convert private flags > BIT(31) to bitfields 2024-09-03 11:36:43 +02:00
devmem.c memory-provider: dmabuf devmem memory provider 2024-09-11 20:44:31 -07:00
devmem.h tcp: RX path for devmem TCP 2024-09-11 20:44:32 -07:00
drop_monitor.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
dst.c net: do not delay dst_entries_add() in dst_release() 2024-10-10 11:28:17 +02:00
dst_cache.c net: dst_cache: add two DEBUG_NET warnings 2024-06-03 18:50:09 -07:00
failover.c net: failover: use IFF_NO_ADDRCONF flag to prevent ipv6 addrconf 2022-12-12 15:18:25 -08:00
fib_notifier.c net: fib_notifier: propagate extack down to the notifier block callback 2019-10-04 11:10:56 -07:00
fib_rules.c net: fib_rules: Enable DSCP selector usage 2024-09-13 21:15:45 -07:00
filter.c bpf: Fix bpf_sk_select_reuseport() memory leak 2025-01-23 17:22:47 +01:00
flow_dissector.c net: flow_dissector: use DEBUG_NET_WARN_ON_ONCE 2024-07-18 10:52:17 +02:00
flow_offload.c tc: flower: Enable offload support IPSEC SPI field. 2023-08-02 10:09:32 +01:00
gen_estimator.c net: use unrcu_pointer() helper 2024-06-06 11:52:52 +02:00
gen_stats.c net: Remove the obsolte u64_stats_fetch_*_irq() users (net). 2022-10-28 20:13:54 -07:00
gro.c net: Add netif_get_gro_max_size helper for GRO 2024-10-01 10:48:51 +02:00
gro_cells.c net: move netdev_max_backlog to net_hotdata 2024-03-07 21:12:42 -08:00
gso.c net: introduce struct net_hotdata 2024-03-07 21:12:41 -08:00
hotdata.c net: move sysctl_mem_pcpu_rsv to net_hotdata 2024-04-30 18:46:52 -07:00
hwbm.c net: hwbm: Make the hwbm_pool lock a mutex 2019-06-09 19:40:10 -07:00
ieee8021q_helpers.c net: add IEEE 802.1q specific helpers 2024-05-08 10:35:09 +01:00
link_watch.c ipvlan: Fix use-after-free in ipvlan_get_iflink(). 2025-01-17 13:40:39 +01:00
lwt_bpf.c bpf: lwtunnel: Unmask upper DSCP bits in bpf_lwt_xmit_reroute() 2024-09-09 14:14:52 +01:00
lwtunnel.c xfrm: lwtunnel: squelch kernel warning in case XFRM encap type is not available 2022-10-12 10:45:51 +02:00
Makefile netdev: support binding dma-buf to netdevice 2024-09-11 20:44:31 -07:00
mp_dmabuf_devmem.h memory-provider: dmabuf devmem memory provider 2024-09-11 20:44:31 -07:00
neighbour.c net/neighbor: clear error in case strict check is not set 2024-12-14 20:03:57 +01:00
net-procfs.c net: make softnet_data.dropped an atomic_t 2024-04-01 11:28:32 +01:00
net-sysfs.c net: sysfs: Fix weird usage of class's namespace relevant fields 2024-09-09 10:30:52 +01:00
net-sysfs.h net-sysfs: add netdev_change_owner() 2020-02-26 20:07:25 -08:00
net-traces.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
net_namespace.c net: defer final 'struct net' free in netns dismantle 2024-12-19 18:13:13 +01:00
net_test.c pfcp: always set pfcp metadata 2024-04-01 10:49:28 +01:00
netclassid_cgroup.c cgroup, netclassid: on modifying netclassid in cgroup, only consider the main process. 2023-10-16 16:36:53 -07:00
netdev-genl-gen.c netdev: avoid CFI problems with sock priv helpers 2025-01-23 17:22:52 +01:00
netdev-genl-gen.h netdev: support binding dma-buf to netdevice 2024-09-11 20:44:31 -07:00
netdev-genl.c netdev: prevent accessing NAPI instances from another namespace 2025-01-17 13:41:00 +01:00
netdev_rx_queue.c memory-provider: dmabuf devmem memory provider 2024-09-11 20:44:31 -07:00
netevent.c net: core: Correct function name netevent_unregister_notifier() in the kerneldoc 2021-03-28 17:56:56 -07:00
netmem_priv.h page_pool: devmem support 2024-09-11 20:44:31 -07:00
netpoll.c netpoll: Use rcu_access_pointer() in __netpoll_setup 2024-12-14 20:03:58 +01:00
netprio_cgroup.c bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode 2021-09-13 16:35:58 -07:00
of_net.c net: Explicitly include correct DT includes 2023-07-27 20:33:16 -07:00
page_pool.c memory-provider: dmabuf devmem memory provider 2024-09-11 20:44:31 -07:00
page_pool_priv.h memory-provider: dmabuf devmem memory provider 2024-09-11 20:44:31 -07:00
page_pool_user.c netdev: add dmabuf introspection 2024-09-11 20:44:32 -07:00
pktgen.c pktgen: Avoid out-of-bounds access in get_imix_entries 2025-01-23 17:22:48 +01:00
ptp_classifier.c ptp: Add generic PTP is_sync() function 2022-03-07 11:31:34 +00:00
request_sock.c tcp: make sure init the accept_queue's spinlocks once 2024-01-19 21:13:25 -08:00
rtnetlink.c net: fix crash when config small gso_max_size/gso_ipv4_max_size 2024-10-29 16:18:23 -07:00
scm.c af_unix: Add dead flag to struct scm_fp_list. 2024-05-10 18:52:45 -07:00
secure_seq.c tcp: Fix data-races around sysctl knobs related to SYN option. 2022-07-20 10:14:49 +01:00
selftests.c net: fill in MODULE_DESCRIPTION()s under net/core 2023-10-28 11:29:27 +01:00
skbuff.c net: add support for skbs with unreadable frags 2024-09-11 20:44:31 -07:00
skmsg.c tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection 2025-01-02 10:34:11 +01:00
sock.c net: restrict SO_REUSEPORT to inet sockets 2025-01-09 13:33:41 +01:00
sock_destructor.h skb_expand_head() adjust skb->truesize incorrectly 2021-10-22 12:35:51 -07:00
sock_diag.c net: use unrcu_pointer() helper 2024-06-06 11:52:52 +02:00
sock_map.c bpf, sockmap: Fix update element with same 2024-12-19 18:13:10 +01:00
sock_reuseport.c net: core: annotate socks of struct sock_reuseport with __counted_by 2024-08-02 17:16:59 -07:00
stream.c net: Return error from sk_stream_wait_connect() if sk_wait_event() fails 2023-12-15 10:48:51 +00:00
sysctl_net_core.c net: let net.core.dev_weight always be non-zero 2025-02-08 09:57:24 +01:00
timestamping.c net: Change the API of PHY default timestamp to MAC 2024-07-15 08:02:26 -07:00
tso.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
utils.c net: Correct spelling in net/core 2024-08-26 09:37:23 -07:00
xdp.c xdp: fix invalid wait context of page_pool_destroy() 2024-07-14 20:40:21 -07:00