* [PATCH net-next v3 2/2] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update
@ 2017-10-29 8:47 Manish Kurup
2017-10-31 13:06 ` Pieter Jansen van Vuuren
0 siblings, 1 reply; 3+ messages in thread
From: Manish Kurup @ 2017-10-29 8:47 UTC (permalink / raw)
To: jhs, xiyou.wangcong, jiri, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, oss-drivers, davem, netdev
Cc: aring, mrv, kurup.manish, Manish Kurup
Using a spinlock in the VLAN action causes performance issues when the VLAN
action is used on multiple cores. Rewrote the VLAN action to use RCU read
locking for reads and updates instead.
Fixed nxp flower action to use VLAN helper functions instead of accessing the
structure directly (build break error).
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Manish Kurup <manish.kurup@verizon.com>
---
drivers/net/ethernet/netronome/nfp/flower/action.c | 5 +-
include/net/tc_act/tc_vlan.h | 46 ++++++++++++---
net/sched/act_vlan.c | 65 ++++++++++++++--------
3 files changed, 80 insertions(+), 36 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index 0a5fc9f..cbaa8ea 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -58,7 +58,6 @@ nfp_fl_push_vlan(struct nfp_fl_push_vlan *push_vlan,
const struct tc_action *action)
{
size_t act_size = sizeof(struct nfp_fl_push_vlan);
- struct tcf_vlan *vlan = to_vlan(action);
u16 tmp_push_vlan_tci;
push_vlan->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_VLAN;
@@ -67,8 +66,8 @@ nfp_fl_push_vlan(struct nfp_fl_push_vlan *push_vlan,
push_vlan->vlan_tpid = tcf_vlan_push_proto(action);
tmp_push_vlan_tci =
- FIELD_PREP(NFP_FL_PUSH_VLAN_PRIO, vlan->tcfv_push_prio) |
- FIELD_PREP(NFP_FL_PUSH_VLAN_VID, vlan->tcfv_push_vid) |
+ FIELD_PREP(NFP_FL_PUSH_VLAN_PRIO, tcf_vlan_push_prio(action)) |
+ FIELD_PREP(NFP_FL_PUSH_VLAN_VID, tcf_vlan_push_vid(action)) |
NFP_FL_PUSH_VLAN_CFI;
push_vlan->vlan_tci = cpu_to_be16(tmp_push_vlan_tci);
}
diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
index c2090df..22ae260 100644
--- a/include/net/tc_act/tc_vlan.h
+++ b/include/net/tc_act/tc_vlan.h
@@ -13,12 +13,17 @@
#include <net/act_api.h>
#include <linux/tc_act/tc_vlan.h>
+struct tcf_vlan_params {
+ int tcfv_action;
+ u16 tcfv_push_vid;
+ __be16 tcfv_push_proto;
+ u8 tcfv_push_prio;
+ struct rcu_head rcu;
+};
+
struct tcf_vlan {
struct tc_action common;
- int tcfv_action;
- u16 tcfv_push_vid;
- __be16 tcfv_push_proto;
- u8 tcfv_push_prio;
+ struct tcf_vlan_params __rcu *vlan_p;
};
#define to_vlan(a) ((struct tcf_vlan *)a)
@@ -33,22 +38,45 @@ static inline bool is_tcf_vlan(const struct tc_action *a)
static inline u32 tcf_vlan_action(const struct tc_action *a)
{
- return to_vlan(a)->tcfv_action;
+ u32 tcfv_action;
+
+ rcu_read_lock();
+ tcfv_action = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_action;
+ rcu_read_unlock();
+
+ return tcfv_action;
}
static inline u16 tcf_vlan_push_vid(const struct tc_action *a)
{
- return to_vlan(a)->tcfv_push_vid;
+ u16 tcfv_push_vid;
+
+ rcu_read_lock();
+ tcfv_push_vid = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_vid;
+ rcu_read_unlock();
+
+ return tcfv_push_vid;
}
static inline __be16 tcf_vlan_push_proto(const struct tc_action *a)
{
- return to_vlan(a)->tcfv_push_proto;
+ __be16 tcfv_push_proto;
+
+ rcu_read_lock();
+ tcfv_push_proto = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_proto;
+ rcu_read_unlock();
+
+ return tcfv_push_proto;
}
static inline u8 tcf_vlan_push_prio(const struct tc_action *a)
{
- return to_vlan(a)->tcfv_push_prio;
-}
+ u8 tcfv_push_prio;
+ rcu_read_lock();
+ tcfv_push_prio = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_prio;
+ rcu_read_unlock();
+
+ return tcfv_push_prio;
+}
#endif /* __NET_TC_VLAN_H */
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index b093bad..7f461f9 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -26,6 +26,7 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{
struct tcf_vlan *v = to_vlan(a);
+ struct tcf_vlan_params *p;
int action;
int err;
u16 tci;
@@ -33,24 +34,27 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
tcf_lastuse_update(&v->tcf_tm);
bstats_cpu_update(this_cpu_ptr(v->common.cpu_bstats), skb);
- spin_lock(&v->tcf_lock);
- action = v->tcf_action;
-
/* Ensure 'data' points at mac_header prior calling vlan manipulating
* functions.
*/
if (skb_at_tc_ingress(skb))
skb_push_rcsum(skb, skb->mac_len);
- switch (v->tcfv_action) {
+ rcu_read_lock();
+
+ action = READ_ONCE(v->tcf_action);
+
+ p = rcu_dereference(v->vlan_p);
+
+ switch (p->tcfv_action) {
case TCA_VLAN_ACT_POP:
err = skb_vlan_pop(skb);
if (err)
goto drop;
break;
case TCA_VLAN_ACT_PUSH:
- err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid |
- (v->tcfv_push_prio << VLAN_PRIO_SHIFT));
+ err = skb_vlan_push(skb, p->tcfv_push_proto, p->tcfv_push_vid |
+ (p->tcfv_push_prio << VLAN_PRIO_SHIFT));
if (err)
goto drop;
break;
@@ -69,14 +73,14 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
goto drop;
}
/* replace the vid */
- tci = (tci & ~VLAN_VID_MASK) | v->tcfv_push_vid;
+ tci = (tci & ~VLAN_VID_MASK) | p->tcfv_push_vid;
/* replace prio bits, if tcfv_push_prio specified */
- if (v->tcfv_push_prio) {
+ if (p->tcfv_push_prio) {
tci &= ~VLAN_PRIO_MASK;
- tci |= v->tcfv_push_prio << VLAN_PRIO_SHIFT;
+ tci |= p->tcfv_push_prio << VLAN_PRIO_SHIFT;
}
/* put updated tci as hwaccel tag */
- __vlan_hwaccel_put_tag(skb, v->tcfv_push_proto, tci);
+ __vlan_hwaccel_put_tag(skb, p->tcfv_push_proto, tci);
break;
default:
BUG();
@@ -89,10 +93,10 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
qstats_drop_inc(this_cpu_ptr(v->common.cpu_qstats));
unlock:
+ rcu_read_unlock();
if (skb_at_tc_ingress(skb))
skb_pull_rcsum(skb, skb->mac_len);
- spin_unlock(&v->tcf_lock);
return action;
}
@@ -109,6 +113,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
{
struct tc_action_net *tn = net_generic(net, vlan_net_id);
struct nlattr *tb[TCA_VLAN_MAX + 1];
+ struct tcf_vlan_params *p, *p_old;
struct tc_vlan *parm;
struct tcf_vlan *v;
int action;
@@ -187,16 +192,27 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
v = to_vlan(*a);
- spin_lock_bh(&v->tcf_lock);
-
- v->tcfv_action = action;
- v->tcfv_push_vid = push_vid;
- v->tcfv_push_prio = push_prio;
- v->tcfv_push_proto = push_proto;
+ ASSERT_RTNL();
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (unlikely(!p)) {
+ if (ovr)
+ tcf_idr_release(*a, bind);
+ return -ENOMEM;
+ }
v->tcf_action = parm->action;
- spin_unlock_bh(&v->tcf_lock);
+ p_old = rtnl_dereference(v->vlan_p);
+
+ p->tcfv_action = action;
+ p->tcfv_push_vid = push_vid;
+ p->tcfv_push_prio = push_prio;
+ p->tcfv_push_proto = push_proto;
+
+ rcu_assign_pointer(v->vlan_p, p);
+
+ if (p_old)
+ kfree_rcu(p_old, rcu);
if (ret == ACT_P_CREATED)
tcf_idr_insert(tn, *a);
@@ -208,25 +224,26 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_vlan *v = to_vlan(a);
+ struct tcf_vlan_params *p = rtnl_dereference(v->vlan_p);
struct tc_vlan opt = {
.index = v->tcf_index,
.refcnt = v->tcf_refcnt - ref,
.bindcnt = v->tcf_bindcnt - bind,
.action = v->tcf_action,
- .v_action = v->tcfv_action,
+ .v_action = p->tcfv_action,
};
struct tcf_t t;
if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt))
goto nla_put_failure;
- if ((v->tcfv_action == TCA_VLAN_ACT_PUSH ||
- v->tcfv_action == TCA_VLAN_ACT_MODIFY) &&
- (nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) ||
+ if ((p->tcfv_action == TCA_VLAN_ACT_PUSH ||
+ p->tcfv_action == TCA_VLAN_ACT_MODIFY) &&
+ (nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, p->tcfv_push_vid) ||
nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL,
- v->tcfv_push_proto) ||
+ p->tcfv_push_proto) ||
(nla_put_u8(skb, TCA_VLAN_PUSH_VLAN_PRIORITY,
- v->tcfv_push_prio))))
+ p->tcfv_push_prio))))
goto nla_put_failure;
tcf_tm_dump(&t, &v->tcf_tm);
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v3 2/2] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update
2017-10-29 8:47 [PATCH net-next v3 2/2] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update Manish Kurup
@ 2017-10-31 13:06 ` Pieter Jansen van Vuuren
[not found] ` <CAJrKpLaANmT07o6S5zMe3LrOJgperyQeuEUgVdWkS3gZv5TwVw@mail.gmail.com>
0 siblings, 1 reply; 3+ messages in thread
From: Pieter Jansen van Vuuren @ 2017-10-31 13:06 UTC (permalink / raw)
To: Manish Kurup
Cc: jhs, xiyou.wangcong, jiri, jakub.kicinski, simon.horman,
john.hurley, oss-drivers, davem, netdev, aring, mrv, Manish Kurup
On Sun, 29 Oct 2017 04:47:54 -0400
Manish Kurup <kurup.manish@gmail.com> wrote:
> Using a spinlock in the VLAN action causes performance issues when the VLAN
> action is used on multiple cores. Rewrote the VLAN action to use RCU read
> locking for reads and updates instead.
> Fixed nxp flower action to use VLAN helper functions instead of accessing the
> structure directly (build break error).
Thank you Manish. One minor nit, I think you meant nfp flower action...
Also is it possible to split this patch into 2 patches, it seems to do 2 things:
1. Update the VLAN action to use RCU.
2. Fix the nfp flower action to use the VLAN helper.
Can you please dump the build break error you are seeing here?
...
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v3 2/2] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update
[not found] ` <CAJrKpLaANmT07o6S5zMe3LrOJgperyQeuEUgVdWkS3gZv5TwVw@mail.gmail.com>
@ 2017-10-31 15:09 ` Pieter Jansen van Vuuren
0 siblings, 0 replies; 3+ messages in thread
From: Pieter Jansen van Vuuren @ 2017-10-31 15:09 UTC (permalink / raw)
To: Manish Kurup
Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, jakub.kicinski,
simon.horman, john.hurley, David Miller, netdev, Alexander Aring,
Roman Mashak, Manish Kurup, oss-drivers
On Tue, 31 Oct 2017 10:16:05 -0400
Manish Kurup <kurup.manish@gmail.com> wrote:
> Hi Pieter,
>
> On Tue, Oct 31, 2017 at 9:06 AM, Pieter Jansen van Vuuren <
> pieter.jansenvanvuuren@netronome.com> wrote:
>
> > On Sun, 29 Oct 2017 04:47:54 -0400
> > Manish Kurup <kurup.manish@gmail.com> wrote:
> >
> > > Using a spinlock in the VLAN action causes performance issues when the
> > VLAN
> > > action is used on multiple cores. Rewrote the VLAN action to use RCU read
> > > locking for reads and updates instead.
> > > Fixed nxp flower action to use VLAN helper functions instead of
> > accessing the
> > > structure directly (build break error).
> > Thank you Manish. One minor nit, I think you meant nfp flower action...
> > Also is it possible to split this patch into 2 patches, it seems to do 2
> > things:
> > 1. Update the VLAN action to use RCU.
> > 2. Fix the nfp flower action to use the VLAN helper.
> >
> > Can you please dump the build break error you are seeing here?
> > ...
> >
>
> Here's what the kbuild robot sent me (follows this mail).
>
> I cannot split this into 2 patches, since this has to be part of a patch
> I'd sent out for review earlier (the one that fixe the act_vlan action).
> Please let me know if you agree with my changes, and I will go ahead and
> commit this.
>
> Thanks,
>
> -Manish
Thanks Manish. I don't see obvious issues with this patch. The changes to nfp
flower action could exist standalone without your other patches, no? If that is
the case I would prefer having them split into 2 patches but keep them part of
your patch set. But I guess this is not crucial. Also the build break error
mentioned only occurs after your patches are applied. I would reword the commit
message to "update nfp flower action to use VLAN helper accessing the structure
directly.". The original commit message made me think there might be an bug in
net.
...
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-10-31 15:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-29 8:47 [PATCH net-next v3 2/2] net sched act_vlan: VLAN action rewrite to use RCU lock/unlock and update Manish Kurup
2017-10-31 13:06 ` Pieter Jansen van Vuuren
[not found] ` <CAJrKpLaANmT07o6S5zMe3LrOJgperyQeuEUgVdWkS3gZv5TwVw@mail.gmail.com>
2017-10-31 15:09 ` Pieter Jansen van Vuuren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).