From patchwork Mon Jan 30 16:02:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Tammela X-Patchwork-Id: 13121409 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D347C54EED for ; Mon, 30 Jan 2023 16:02:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235789AbjA3QCz (ORCPT ); Mon, 30 Jan 2023 11:02:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235709AbjA3QCx (ORCPT ); Mon, 30 Jan 2023 11:02:53 -0500 Received: from mail-oo1-xc2c.google.com (mail-oo1-xc2c.google.com [IPv6:2607:f8b0:4864:20::c2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 997C811B for ; Mon, 30 Jan 2023 08:02:50 -0800 (PST) Received: by mail-oo1-xc2c.google.com with SMTP id y26-20020a4ad65a000000b005173859761dso768853oos.1 for ; Mon, 30 Jan 2023 08:02:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mojatatu-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jt9llzQUT4Dk7WxFcfr43Y4pdSp3n2fA7C1eihsbEvY=; b=qd7RYBgWcA7hBNO6o15BYY518FEbf687cUdY6eln9vHObmeDKz1YCBjDqscVRsoUcI 8rdhTCOWmWdcyxDbF8znLqC9aBzo9JLluysBDQt01zgrGC1rkKOv0wdx8D2NFcaJ6StK WeKb5z4c27Q3136lBDWNRvGol1gSHjQtO/uKT8o27gfveghiNwgJR3Csg/O67B4xnt+l 6Ci13mJsBjgyQYRavlrfMY4+WATm/vNOd/c5Hy7V4+kunpr6UOW3mAqrjLcqMZ8LFhzm YtLk1Nj4ubhxeabYQzCf3zhS4wSySrdUswV8nahE5DqnTvk42W5cvH6QZ4Wl3eOxXZ9g jDAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jt9llzQUT4Dk7WxFcfr43Y4pdSp3n2fA7C1eihsbEvY=; b=VCu7K+sTnUvC3Qj5N05Kdu0Zah8Lk+nVDorlL2MXybCZKPOuvp1jgGuBnC9bDc8a8o Zkj4OYb3q6NwH/kkaUWXCUaICoXx572AqckJUHn3uULyzQfPO1JikiIspyN3wKGRly3D figlD0F8P5bQMF+BA0CooJba/NDbGg9y442bq+1lFsMXsOrjKe7Km5l/H7fWbzxy5cpv VnTdPtkVlmmnW+eSRjxgqgQJfHvBaKAUmI/arD8oQFlzChH/FYdK80FXxS/IOE+H/NB+ //tCHj5TS6CBmx9Fc5IvtBlTHzN1tPkTBrPmQ4Tkj+Lqd3Uhi5mQGu5z3fNt7k9BD/YZ th9w== X-Gm-Message-State: AO0yUKXZuWeGKvvNDgMs/fWWTXvZ1C2JT+AJDb3QTA2TQR44Gk/E3MmG D9nnSurPF/O2hIZm62XLBFQ2OE9cA60TN85h X-Google-Smtp-Source: AK7set802PhVz/+8pVH1Rxe8Dr6mzfbVOxbE6tqCK1+9aVwtad8TJvxP0BhTwbWcmPExEMCrvE245g== X-Received: by 2002:a4a:3791:0:b0:517:67ba:586 with SMTP id r139-20020a4a3791000000b0051767ba0586mr2593787oor.3.1675094569758; Mon, 30 Jan 2023 08:02:49 -0800 (PST) Received: from localhost.localdomain ([2804:14d:5c5e:4698:c9d9:8f8:eebd:a6b0]) by smtp.gmail.com with ESMTPSA id s16-20020a4ae550000000b004fd878ef510sm5119845oot.21.2023.01.30.08.02.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Jan 2023 08:02:49 -0800 (PST) From: Pedro Tammela To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, simon.horman@corigine.com, Pedro Tammela Subject: [PATCH net-next v4 1/2] net/sched: transition act_pedit to rcu and percpu stats Date: Mon, 30 Jan 2023 13:02:32 -0300 Message-Id: <20230130160233.3702650-2-pctammela@mojatatu.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230130160233.3702650-1-pctammela@mojatatu.com> References: <20230130160233.3702650-1-pctammela@mojatatu.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The software pedit action didn't get the same love as some of the other actions and it's still using spinlocks and shared stats in the datapath. Transition the action to rcu and percpu stats as this improves the action's performance on multiple cpu deployments. Reviewed-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela --- include/net/tc_act/tc_pedit.h | 81 +++++++++++++++---- net/sched/act_pedit.c | 144 +++++++++++++++++++++------------- 2 files changed, 154 insertions(+), 71 deletions(-) diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h index 3e02709a1df6..83fe39931781 100644 --- a/include/net/tc_act/tc_pedit.h +++ b/include/net/tc_act/tc_pedit.h @@ -4,22 +4,29 @@ #include #include +#include struct tcf_pedit_key_ex { enum pedit_header_type htype; enum pedit_cmd cmd; }; -struct tcf_pedit { - struct tc_action common; - unsigned char tcfp_nkeys; - unsigned char tcfp_flags; - u32 tcfp_off_max_hint; +struct tcf_pedit_parms { struct tc_pedit_key *tcfp_keys; struct tcf_pedit_key_ex *tcfp_keys_ex; + u32 tcfp_off_max_hint; + unsigned char tcfp_nkeys; + unsigned char tcfp_flags; + struct rcu_head rcu; +}; + +struct tcf_pedit { + struct tc_action common; + struct tcf_pedit_parms __rcu *parms; }; #define to_pedit(a) ((struct tcf_pedit *)a) +#define to_pedit_parms(a) (rcu_dereference(to_pedit(a)->parms)) static inline bool is_tcf_pedit(const struct tc_action *a) { @@ -32,37 +39,81 @@ static inline bool is_tcf_pedit(const struct tc_action *a) static inline int tcf_pedit_nkeys(const struct tc_action *a) { - return to_pedit(a)->tcfp_nkeys; + struct tcf_pedit_parms *parms; + int nkeys; + + rcu_read_lock(); + parms = to_pedit_parms(a); + nkeys = parms->tcfp_nkeys; + rcu_read_unlock(); + + return nkeys; } static inline u32 tcf_pedit_htype(const struct tc_action *a, int index) { - if (to_pedit(a)->tcfp_keys_ex) - return to_pedit(a)->tcfp_keys_ex[index].htype; + u32 htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; + struct tcf_pedit_parms *parms; + + rcu_read_lock(); + parms = to_pedit_parms(a); + if (parms->tcfp_keys_ex) + htype = parms->tcfp_keys_ex[index].htype; + rcu_read_unlock(); - return TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; + return htype; } static inline u32 tcf_pedit_cmd(const struct tc_action *a, int index) { - if (to_pedit(a)->tcfp_keys_ex) - return to_pedit(a)->tcfp_keys_ex[index].cmd; + struct tcf_pedit_parms *parms; + u32 cmd = __PEDIT_CMD_MAX; - return __PEDIT_CMD_MAX; + rcu_read_lock(); + parms = to_pedit_parms(a); + if (parms->tcfp_keys_ex) + cmd = parms->tcfp_keys_ex[index].cmd; + rcu_read_unlock(); + + return cmd; } static inline u32 tcf_pedit_mask(const struct tc_action *a, int index) { - return to_pedit(a)->tcfp_keys[index].mask; + struct tcf_pedit_parms *parms; + u32 mask; + + rcu_read_lock(); + parms = to_pedit_parms(a); + mask = parms->tcfp_keys[index].mask; + rcu_read_unlock(); + + return mask; } static inline u32 tcf_pedit_val(const struct tc_action *a, int index) { - return to_pedit(a)->tcfp_keys[index].val; + struct tcf_pedit_parms *parms; + u32 val; + + rcu_read_lock(); + parms = to_pedit_parms(a); + val = parms->tcfp_keys[index].val; + rcu_read_unlock(); + + return val; } static inline u32 tcf_pedit_offset(const struct tc_action *a, int index) { - return to_pedit(a)->tcfp_keys[index].off; + struct tcf_pedit_parms *parms; + u32 off; + + rcu_read_lock(); + parms = to_pedit_parms(a); + off = parms->tcfp_keys[index].off; + rcu_read_unlock(); + + return off; } #endif /* __NET_TC_PED_H */ diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index a0378e9f0121..c8e8748dc258 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -134,6 +134,17 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb, return -EINVAL; } +static void tcf_pedit_cleanup_rcu(struct rcu_head *head) +{ + struct tcf_pedit_parms *parms = + container_of(head, struct tcf_pedit_parms, rcu); + + kfree(parms->tcfp_keys_ex); + kfree(parms->tcfp_keys); + + kfree(parms); +} + static int tcf_pedit_init(struct net *net, struct nlattr *nla, struct nlattr *est, struct tc_action **a, struct tcf_proto *tp, u32 flags, @@ -143,8 +154,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, bool bind = flags & TCA_ACT_FLAGS_BIND; struct nlattr *tb[TCA_PEDIT_MAX + 1]; struct tcf_chain *goto_ch = NULL; - struct tc_pedit_key *keys = NULL; - struct tcf_pedit_key_ex *keys_ex; + struct tcf_pedit_parms *oparms, *nparms; struct tc_pedit *parm; struct nlattr *pattr; struct tcf_pedit *p; @@ -181,18 +191,25 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, return -EINVAL; } - keys_ex = tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys); - if (IS_ERR(keys_ex)) - return PTR_ERR(keys_ex); + nparms = kzalloc(sizeof(*nparms), GFP_KERNEL); + if (!nparms) + return -ENOMEM; + + nparms->tcfp_keys_ex = + tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys); + if (IS_ERR(nparms->tcfp_keys_ex)) { + ret = PTR_ERR(nparms->tcfp_keys_ex); + goto out_free; + } index = parm->index; err = tcf_idr_check_alloc(tn, &index, a, bind); if (!err) { - ret = tcf_idr_create(tn, index, est, a, - &act_pedit_ops, bind, false, flags); + ret = tcf_idr_create_from_flags(tn, index, est, a, + &act_pedit_ops, bind, flags); if (ret) { tcf_idr_cleanup(tn, index); - goto out_free; + goto out_free_ex; } ret = ACT_P_CREATED; } else if (err > 0) { @@ -204,7 +221,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, } } else { ret = err; - goto out_free; + goto out_free_ex; } err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); @@ -212,68 +229,79 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ret = err; goto out_release; } + + nparms->tcfp_off_max_hint = 0; + nparms->tcfp_flags = parm->flags; + p = to_pedit(*a); spin_lock_bh(&p->tcf_lock); + oparms = rcu_dereference_protected(p->parms, 1); + if (ret == ACT_P_CREATED || - (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) { - keys = kmalloc(ksize, GFP_ATOMIC); - if (!keys) { + (oparms->tcfp_nkeys && oparms->tcfp_nkeys != parm->nkeys)) { + nparms->tcfp_keys = kmalloc(ksize, GFP_ATOMIC); + if (!nparms->tcfp_keys) { spin_unlock_bh(&p->tcf_lock); ret = -ENOMEM; - goto put_chain; + goto out_release; } - kfree(p->tcfp_keys); - p->tcfp_keys = keys; - p->tcfp_nkeys = parm->nkeys; + nparms->tcfp_nkeys = parm->nkeys; + } else { + nparms->tcfp_keys = oparms->tcfp_keys; + nparms->tcfp_nkeys = oparms->tcfp_nkeys; } - memcpy(p->tcfp_keys, parm->keys, ksize); - p->tcfp_off_max_hint = 0; - for (i = 0; i < p->tcfp_nkeys; ++i) { - u32 cur = p->tcfp_keys[i].off; + + memcpy(nparms->tcfp_keys, parm->keys, ksize); + + for (i = 0; i < nparms->tcfp_nkeys; ++i) { + u32 cur = nparms->tcfp_keys[i].off; /* sanitize the shift value for any later use */ - p->tcfp_keys[i].shift = min_t(size_t, BITS_PER_TYPE(int) - 1, - p->tcfp_keys[i].shift); + nparms->tcfp_keys[i].shift = min_t(size_t, + BITS_PER_TYPE(int) - 1, + nparms->tcfp_keys[i].shift); /* The AT option can read a single byte, we can bound the actual * value with uchar max. */ - cur += (0xff & p->tcfp_keys[i].offmask) >> p->tcfp_keys[i].shift; + cur += (0xff & nparms->tcfp_keys[i].offmask) >> nparms->tcfp_keys[i].shift; /* Each key touches 4 bytes starting from the computed offset */ - p->tcfp_off_max_hint = max(p->tcfp_off_max_hint, cur + 4); + nparms->tcfp_off_max_hint = + max(nparms->tcfp_off_max_hint, cur + 4); } - p->tcfp_flags = parm->flags; goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); - kfree(p->tcfp_keys_ex); - p->tcfp_keys_ex = keys_ex; + rcu_assign_pointer(p->parms, nparms); spin_unlock_bh(&p->tcf_lock); + + if (oparms) + call_rcu(&oparms->rcu, tcf_pedit_cleanup_rcu); + if (goto_ch) tcf_chain_put_by_act(goto_ch); + return ret; -put_chain: - if (goto_ch) - tcf_chain_put_by_act(goto_ch); out_release: tcf_idr_release(*a, bind); +out_free_ex: + kfree(nparms->tcfp_keys_ex); out_free: - kfree(keys_ex); + kfree(nparms); return ret; - } static void tcf_pedit_cleanup(struct tc_action *a) { struct tcf_pedit *p = to_pedit(a); - struct tc_pedit_key *keys = p->tcfp_keys; + struct tcf_pedit_parms *parms; - kfree(keys); - kfree(p->tcfp_keys_ex); + parms = rcu_dereference_protected(p->parms, 1); + call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu); } static bool offset_valid(struct sk_buff *skb, int offset) @@ -325,28 +353,30 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, struct tcf_result *res) { struct tcf_pedit *p = to_pedit(a); + struct tcf_pedit_parms *parms; u32 max_offset; int i; - spin_lock(&p->tcf_lock); + parms = rcu_dereference_bh(p->parms); max_offset = (skb_transport_header_was_set(skb) ? skb_transport_offset(skb) : skb_network_offset(skb)) + - p->tcfp_off_max_hint; + parms->tcfp_off_max_hint; if (skb_ensure_writable(skb, min(skb->len, max_offset))) - goto unlock; + goto done; tcf_lastuse_update(&p->tcf_tm); + tcf_action_update_bstats(&p->common, skb); - if (p->tcfp_nkeys > 0) { - struct tc_pedit_key *tkey = p->tcfp_keys; - struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex; + if (parms->tcfp_nkeys > 0) { + struct tc_pedit_key *tkey = parms->tcfp_keys; + struct tcf_pedit_key_ex *tkey_ex = parms->tcfp_keys_ex; enum pedit_header_type htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; - for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { + for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) { u32 *ptr, hdata; int offset = tkey->off; int hoffset; @@ -422,11 +452,10 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, } bad: + spin_lock(&p->tcf_lock); p->tcf_qstats.overlimits++; -done: - bstats_update(&p->tcf_bstats, skb); -unlock: spin_unlock(&p->tcf_lock); +done: return p->tcf_action; } @@ -445,30 +474,33 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a, { unsigned char *b = skb_tail_pointer(skb); struct tcf_pedit *p = to_pedit(a); + struct tcf_pedit_parms *parms; struct tc_pedit *opt; struct tcf_t t; int s; - s = struct_size(opt, keys, p->tcfp_nkeys); + spin_lock_bh(&p->tcf_lock); + parms = rcu_dereference_protected(p->parms, 1); + s = struct_size(opt, keys, parms->tcfp_nkeys); - /* netlink spinlocks held above us - must use ATOMIC */ opt = kzalloc(s, GFP_ATOMIC); - if (unlikely(!opt)) + if (unlikely(!opt)) { + spin_unlock_bh(&p->tcf_lock); return -ENOBUFS; + } - spin_lock_bh(&p->tcf_lock); - memcpy(opt->keys, p->tcfp_keys, flex_array_size(opt, keys, p->tcfp_nkeys)); + memcpy(opt->keys, parms->tcfp_keys, + flex_array_size(opt, keys, parms->tcfp_nkeys)); opt->index = p->tcf_index; - opt->nkeys = p->tcfp_nkeys; - opt->flags = p->tcfp_flags; + opt->nkeys = parms->tcfp_nkeys; + opt->flags = parms->tcfp_flags; opt->action = p->tcf_action; opt->refcnt = refcount_read(&p->tcf_refcnt) - ref; opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind; - if (p->tcfp_keys_ex) { - if (tcf_pedit_key_ex_dump(skb, - p->tcfp_keys_ex, - p->tcfp_nkeys)) + if (parms->tcfp_keys_ex) { + if (tcf_pedit_key_ex_dump(skb, parms->tcfp_keys_ex, + parms->tcfp_nkeys)) goto nla_put_failure; if (nla_put(skb, TCA_PEDIT_PARMS_EX, s, opt)) From patchwork Mon Jan 30 16:02:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Tammela X-Patchwork-Id: 13121410 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24918C54EED for ; Mon, 30 Jan 2023 16:03:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235747AbjA3QDB (ORCPT ); Mon, 30 Jan 2023 11:03:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235709AbjA3QC6 (ORCPT ); Mon, 30 Jan 2023 11:02:58 -0500 Received: from mail-oo1-xc33.google.com (mail-oo1-xc33.google.com [IPv6:2607:f8b0:4864:20::c33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E53A7A94 for ; Mon, 30 Jan 2023 08:02:55 -0800 (PST) Received: by mail-oo1-xc33.google.com with SMTP id 19-20020a4ae1b3000000b005173e0749cbso700263ooy.7 for ; Mon, 30 Jan 2023 08:02:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mojatatu-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nUxkdcDxyb8uvhf260ZYmPZtg3Cz9pELOlYoywsS4mM=; b=4KiD7NhhIA6FsKRYjmszfOu3qk20r+FSBZZngQtZX7gUdRXloWwSUenKvesnbyGO/L V05k99i30VbvVsQ2oXn7U8ByC++lMHevAqCLSlr0oLpdu7O2PkyzGZVtk3l5VlSonvQ6 W9gcC8tTYAwVXNYUlxxcTU2cGdklWODR81FMVnCp0qri3mlayRNc85eLj8fj34Aea/TF +L022KPt9Ty1ZkPvMvtYvT1pliq8cJ+E9Ojnf2CBouO40cpXBvhRHjDJLD9b8ZjtobXU 7kI7yT3aM43t04XrhvpbsoPB/4EyfArHeJ+lnPElktGou4ixaC0fJnq1IonV8PHo64IW 6p7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nUxkdcDxyb8uvhf260ZYmPZtg3Cz9pELOlYoywsS4mM=; b=hx94uzpvVooY+kI3ZPPkxmgeASInti5E5jlfvRUJXv3rADKGJaGAeRtne1+PB+R67W 1YEpOO7q1K0RlbmOay2ywDGdXVyZQoXbGE4/EBYtNe1kFVWexSrjFB2L5wb7UwDFWblC 8mEn7jLFHK49hOP2a54BHubtNlCFLn+KoZFMBn8jIA7tD9v/73TBNoiYtPiLgkZ63yhV NkNkwophff6DtFICTvm7cPLNdbsT6m9dFvbQsRHyIW5B32qvvPfCE9Jkyx9yP3Y/+6Xj o56fe4E/JMIMFpIECbEV/Z3cSL6tGf53JK42jnOy7lOgHyYkVfV5fvAcrspmqAnXWd+P sLIA== X-Gm-Message-State: AO0yUKW1DVmPQOabZlim3p6/ivme6NqF/0esaL0cTBEBYZQC+19TMa6H W5rNhTMFTWJ/ZBsnBEJB8m1rsoRA2iR9YOCr X-Google-Smtp-Source: AK7set9MYD1xrP72rp4qjUsVSJi3153nq4nvZx0t2f+4VR1tNsGxbsIxUX8CHrmoJ0rfCvQmaigOWg== X-Received: by 2002:a4a:88d3:0:b0:511:f3d2:bb8d with SMTP id q19-20020a4a88d3000000b00511f3d2bb8dmr9769823ooh.5.1675094574986; Mon, 30 Jan 2023 08:02:54 -0800 (PST) Received: from localhost.localdomain ([2804:14d:5c5e:4698:c9d9:8f8:eebd:a6b0]) by smtp.gmail.com with ESMTPSA id s16-20020a4ae550000000b004fd878ef510sm5119845oot.21.2023.01.30.08.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Jan 2023 08:02:54 -0800 (PST) From: Pedro Tammela To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, simon.horman@corigine.com, Pedro Tammela Subject: [PATCH net-next v4 2/2] net/sched: simplify tcf_pedit_act Date: Mon, 30 Jan 2023 13:02:33 -0300 Message-Id: <20230130160233.3702650-3-pctammela@mojatatu.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230130160233.3702650-1-pctammela@mojatatu.com> References: <20230130160233.3702650-1-pctammela@mojatatu.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Remove the check for a negative number of keys as this cannot ever happen Reviewed-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Reviewed-by: Simon Horman --- net/sched/act_pedit.c | 137 +++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index c8e8748dc258..d0098b9ebb1b 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -352,8 +352,12 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { + enum pedit_header_type htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; + enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; struct tcf_pedit *p = to_pedit(a); + struct tcf_pedit_key_ex *tkey_ex; struct tcf_pedit_parms *parms; + struct tc_pedit_key *tkey; u32 max_offset; int i; @@ -369,88 +373,81 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, tcf_lastuse_update(&p->tcf_tm); tcf_action_update_bstats(&p->common, skb); - if (parms->tcfp_nkeys > 0) { - struct tc_pedit_key *tkey = parms->tcfp_keys; - struct tcf_pedit_key_ex *tkey_ex = parms->tcfp_keys_ex; - enum pedit_header_type htype = - TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; - enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; - - for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) { - u32 *ptr, hdata; - int offset = tkey->off; - int hoffset; - u32 val; - int rc; - - if (tkey_ex) { - htype = tkey_ex->htype; - cmd = tkey_ex->cmd; - - tkey_ex++; - } + tkey = parms->tcfp_keys; + tkey_ex = parms->tcfp_keys_ex; - rc = pedit_skb_hdr_offset(skb, htype, &hoffset); - if (rc) { - pr_info("tc action pedit bad header type specified (0x%x)\n", - htype); - goto bad; - } + for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) { + int offset = tkey->off; + u32 *ptr, hdata; + int hoffset; + u32 val; + int rc; - if (tkey->offmask) { - u8 *d, _d; - - if (!offset_valid(skb, hoffset + tkey->at)) { - pr_info("tc action pedit 'at' offset %d out of bounds\n", - hoffset + tkey->at); - goto bad; - } - d = skb_header_pointer(skb, hoffset + tkey->at, - sizeof(_d), &_d); - if (!d) - goto bad; - offset += (*d & tkey->offmask) >> tkey->shift; - } + if (tkey_ex) { + htype = tkey_ex->htype; + cmd = tkey_ex->cmd; - if (offset % 4) { - pr_info("tc action pedit offset must be on 32 bit boundaries\n"); - goto bad; - } + tkey_ex++; + } - if (!offset_valid(skb, hoffset + offset)) { - pr_info("tc action pedit offset %d out of bounds\n", - hoffset + offset); - goto bad; - } + rc = pedit_skb_hdr_offset(skb, htype, &hoffset); + if (rc) { + pr_info("tc action pedit bad header type specified (0x%x)\n", + htype); + goto bad; + } - ptr = skb_header_pointer(skb, hoffset + offset, - sizeof(hdata), &hdata); - if (!ptr) - goto bad; - /* just do it, baby */ - switch (cmd) { - case TCA_PEDIT_KEY_EX_CMD_SET: - val = tkey->val; - break; - case TCA_PEDIT_KEY_EX_CMD_ADD: - val = (*ptr + tkey->val) & ~tkey->mask; - break; - default: - pr_info("tc action pedit bad command (%d)\n", - cmd); + if (tkey->offmask) { + u8 *d, _d; + + if (!offset_valid(skb, hoffset + tkey->at)) { + pr_info("tc action pedit 'at' offset %d out of bounds\n", + hoffset + tkey->at); goto bad; } + d = skb_header_pointer(skb, hoffset + tkey->at, + sizeof(_d), &_d); + if (!d) + goto bad; + offset += (*d & tkey->offmask) >> tkey->shift; + } - *ptr = ((*ptr & tkey->mask) ^ val); - if (ptr == &hdata) - skb_store_bits(skb, hoffset + offset, ptr, 4); + if (offset % 4) { + pr_info("tc action pedit offset must be on 32 bit boundaries\n"); + goto bad; } - goto done; - } else { - WARN(1, "pedit BUG: index %d\n", p->tcf_index); + if (!offset_valid(skb, hoffset + offset)) { + pr_info("tc action pedit offset %d out of bounds\n", + hoffset + offset); + goto bad; + } + + ptr = skb_header_pointer(skb, hoffset + offset, + sizeof(hdata), &hdata); + if (!ptr) + goto bad; + /* just do it, baby */ + switch (cmd) { + case TCA_PEDIT_KEY_EX_CMD_SET: + val = tkey->val; + break; + case TCA_PEDIT_KEY_EX_CMD_ADD: + val = (*ptr + tkey->val) & ~tkey->mask; + break; + default: + pr_info("tc action pedit bad command (%d)\n", + cmd); + goto bad; + } + + *ptr = ((*ptr & tkey->mask) ^ val); + if (ptr == &hdata) + skb_store_bits(skb, hoffset + offset, ptr, 4); } + goto done; + bad: spin_lock(&p->tcf_lock); p->tcf_qstats.overlimits++;