Skip to content

Commit bd070e2

Browse files
committed
Merge branch 'tc-sw-only'
John Fastabend says: ==================== tc software only This adds a software only flag to tc but incorporates a bunch of comments from the original attempt at this. First instead of having the offload decision logic be embedded in cls_u32 I lifted into cls_pkt.h so it can be used anywhere and named the flag TCA_CLS_FLAGS_SKIP_HW (Thanks Jiri ;) In order to do this I put the flag defines in pkt_cls.h as well. However it was suggested that perhaps these flags could be lifted into the upper layer of TCA_ as well but I'm afraid this can not be done with existing tc design as far as I can tell. The problem is the filters are packed and unpacked in the classifier specific code and pushing the flags through the high level doesn't seem easily doable. And we already have this design where classifiers handle generic options such as actions and policers. So I think adding one more thing here is OK as 'tc', et. al. already know how to handle this type of thing. ==================== Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents d2e42a1 + 9e8ce79 commit bd070e2

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8400,9 +8400,6 @@ int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
84008400

84018401
if (TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS) &&
84028402
tc->type == TC_SETUP_CLSU32) {
8403-
if (!(dev->features & NETIF_F_HW_TC))
8404-
return -EINVAL;
8405-
84068403
switch (tc->cls_u32->command) {
84078404
case TC_CLSU32_NEW_KNODE:
84088405
case TC_CLSU32_REPLACE_KNODE:

include/net/pkt_cls.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,21 @@ struct tc_cls_u32_offload {
392392
};
393393
};
394394

395+
/* tca flags definitions */
396+
#define TCA_CLS_FLAGS_SKIP_HW 1
397+
398+
static inline bool tc_should_offload(struct net_device *dev, u32 flags)
399+
{
400+
if (!(dev->features & NETIF_F_HW_TC))
401+
return false;
402+
403+
if (flags & TCA_CLS_FLAGS_SKIP_HW)
404+
return false;
405+
406+
if (!dev->netdev_ops->ndo_setup_tc)
407+
return false;
408+
409+
return true;
410+
}
411+
395412
#endif

include/uapi/linux/pkt_cls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ enum {
172172
TCA_U32_INDEV,
173173
TCA_U32_PCNT,
174174
TCA_U32_MARK,
175+
TCA_U32_FLAGS,
175176
__TCA_U32_MAX
176177
};
177178

net/sched/cls_u32.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct tc_u_knode {
5959
#ifdef CONFIG_CLS_U32_PERF
6060
struct tc_u32_pcnt __percpu *pf;
6161
#endif
62+
u32 flags;
6263
#ifdef CONFIG_CLS_U32_MARK
6364
u32 val;
6465
u32 mask;
@@ -434,15 +435,17 @@ static void u32_remove_hw_knode(struct tcf_proto *tp, u32 handle)
434435
offload.type = TC_SETUP_CLSU32;
435436
offload.cls_u32 = &u32_offload;
436437

437-
if (dev->netdev_ops->ndo_setup_tc) {
438+
if (tc_should_offload(dev, 0)) {
438439
offload.cls_u32->command = TC_CLSU32_DELETE_KNODE;
439440
offload.cls_u32->knode.handle = handle;
440441
dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
441442
tp->protocol, &offload);
442443
}
443444
}
444445

445-
static void u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
446+
static void u32_replace_hw_hnode(struct tcf_proto *tp,
447+
struct tc_u_hnode *h,
448+
u32 flags)
446449
{
447450
struct net_device *dev = tp->q->dev_queue->dev;
448451
struct tc_cls_u32_offload u32_offload = {0};
@@ -451,7 +454,7 @@ static void u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
451454
offload.type = TC_SETUP_CLSU32;
452455
offload.cls_u32 = &u32_offload;
453456

454-
if (dev->netdev_ops->ndo_setup_tc) {
457+
if (tc_should_offload(dev, flags)) {
455458
offload.cls_u32->command = TC_CLSU32_NEW_HNODE;
456459
offload.cls_u32->hnode.divisor = h->divisor;
457460
offload.cls_u32->hnode.handle = h->handle;
@@ -471,7 +474,7 @@ static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
471474
offload.type = TC_SETUP_CLSU32;
472475
offload.cls_u32 = &u32_offload;
473476

474-
if (dev->netdev_ops->ndo_setup_tc) {
477+
if (tc_should_offload(dev, 0)) {
475478
offload.cls_u32->command = TC_CLSU32_DELETE_HNODE;
476479
offload.cls_u32->hnode.divisor = h->divisor;
477480
offload.cls_u32->hnode.handle = h->handle;
@@ -482,7 +485,9 @@ static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h)
482485
}
483486
}
484487

485-
static void u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n)
488+
static void u32_replace_hw_knode(struct tcf_proto *tp,
489+
struct tc_u_knode *n,
490+
u32 flags)
486491
{
487492
struct net_device *dev = tp->q->dev_queue->dev;
488493
struct tc_cls_u32_offload u32_offload = {0};
@@ -491,7 +496,7 @@ static void u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n)
491496
offload.type = TC_SETUP_CLSU32;
492497
offload.cls_u32 = &u32_offload;
493498

494-
if (dev->netdev_ops->ndo_setup_tc) {
499+
if (tc_should_offload(dev, flags)) {
495500
offload.cls_u32->command = TC_CLSU32_REPLACE_KNODE;
496501
offload.cls_u32->knode.handle = n->handle;
497502
offload.cls_u32->knode.fshift = n->fshift;
@@ -679,6 +684,7 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
679684
[TCA_U32_SEL] = { .len = sizeof(struct tc_u32_sel) },
680685
[TCA_U32_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ },
681686
[TCA_U32_MARK] = { .len = sizeof(struct tc_u32_mark) },
687+
[TCA_U32_FLAGS] = { .type = NLA_U32 },
682688
};
683689

684690
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
@@ -786,6 +792,7 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp,
786792
#endif
787793
new->fshift = n->fshift;
788794
new->res = n->res;
795+
new->flags = n->flags;
789796
RCU_INIT_POINTER(new->ht_down, n->ht_down);
790797

791798
/* bump reference count as long as we hold pointer to structure */
@@ -825,7 +832,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
825832
struct tc_u32_sel *s;
826833
struct nlattr *opt = tca[TCA_OPTIONS];
827834
struct nlattr *tb[TCA_U32_MAX + 1];
828-
u32 htid;
835+
u32 htid, flags = 0;
829836
int err;
830837
#ifdef CONFIG_CLS_U32_PERF
831838
size_t size;
@@ -838,13 +845,19 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
838845
if (err < 0)
839846
return err;
840847

848+
if (tb[TCA_U32_FLAGS])
849+
flags = nla_get_u32(tb[TCA_U32_FLAGS]);
850+
841851
n = (struct tc_u_knode *)*arg;
842852
if (n) {
843853
struct tc_u_knode *new;
844854

845855
if (TC_U32_KEY(n->handle) == 0)
846856
return -EINVAL;
847857

858+
if (n->flags != flags)
859+
return -EINVAL;
860+
848861
new = u32_init_knode(tp, n);
849862
if (!new)
850863
return -ENOMEM;
@@ -861,7 +874,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
861874
u32_replace_knode(tp, tp_c, new);
862875
tcf_unbind_filter(tp, &n->res);
863876
call_rcu(&n->rcu, u32_delete_key_rcu);
864-
u32_replace_hw_knode(tp, new);
877+
u32_replace_hw_knode(tp, new, flags);
865878
return 0;
866879
}
867880

@@ -889,7 +902,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
889902
rcu_assign_pointer(tp_c->hlist, ht);
890903
*arg = (unsigned long)ht;
891904

892-
u32_replace_hw_hnode(tp, ht);
905+
u32_replace_hw_hnode(tp, ht, flags);
893906
return 0;
894907
}
895908

@@ -940,6 +953,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
940953
RCU_INIT_POINTER(n->ht_up, ht);
941954
n->handle = handle;
942955
n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
956+
n->flags = flags;
943957
tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);
944958
n->tp = tp;
945959

@@ -972,7 +986,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
972986

973987
RCU_INIT_POINTER(n->next, pins);
974988
rcu_assign_pointer(*ins, n);
975-
u32_replace_hw_knode(tp, n);
989+
u32_replace_hw_knode(tp, n, flags);
976990
*arg = (unsigned long)n;
977991
return 0;
978992
}
@@ -1077,6 +1091,9 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
10771091
nla_put_u32(skb, TCA_U32_LINK, ht_down->handle))
10781092
goto nla_put_failure;
10791093

1094+
if (n->flags && nla_put_u32(skb, TCA_U32_FLAGS, n->flags))
1095+
goto nla_put_failure;
1096+
10801097
#ifdef CONFIG_CLS_U32_MARK
10811098
if ((n->val || n->mask)) {
10821099
struct tc_u32_mark mark = {.val = n->val,

0 commit comments

Comments
 (0)