From: Li Xiasong <lixiasong1@huawei.com> hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9244 -------------------------------- Rule add/delete is handled asynchronously and delete can be queued before the corresponding add work has committed the rule state. This may cause delete to be skipped by an early "rule not found" check. Move the existence check into cfg_work under vecls_sk_rules.mutex, so the decision is made in the same serialized worker context as rule updates. This avoids dropping valid delete requests during add/delete reordering. Signed-off-by: Li Xiasong <lixiasong1@huawei.com> Signed-off-by: Yue Haibing <yuehaibing@huawei.com> --- net/venetcls/venetcls_ntuple.c | 44 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/net/venetcls/venetcls_ntuple.c b/net/venetcls/venetcls_ntuple.c index 6044465d0bba..22539a0e559a 100644 --- a/net/venetcls/venetcls_ntuple.c +++ b/net/venetcls/venetcls_ntuple.c @@ -147,6 +147,23 @@ static struct vecls_sk_rule *get_rule_from_sk(int devid, void *sk) return rule; } +static bool has_sock_rule(struct sock *sk) +{ + struct vecls_netdev_info *vecls_dev; + struct vecls_sk_rule *rule; + int devid; + + for (devid = 0; devid < vecls_netdev_num; devid++) { + vecls_dev = get_vecls_netdev_info(devid); + if (!vecls_dev) + continue; + rule = get_rule_from_sk(devid, sk); + if (rule) + return true; + } + return false; +} + static inline bool reuseport_check(int devid, struct cmd_context ctx) { return !!get_sk_rule(devid, ctx); @@ -477,6 +494,11 @@ static void cfg_work(struct work_struct *work) struct vecls_sk_rule *rule; int devid, rxq_id, err; + mutex_lock(&vecls_sk_rules.mutex); + if (ctx_p->is_del && !has_sock_rule(ctx_p->sk)) + goto out_lock; + mutex_unlock(&vecls_sk_rules.mutex); + get_sk_rule_addr(ctx_p); mutex_lock(&vecls_sk_rules.mutex); @@ -529,36 +551,18 @@ static void cfg_work(struct work_struct *work) del_sk_rule(rule); } } + +out_lock: mutex_unlock(&vecls_sk_rules.mutex); put_net(ctx_p->sk_snapshot.net); kfree(ctx_p); atomic_dec(&vecls_worker_count); } -static bool has_sock_rule(struct sock *sk) -{ - struct vecls_netdev_info *vecls_dev; - struct vecls_sk_rule *rule; - int devid; - - for (devid = 0; devid < vecls_netdev_num; devid++) { - vecls_dev = get_vecls_netdev_info(devid); - if (!vecls_dev) - continue; - rule = get_rule_from_sk(devid, sk); - if (rule) - return true; - } - return false; -} - static void del_ntuple_rule(struct sock *sk) { struct cfg_param *ctx_p; - if (!has_sock_rule(sk)) - return; - ctx_p = kzalloc(sizeof(*ctx_p), GFP_ATOMIC); if (!ctx_p) return; -- 2.34.1