net: sched: cls_bpf: call block callbacks for offload

Use the newly introduced callbacks infrastructure and call block
callbacks alongside with the existing per-netdev ndo_setup_tc.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jiri Pirko 2017-10-19 15:50:36 +02:00 committed by David S. Miller
parent 245dc5121a
commit 3f7889c4c7

View file

@ -147,7 +147,10 @@ static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog)
static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
enum tc_clsbpf_command cmd) enum tc_clsbpf_command cmd)
{ {
bool addorrep = cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE;
struct net_device *dev = tp->q->dev_queue->dev; struct net_device *dev = tp->q->dev_queue->dev;
struct tcf_block *block = tp->chain->block;
bool skip_sw = tc_skip_sw(prog->gen_flags);
struct tc_cls_bpf_offload cls_bpf = {}; struct tc_cls_bpf_offload cls_bpf = {};
int err; int err;
@ -159,17 +162,38 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
cls_bpf.exts_integrated = prog->exts_integrated; cls_bpf.exts_integrated = prog->exts_integrated;
cls_bpf.gen_flags = prog->gen_flags; cls_bpf.gen_flags = prog->gen_flags;
err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSBPF, &cls_bpf); if (tc_can_offload(dev)) {
if (!err && (cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE)) err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSBPF,
prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; &cls_bpf);
if (addorrep) {
if (err) {
if (skip_sw)
return err;
} else {
prog->gen_flags |= TCA_CLS_FLAGS_IN_HW;
}
}
}
return err; err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw);
if (addorrep) {
if (err < 0) {
cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY);
return err;
} else if (err > 0) {
prog->gen_flags |= TCA_CLS_FLAGS_IN_HW;
}
}
if (addorrep && skip_sw && !(prog->gen_flags && TCA_CLS_FLAGS_IN_HW))
return -EINVAL;
return 0;
} }
static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
struct cls_bpf_prog *oldprog) struct cls_bpf_prog *oldprog)
{ {
struct net_device *dev = tp->q->dev_queue->dev;
struct cls_bpf_prog *obj = prog; struct cls_bpf_prog *obj = prog;
enum tc_clsbpf_command cmd; enum tc_clsbpf_command cmd;
bool skip_sw; bool skip_sw;
@ -179,7 +203,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
(oldprog && tc_skip_sw(oldprog->gen_flags)); (oldprog && tc_skip_sw(oldprog->gen_flags));
if (oldprog && oldprog->offloaded) { if (oldprog && oldprog->offloaded) {
if (tc_should_offload(dev, prog->gen_flags)) { if (!tc_skip_hw(prog->gen_flags)) {
cmd = TC_CLSBPF_REPLACE; cmd = TC_CLSBPF_REPLACE;
} else if (!tc_skip_sw(prog->gen_flags)) { } else if (!tc_skip_sw(prog->gen_flags)) {
obj = oldprog; obj = oldprog;
@ -188,14 +212,14 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
return -EINVAL; return -EINVAL;
} }
} else { } else {
if (!tc_should_offload(dev, prog->gen_flags)) if (tc_skip_hw(prog->gen_flags))
return skip_sw ? -EINVAL : 0; return skip_sw ? -EINVAL : 0;
cmd = TC_CLSBPF_ADD; cmd = TC_CLSBPF_ADD;
} }
ret = cls_bpf_offload_cmd(tp, obj, cmd); ret = cls_bpf_offload_cmd(tp, obj, cmd);
if (ret) if (ret)
return skip_sw ? ret : 0; return ret;
obj->offloaded = true; obj->offloaded = true;
if (oldprog) if (oldprog)