[PATCH OLK-6.6 0/3] fix oenetcls bugs

Wang Liang (3): net/oenetcls: use raw_smp_processor_id() instead of smp_processor_id() net/oenetcls: remove oenetcls trace hook net/oenetcls: use workqueue for ntuple cfg arch/arm64/configs/openeuler_defconfig | 1 - arch/x86/configs/openeuler_defconfig | 1 - drivers/hooks/Kconfig | 10 -- drivers/hooks/vendor_hooks.c | 8 -- include/linux/oenetcls.h | 81 ++++++++++++++ include/trace/hooks/oenetcls.h | 44 -------- net/core/dev.c | 23 ++-- net/ipv4/af_inet.c | 9 +- net/ipv4/tcp.c | 13 ++- net/oenetcls/Kconfig | 1 - net/oenetcls/oenetcls.h | 10 ++ net/oenetcls/oenetcls_flow.c | 39 ++++--- net/oenetcls/oenetcls_main.c | 4 +- net/oenetcls/oenetcls_ntuple.c | 149 +++++++++++++++---------- 14 files changed, 232 insertions(+), 161 deletions(-) create mode 100644 include/linux/oenetcls.h delete mode 100644 include/trace/hooks/oenetcls.h -- 2.34.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/17980 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FWR... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/17980 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FWR...

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICS3XV -------------------------------- Function smp_processor_id() should not be used in preemptible code. Fixes: 4bed6ba0e88f ("net/oenetcls: introduce oenetcls for network optimization") Signed-off-by: Wang Liang <wangliang74@huawei.com> --- net/oenetcls/oenetcls_main.c | 4 ++-- net/oenetcls/oenetcls_ntuple.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/oenetcls/oenetcls_main.c b/net/oenetcls/oenetcls_main.c index 67c73f4595be..ef3c6dabb2f3 100644 --- a/net/oenetcls/oenetcls_main.c +++ b/net/oenetcls/oenetcls_main.c @@ -671,7 +671,7 @@ static int init_numa_rxq_bitmap(int nid, struct oecls_numa_info *numa_info) static int get_cluster_rxq(struct oecls_numa_bound_dev_info *bound_dev) { - int cpu = smp_processor_id(); + int cpu = raw_smp_processor_id(); int cluster_id = cpu / oecls_cluster_cpu_num; int i, j, rxq_id; @@ -796,7 +796,7 @@ static int init_oecls_numa_info(void) return ret; } - oecls_cluster_cpu_num = cpumask_weight(topology_cluster_cpumask(smp_processor_id())); + oecls_cluster_cpu_num = cpumask_weight(topology_cluster_cpumask(raw_smp_processor_id())); oecls_cluster_per_numa = (nr_cpu_ids / oecls_cluster_cpu_num) / oecls_numa_num; oecls_debug("oecls_numa_num=%d cluster_cpu_num:%d cluster_cpu_num:%d\n", oecls_numa_num, oecls_cluster_per_numa, oecls_cluster_cpu_num); diff --git a/net/oenetcls/oenetcls_ntuple.c b/net/oenetcls/oenetcls_ntuple.c index 3986d86efe83..7cbfe2841706 100644 --- a/net/oenetcls/oenetcls_ntuple.c +++ b/net/oenetcls/oenetcls_ntuple.c @@ -465,7 +465,7 @@ static void add_ntuple_rule(struct sock *sk) { struct oecls_netdev_info *oecls_dev; struct cmd_context ctx = { 0 }; - int cpu = smp_processor_id(); + int cpu = raw_smp_processor_id(); int nid = cpu_to_node(cpu); int rxq_id; int devid; @@ -511,7 +511,7 @@ static void ethtool_cfg_rxcls(void *data, struct sock *sk, int is_del) if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) return; - oecls_debug("[cpu:%d] app:%s, sk:%p, is_del:%d, ip:%pI4, port:%d\n", smp_processor_id(), + oecls_debug("[cpu:%d] app:%s, sk:%p, is_del:%d, ip:%pI4, port:%d\n", raw_smp_processor_id(), current->comm, sk, is_del, &sk->sk_rcv_saddr, (u16)sk->sk_num); if (is_del) -- 2.34.1

hulk inclusion category: cleanup bugzilla: https://gitee.com/openeuler/kernel/issues/ICS3XV -------------------------------- Use oecls_hook_ops instead of trace hook. Signed-off-by: Wang Liang <wangliang74@huawei.com> --- arch/arm64/configs/openeuler_defconfig | 1 - arch/x86/configs/openeuler_defconfig | 1 - drivers/hooks/Kconfig | 10 ---- drivers/hooks/vendor_hooks.c | 8 --- include/linux/oenetcls.h | 81 ++++++++++++++++++++++++++ include/trace/hooks/oenetcls.h | 44 -------------- net/core/dev.c | 23 ++++---- net/ipv4/af_inet.c | 9 ++- net/ipv4/tcp.c | 13 +++-- net/oenetcls/Kconfig | 1 - net/oenetcls/oenetcls_flow.c | 39 ++++++++----- net/oenetcls/oenetcls_ntuple.c | 15 +++-- 12 files changed, 144 insertions(+), 101 deletions(-) create mode 100644 include/linux/oenetcls.h delete mode 100644 include/trace/hooks/oenetcls.h diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index bbe2488e6440..66c2944917aa 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -6951,7 +6951,6 @@ CONFIG_USB4=m # CONFIG_VENDOR_HOOKS=y CONFIG_VENDOR_BOND_HOOKS=y -CONFIG_OENETCLS_HOOKS=y CONFIG_OENETCLS=m # end of Vendor Hooks diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 9d884b734f4c..229d08b3d8de 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -8146,7 +8146,6 @@ CONFIG_USB4=m # CONFIG_VENDOR_HOOKS=y CONFIG_VENDOR_BOND_HOOKS=y -# CONFIG_OENETCLS_HOOKS is not set # end of Vendor Hooks CONFIG_LIBNVDIMM=m diff --git a/drivers/hooks/Kconfig b/drivers/hooks/Kconfig index 90b0f6ea4040..6a00168e67ad 100644 --- a/drivers/hooks/Kconfig +++ b/drivers/hooks/Kconfig @@ -20,14 +20,4 @@ config VENDOR_BOND_HOOKS Allow vendor modules to attach bonding driver hooks defined via DECLARE_HOOK or DECLARE_RESTRICTED_HOOK. -config OENETCLS_HOOKS - bool "Oenetcls driver Hooks" - depends on VENDOR_HOOKS - default n - help - Enable oenetcls vendor hooks - Allow vendor modules to attach oenetcls hooks defined via - DECLARE_HOOK or DECLARE_RESTRICTED_HOOK. - Use OENETCLS && OENETCLS_HOOKS to enable oenetcls feature. - endmenu diff --git a/drivers/hooks/vendor_hooks.c b/drivers/hooks/vendor_hooks.c index d9b85b57a742..85bda58159f6 100644 --- a/drivers/hooks/vendor_hooks.c +++ b/drivers/hooks/vendor_hooks.c @@ -9,7 +9,6 @@ #define CREATE_TRACE_POINTS #include <trace/hooks/vendor_hooks.h> #include <trace/hooks/bonding.h> -#include <trace/hooks/oenetcls.h> /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -19,10 +18,3 @@ #ifdef CONFIG_VENDOR_BOND_HOOKS EXPORT_TRACEPOINT_SYMBOL_GPL(vendor_bond_check_dev_link); #endif - -#ifdef CONFIG_OENETCLS_HOOKS -EXPORT_TRACEPOINT_SYMBOL_GPL(oecls_flow_update); -EXPORT_TRACEPOINT_SYMBOL_GPL(oecls_set_cpu); -EXPORT_TRACEPOINT_SYMBOL_GPL(oecls_timeout); -EXPORT_TRACEPOINT_SYMBOL_GPL(ethtool_cfg_rxcls); -#endif diff --git a/include/linux/oenetcls.h b/include/linux/oenetcls.h new file mode 100644 index 000000000000..29c0db40971f --- /dev/null +++ b/include/linux/oenetcls.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _LINUX_OENETCLS_H +#define _LINUX_OENETCLS_H + +struct oecls_hook_ops { + void (*oecls_cfg_rxcls)(struct sock *sk, int is_del); + void (*oecls_flow_update)(struct sock *sk); + void (*oecls_set_cpu)(struct sk_buff *skb); + bool (*oecls_timeout)(struct net_device *dev, u16 rxq_index, + u32 flow_id, u16 filter_id); +}; + +extern const struct oecls_hook_ops __rcu *oecls_ops; + +static inline void oenetcls_cfg_rxcls(struct sock *sk, int is_del) +{ + const struct oecls_hook_ops *ops; + + rcu_read_lock(); + ops = rcu_dereference(oecls_ops); + if (ops && ops->oecls_cfg_rxcls) + ops->oecls_cfg_rxcls(sk, is_del); + rcu_read_unlock(); +} + +static inline void oenetcls_flow_update(struct sock *sk) +{ + const struct oecls_hook_ops *ops; + + rcu_read_lock(); + ops = rcu_dereference(oecls_ops); + if (ops && ops->oecls_flow_update) + ops->oecls_flow_update(sk); + rcu_read_unlock(); +} + +static inline void oenetcls_skb_set_cpu(struct sk_buff *skb) +{ + const struct oecls_hook_ops *ops; + + rcu_read_lock(); + ops = rcu_dereference(oecls_ops); + if (ops && ops->oecls_set_cpu) + ops->oecls_set_cpu(skb); + rcu_read_unlock(); +} + +static inline void oenetcls_skblist_set_cpu(struct list_head *head) +{ + const struct oecls_hook_ops *ops; + struct sk_buff *skb, *next; + + rcu_read_lock(); + ops = rcu_dereference(oecls_ops); + if (ops && ops->oecls_set_cpu) { + list_for_each_entry_safe(skb, next, head, list) + ops->oecls_set_cpu(skb); + } + rcu_read_unlock(); +} + +static inline bool oenetcls_may_expire_flow(struct net_device *dev, + u16 rxq_index, u32 flow_id, + u16 filter_id, bool *expire) +{ + const struct oecls_hook_ops *ops; + + rcu_read_lock(); + ops = rcu_dereference(oecls_ops); + if (ops && ops->oecls_timeout) { + *expire = ops->oecls_timeout(dev, rxq_index, flow_id, filter_id); + rcu_read_unlock(); + return true; + } + rcu_read_unlock(); + + return false; +} + +#endif /* _LINUX_OENETCLS_H */ + diff --git a/include/trace/hooks/oenetcls.h b/include/trace/hooks/oenetcls.h deleted file mode 100644 index c38545d7a6a2..000000000000 --- a/include/trace/hooks/oenetcls.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * oenetcls driver Hooks - * - * Copyright (c) 2025, Huawei Tech. Co., Ltd. - */ - -#ifdef CONFIG_OENETCLS_HOOKS - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM oenetcls - -#define TRACE_INCLUDE_PATH trace/hooks -#if !defined(_TRACE_OENETCLS_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_OENETCLS_H -#include <linux/tracepoint.h> -#include <trace/hooks/vendor_hooks.h> - -struct sock; -struct sk_buff; -struct net_device; - -DECLARE_HOOK(oecls_flow_update, -TP_PROTO(struct sock *sk), -TP_ARGS(sk)); - -DECLARE_HOOK(oecls_set_cpu, -TP_PROTO(struct sk_buff *skb), -TP_ARGS(skb)); - -DECLARE_HOOK(oecls_timeout, -TP_PROTO(struct net_device *dev, u16 rxq_index, u32 flow_id, u16 filter_id, bool *ret), -TP_ARGS(dev, rxq_index, flow_id, filter_id, ret)); - -DECLARE_HOOK(ethtool_cfg_rxcls, -TP_PROTO(struct sock *sk, int is_del), -TP_ARGS(sk, is_del)); - -#endif -/* This part must be outside protection */ -#include <trace/define_trace.h> - -#endif - diff --git a/net/core/dev.c b/net/core/dev.c index 78f94e67780f..e2d61f786c8a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -154,11 +154,16 @@ #include <linux/once_lite.h> #include <net/netdev_rx_queue.h> #include <linux/if_caqm.h> -#include <trace/hooks/oenetcls.h> #include "dev.h" #include "net-sysfs.h" +#if IS_ENABLED(CONFIG_OENETCLS) +#include <linux/oenetcls.h> +const struct oecls_hook_ops __rcu *oecls_ops __read_mostly; +EXPORT_SYMBOL_GPL(oecls_ops); +#endif + static DEFINE_SPINLOCK(ptype_lock); struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; struct list_head ptype_all __read_mostly; /* Taps */ @@ -4728,10 +4733,9 @@ bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index, bool expire = true; unsigned int cpu; -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - trace_oecls_timeout(dev, rxq_index, flow_id, filter_id, &expire); - if (expire) - return true; +#if IS_ENABLED(CONFIG_OENETCLS) + if (oenetcls_may_expire_flow(dev, rxq_index, flow_id, filter_id, &expire)) + return expire; #endif rcu_read_lock(); flow_table = rcu_dereference(rxqueue->rps_flow_table); @@ -5891,8 +5895,8 @@ static int netif_receive_skb_internal(struct sk_buff *skb) } #endif -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - trace_oecls_set_cpu(skb); +#if IS_ENABLED(CONFIG_OENETCLS) + oenetcls_skb_set_cpu(skb); #endif ret = __netif_receive_skb(skb); @@ -5930,9 +5934,8 @@ void netif_receive_skb_list_internal(struct list_head *head) } #endif -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - list_for_each_entry_safe(skb, next, head, list) - trace_oecls_set_cpu(skb); +#if IS_ENABLED(CONFIG_OENETCLS) + oenetcls_skblist_set_cpu(head); #endif __netif_receive_skb_list(head); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index ee224b196666..ab3f7dfcae94 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -121,7 +121,10 @@ #include <net/compat.h> #include <trace/events/sock.h> -#include <trace/hooks/oenetcls.h> + +#if IS_ENABLED(CONFIG_OENETCLS) +#include <linux/oenetcls.h> +#endif /* The inetsw table contains everything that inet_create needs to * build a new socket. @@ -220,8 +223,8 @@ int __inet_listen_sk(struct sock *sk, int backlog) return err; tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_LISTEN_CB, 0, NULL); -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - trace_ethtool_cfg_rxcls(sk, 0); +#if IS_ENABLED(CONFIG_OENETCLS) + oenetcls_cfg_rxcls(sk, 0); #endif } return 0; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index aebcda267a9a..41c02ed1c26e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -279,7 +279,10 @@ #include <linux/uaccess.h> #include <asm/ioctls.h> #include <net/busy_poll.h> -#include <trace/hooks/oenetcls.h> + +#if IS_ENABLED(CONFIG_OENETCLS) +#include <linux/oenetcls.h> +#endif /* Track pending CMSGs. */ enum { @@ -2578,8 +2581,8 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, if (unlikely(flags & MSG_ERRQUEUE)) return inet_recv_error(sk, msg, len, addr_len); -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - trace_oecls_flow_update(sk); +#if IS_ENABLED(CONFIG_OENETCLS) + oenetcls_flow_update(sk); #endif if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) && @@ -2944,8 +2947,8 @@ void __tcp_close(struct sock *sk, long timeout) void tcp_close(struct sock *sk, long timeout) { lock_sock(sk); -#if IS_ENABLED(CONFIG_OENETCLS_HOOKS) - trace_ethtool_cfg_rxcls(sk, 1); +#if IS_ENABLED(CONFIG_OENETCLS) + oenetcls_cfg_rxcls(sk, 1); #endif __tcp_close(sk, timeout); release_sock(sk); diff --git a/net/oenetcls/Kconfig b/net/oenetcls/Kconfig index 2ab980258c31..68d5c6904319 100644 --- a/net/oenetcls/Kconfig +++ b/net/oenetcls/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only config OENETCLS tristate "Network classification" - depends on OENETCLS_HOOKS default n help Allows to configure ntuple rule, and bind interrupt to netdev diff --git a/net/oenetcls/oenetcls_flow.c b/net/oenetcls/oenetcls_flow.c index 5dc58e8bae25..670ca3631fdc 100644 --- a/net/oenetcls/oenetcls_flow.c +++ b/net/oenetcls/oenetcls_flow.c @@ -7,7 +7,7 @@ #include <linux/inet.h> #include <net/netdev_rx_queue.h> #include <net/sock.h> -#include <trace/hooks/oenetcls.h> +#include <linux/oenetcls.h> #include "oenetcls.h" static u32 oecls_cpu_mask; @@ -27,8 +27,8 @@ bool is_oecls_config_netdev(const char *name) return false; } -static void oecls_timeout(void *data, struct net_device *dev, u16 rxq_index, - u32 flow_id, u16 filter_id, bool *ret) +static bool _oecls_timeout(struct net_device *dev, u16 rxq_index, + u32 flow_id, u16 filter_id) { struct netdev_rx_queue *rxqueue = dev->_rx + rxq_index; struct oecls_dev_flow_table *flow_table; @@ -56,10 +56,10 @@ static void oecls_timeout(void *data, struct net_device *dev, u16 rxq_index, rcu_read_unlock(); oecls_debug("%s, dev:%s, rxq:%d, flow_id:%u, filter_id:%d, expire:%d\n", __func__, dev->name, rxq_index, flow_id, filter_id, expire); - *ret = expire; + return expire; } -static void oecls_flow_update(void *data, struct sock *sk) +static void _oecls_flow_update(struct sock *sk) { struct oecls_sock_flow_table *tb; unsigned int hash, index; @@ -201,7 +201,7 @@ static void __oecls_set_cpu(struct sk_buff *skb, struct net_device *ndev, set_oecls_cpu(ndev, skb, rflow, old_rxq_id, last_recv_cpu); } -static void oecls_set_cpu(void *data, struct sk_buff *skb) +static void _oecls_set_cpu(struct sk_buff *skb) { struct net_device *ndev = skb->dev; struct oecls_sock_flow_table *stb; @@ -356,9 +356,6 @@ static int oecls_sock_flow_table_release(void) synchronize_rcu(); vfree(tb); - unregister_trace_oecls_flow_update(&oecls_flow_update, NULL); - unregister_trace_oecls_set_cpu(&oecls_set_cpu, NULL); - unregister_trace_oecls_timeout(&oecls_timeout, NULL); return 0; } @@ -384,20 +381,34 @@ static int oecls_sock_flow_table_init(void) rcu_assign_pointer(oecls_sock_flow_table, table); mutex_unlock(&oecls_sock_flow_mutex); - register_trace_oecls_flow_update(oecls_flow_update, NULL); - register_trace_oecls_set_cpu(&oecls_set_cpu, NULL); - register_trace_oecls_timeout(&oecls_timeout, NULL); return 0; } +static const struct oecls_hook_ops oecls_flow_ops = { + .oecls_flow_update = _oecls_flow_update, + .oecls_set_cpu = _oecls_set_cpu, + .oecls_timeout = _oecls_timeout, + .oecls_cfg_rxcls = NULL, +}; + void oecls_flow_res_init(void) { - oecls_sock_flow_table_init(); - oecls_dev_flow_table_init(); + int err; + + err = oecls_sock_flow_table_init(); + if (err) + return; + + err = oecls_dev_flow_table_init(); + if (err) + return; + + RCU_INIT_POINTER(oecls_ops, &oecls_flow_ops); } void oecls_flow_res_clean(void) { + RCU_INIT_POINTER(oecls_ops, NULL); oecls_sock_flow_table_release(); oecls_dev_flow_table_release(); } diff --git a/net/oenetcls/oenetcls_ntuple.c b/net/oenetcls/oenetcls_ntuple.c index 7cbfe2841706..3b69f927d25b 100644 --- a/net/oenetcls/oenetcls_ntuple.c +++ b/net/oenetcls/oenetcls_ntuple.c @@ -8,7 +8,7 @@ #include <linux/inet.h> #include <linux/jhash.h> #include <net/sock.h> -#include <trace/hooks/oenetcls.h> +#include <linux/oenetcls.h> #include "oenetcls.h" struct oecls_sk_rule_list oecls_sk_rules, oecls_sk_list; @@ -503,7 +503,7 @@ static void add_ntuple_rule(struct sock *sk) mutex_unlock(&oecls_sk_rules.mutex); } -static void ethtool_cfg_rxcls(void *data, struct sock *sk, int is_del) +static void ethtool_cfg_rxcls(struct sock *sk, int is_del) { if (sk->sk_state != TCP_LISTEN) return; @@ -552,14 +552,21 @@ static void clean_oecls_sk_rules(void) mutex_unlock(&oecls_sk_rules.mutex); } +static const struct oecls_hook_ops oecls_ntuple_ops = { + .oecls_flow_update = NULL, + .oecls_set_cpu = NULL, + .oecls_timeout = NULL, + .oecls_cfg_rxcls = ethtool_cfg_rxcls, +}; + void oecls_ntuple_res_init(void) { init_oecls_sk_rules(); - register_trace_ethtool_cfg_rxcls(ðtool_cfg_rxcls, NULL); + RCU_INIT_POINTER(oecls_ops, &oecls_ntuple_ops); } void oecls_ntuple_res_clean(void) { - unregister_trace_ethtool_cfg_rxcls(ðtool_cfg_rxcls, NULL); + RCU_INIT_POINTER(oecls_ops, NULL); clean_oecls_sk_rules(); } -- 2.34.1

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICS3XV -------------------------------- Use workqueue for ntuple cfg to avoid mutex_lock in rcu context. Fixes: 4bed6ba0e88f ("net/oenetcls: introduce oenetcls for network optimization") Signed-off-by: Wang Liang <wangliang74@huawei.com> --- net/oenetcls/oenetcls.h | 10 +++ net/oenetcls/oenetcls_ntuple.c | 130 +++++++++++++++++++-------------- 2 files changed, 84 insertions(+), 56 deletions(-) diff --git a/net/oenetcls/oenetcls.h b/net/oenetcls/oenetcls.h index 215ae3e7e153..2eef768e365e 100644 --- a/net/oenetcls/oenetcls.h +++ b/net/oenetcls/oenetcls.h @@ -121,6 +121,16 @@ struct rmgr_ctrl { __u32 size; }; +struct cfg_param { + struct work_struct work; + struct cmd_context ctx; + struct oecls_sk_rule *rule; + struct sock *sk; + bool is_del; + int devid; + int nid; +}; + extern int match_ip_flag; extern int debug; extern int oecls_netdev_num; diff --git a/net/oenetcls/oenetcls_ntuple.c b/net/oenetcls/oenetcls_ntuple.c index 3b69f927d25b..a80830fb75a5 100644 --- a/net/oenetcls/oenetcls_ntuple.c +++ b/net/oenetcls/oenetcls_ntuple.c @@ -12,6 +12,7 @@ #include "oenetcls.h" struct oecls_sk_rule_list oecls_sk_rules, oecls_sk_list; +static struct workqueue_struct *do_cfg_workqueue; static void init_oecls_sk_rules(void) { @@ -422,85 +423,96 @@ static int cfg_ethtool_rule(struct cmd_context *ctx, bool is_del) return ret; } -static void del_ntuple_rule(struct sock *sk) +static void cfg_work(struct work_struct *work) { + struct cfg_param *ctx_p = container_of(work, struct cfg_param, work); struct oecls_netdev_info *oecls_dev; - struct cmd_context ctx = { 0 }; struct oecls_sk_rule *rule; - int devid; - u16 dport; - u32 dip4; + int devid, rxq_id; int err; - get_sk_rule_addr(sk, &dip4, &dport); - mutex_lock(&oecls_sk_rules.mutex); for_each_oecls_netdev(devid, oecls_dev) { - strncpy(ctx.netdev, oecls_dev->dev_name, IFNAMSIZ); - rule = get_rule_from_sk(devid, sk); - if (!rule) { - oecls_debug("rule not found! sk:%p, devid:%d, dip4:%pI4, dport:%d\n", - sk, devid, &dip4, ntohs(dport)); - continue; - } + strncpy(ctx_p->ctx.netdev, oecls_dev->dev_name, IFNAMSIZ); + if (!ctx_p->is_del) { + if (reuseport_check(devid, ctx_p->ctx.dip4, ctx_p->ctx.dport)) { + oecls_error("dip4:%pI4, dport:%d reuse!\n", &ctx_p->ctx.dip4, + ctx_p->ctx.dport); + continue; + } - // Config Ntuple rule to dev - ctx.del_ruleid = rule->ruleid; - err = cfg_ethtool_rule(&ctx, true); - if (err) { - oecls_error("del sk:%p, nid:%d, devid:%d, action:%d, ruleid:%d, err:%d\n", - sk, rule->nid, devid, rule->action, rule->ruleid, err); - } + // Calculate the bound queue + rxq_id = alloc_rxq_id(ctx_p->nid, devid); + if (rxq_id < 0) + continue; - // Free the bound queue - free_rxq_id(rule->nid, devid, rule->action); + // Config Ntuple rule to dev + ctx_p->ctx.action = (u16)rxq_id; + err = cfg_ethtool_rule(&ctx_p->ctx, ctx_p->is_del); + // Add sk rule only on success + if (!err) + add_sk_rule(ctx_p->devid, ctx_p->ctx.dip4, ctx_p->ctx.dport, + ctx_p->sk, ctx_p->ctx.action, ctx_p->ctx.ret_loc, + ctx_p->nid); + } else { + rule = get_rule_from_sk(ctx_p->devid, ctx_p->sk); + if (!rule) { + oecls_debug("rule not found! sk:%p, devid:%d, dip4:%pI4, dport:%d\n", + ctx_p->sk, ctx_p->devid, &ctx_p->ctx.dip4, + ntohs(ctx_p->ctx.dport)); + continue; + } - // Delete sk rule - del_sk_rule(rule); + // Config Ntuple rule to dev + ctx_p->ctx.del_ruleid = rule->ruleid; + ctx_p->rule = rule; + err = cfg_ethtool_rule(&ctx_p->ctx, ctx_p->is_del); + // Free the bound queue + free_rxq_id(ctx_p->rule->nid, ctx_p->devid, ctx_p->rule->action); + // Delete sk rule + del_sk_rule(ctx_p->rule); + } } mutex_unlock(&oecls_sk_rules.mutex); + kfree(ctx_p); +} + +static void del_ntuple_rule(struct sock *sk) +{ + struct cfg_param *ctx_p; + u16 dport; + u32 dip4; + + ctx_p = kzalloc(sizeof(*ctx_p), GFP_ATOMIC); + if (!ctx_p) + return; + get_sk_rule_addr(sk, &dip4, &dport); + + ctx_p->is_del = true; + ctx_p->sk = sk; + INIT_WORK(&ctx_p->work, cfg_work); + queue_work(do_cfg_workqueue, &ctx_p->work); } static void add_ntuple_rule(struct sock *sk) { - struct oecls_netdev_info *oecls_dev; - struct cmd_context ctx = { 0 }; + struct cfg_param *ctx_p; int cpu = raw_smp_processor_id(); int nid = cpu_to_node(cpu); - int rxq_id; - int devid; - int err; if (check_appname(current->comm)) return; - get_sk_rule_addr(sk, &ctx.dip4, &ctx.dport); - - mutex_lock(&oecls_sk_rules.mutex); - for_each_oecls_netdev(devid, oecls_dev) { - strncpy(ctx.netdev, oecls_dev->dev_name, IFNAMSIZ); - if (reuseport_check(devid, ctx.dip4, ctx.dport)) { - oecls_error("dip4:%pI4, dport:%d reuse!\n", &ctx.dip4, ctx.dport); - continue; - } - // Calculate the bound queue - rxq_id = alloc_rxq_id(nid, devid); - if (rxq_id < 0) - continue; - - // Config Ntuple rule to dev - ctx.action = (u16)rxq_id; - err = cfg_ethtool_rule(&ctx, false); - if (err) { - oecls_error("add sk:%p, nid:%d, devid:%d, action:%d, ruleid:%d, err:%d\n", - sk, nid, devid, ctx.action, ctx.ret_loc, err); - continue; - } + ctx_p = kzalloc(sizeof(*ctx_p), GFP_ATOMIC); + if (!ctx_p) + return; + get_sk_rule_addr(sk, &ctx_p->ctx.dip4, &ctx_p->ctx.dport); - // Add sk rule - add_sk_rule(devid, ctx.dip4, ctx.dport, sk, ctx.action, ctx.ret_loc, nid); - } - mutex_unlock(&oecls_sk_rules.mutex); + ctx_p->is_del = false; + ctx_p->sk = sk; + ctx_p->nid = nid; + INIT_WORK(&ctx_p->work, cfg_work); + queue_work(do_cfg_workqueue, &ctx_p->work); } static void ethtool_cfg_rxcls(struct sock *sk, int is_del) @@ -561,6 +573,12 @@ static const struct oecls_hook_ops oecls_ntuple_ops = { void oecls_ntuple_res_init(void) { + do_cfg_workqueue = alloc_ordered_workqueue("oecls_cfg", 0); + if (!do_cfg_workqueue) { + oecls_debug("alloc_ordered_workqueue fails\n"); + return; + } + init_oecls_sk_rules(); RCU_INIT_POINTER(oecls_ops, &oecls_ntuple_ops); } -- 2.34.1
participants (2)
-
patchwork bot
-
Wang Liang