Commit bf2a752b authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

net: sched: red: offload a graft notification

Drivers offloading Qdiscs should have reasonable certainty
the offloaded behaviour matches the SW path.  This is impossible
if the driver does not know about all Qdiscs or when Qdiscs move
and are reused.  Send a graft notification from RED.  The drivers
are expected to simply stop offloading the Qdisc, if a non-standard
child is ever grafted onto it.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarJohn Hurley <john.hurley@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aee7539c
...@@ -834,6 +834,7 @@ enum tc_red_command { ...@@ -834,6 +834,7 @@ enum tc_red_command {
TC_RED_DESTROY, TC_RED_DESTROY,
TC_RED_STATS, TC_RED_STATS,
TC_RED_XSTATS, TC_RED_XSTATS,
TC_RED_GRAFT,
}; };
struct tc_red_qopt_offload_params { struct tc_red_qopt_offload_params {
...@@ -853,6 +854,7 @@ struct tc_red_qopt_offload { ...@@ -853,6 +854,7 @@ struct tc_red_qopt_offload {
struct tc_red_qopt_offload_params set; struct tc_red_qopt_offload_params set;
struct tc_qopt_offload_stats stats; struct tc_qopt_offload_stats stats;
struct red_stats *xstats; struct red_stats *xstats;
u32 child_handle;
}; };
}; };
......
...@@ -367,6 +367,21 @@ static int red_dump_class(struct Qdisc *sch, unsigned long cl, ...@@ -367,6 +367,21 @@ static int red_dump_class(struct Qdisc *sch, unsigned long cl,
return 0; return 0;
} }
static void red_graft_offload(struct Qdisc *sch,
struct Qdisc *new, struct Qdisc *old,
struct netlink_ext_ack *extack)
{
struct tc_red_qopt_offload graft_offload = {
.handle = sch->handle,
.parent = sch->parent,
.child_handle = new->handle,
.command = TC_RED_GRAFT,
};
qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, old,
TC_SETUP_QDISC_RED, &graft_offload, extack);
}
static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
struct Qdisc **old, struct netlink_ext_ack *extack) struct Qdisc **old, struct netlink_ext_ack *extack)
{ {
...@@ -376,6 +391,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, ...@@ -376,6 +391,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
new = &noop_qdisc; new = &noop_qdisc;
*old = qdisc_replace(sch, new, &q->qdisc); *old = qdisc_replace(sch, new, &q->qdisc);
red_graft_offload(sch, new, *old, extack);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment