Skip to content

Commit

Permalink
net: sch: prio: Add offload ability for grafting a child
Browse files Browse the repository at this point in the history
Offload sch_prio graft command for capable drivers.
Warn in case of a failure, unless the graft was done as part of a destroy
operation (the new qdisc is a noop) or if all the qdiscs (the parent, the
old child, and the new one) are not offloaded.

Signed-off-by: Nogah Frankel <nogahf@mellanox.com>
Reviewed-by: Yuval Mintz <yuvalm@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nogah Frankel authored and David S. Miller committed Feb 28, 2018
1 parent 98ceb7b commit b9c7a7a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/net/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ enum tc_prio_command {
TC_PRIO_REPLACE,
TC_PRIO_DESTROY,
TC_PRIO_STATS,
TC_PRIO_GRAFT,
};

struct tc_prio_qopt_offload_params {
Expand All @@ -818,13 +819,20 @@ struct tc_prio_qopt_offload_params {
struct gnet_stats_queue *qstats;
};

struct tc_prio_qopt_offload_graft_params {
u8 band;
u32 child_handle;
};

struct tc_prio_qopt_offload {
enum tc_prio_command command;
u32 handle;
u32 parent;
union {
struct tc_prio_qopt_offload_params replace_params;
struct tc_qopt_offload_stats stats;
struct tc_prio_qopt_offload_graft_params graft_params;
};
};

#endif
32 changes: 32 additions & 0 deletions net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,44 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
struct Qdisc **old, struct netlink_ext_ack *extack)
{
struct prio_sched_data *q = qdisc_priv(sch);
struct tc_prio_qopt_offload graft_offload;
struct net_device *dev = qdisc_dev(sch);
unsigned long band = arg - 1;
bool any_qdisc_is_offloaded;
int err;

if (new == NULL)
new = &noop_qdisc;

*old = qdisc_replace(sch, new, &q->queues[band]);

if (!tc_can_offload(dev))
return 0;

graft_offload.handle = sch->handle;
graft_offload.parent = sch->parent;
graft_offload.graft_params.band = band;
graft_offload.graft_params.child_handle = new->handle;
graft_offload.command = TC_PRIO_GRAFT;

err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO,
&graft_offload);

/* Don't report error if the graft is part of destroy operation. */
if (err && new != &noop_qdisc) {
/* Don't report error if the parent, the old child and the new
* one are not offloaded.
*/
any_qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
any_qdisc_is_offloaded |= new->flags & TCQ_F_OFFLOADED;
if (*old)
any_qdisc_is_offloaded |= (*old)->flags &
TCQ_F_OFFLOADED;

if (any_qdisc_is_offloaded)
NL_SET_ERR_MSG(extack, "Offloading graft operation failed.");
}

return 0;
}

Expand Down

0 comments on commit b9c7a7a

Please sign in to comment.