| From foo@baz Sun 09 Feb 2020 10:47:54 PM CET |
| From: Vinicius Costa Gomes <vinicius.gomes@intel.com> |
| Date: Thu, 6 Feb 2020 13:46:06 -0800 |
| Subject: taprio: Fix enabling offload with wrong number of traffic classes |
| |
| From: Vinicius Costa Gomes <vinicius.gomes@intel.com> |
| |
| [ Upstream commit 5652e63df3303c2a702bac25fbf710b9cb64dfba ] |
| |
| If the driver implementing taprio offloading depends on the value of |
| the network device number of traffic classes (dev->num_tc) for |
| whatever reason, it was going to receive the value zero. The value was |
| only set after the offloading function is called. |
| |
| So, moving setting the number of traffic classes to before the |
| offloading function is called fixes this issue. This is safe because |
| this only happens when taprio is instantiated (we don't allow this |
| configuration to be changed without first removing taprio). |
| |
| Fixes: 9c66d1564676 ("taprio: Add support for hardware offloading") |
| Reported-by: Po Liu <po.liu@nxp.com> |
| Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> |
| Acked-by: Vladimir Oltean <vladimir.oltean@nxp.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/sched/sch_taprio.c | 26 +++++++++++++------------- |
| 1 file changed, 13 insertions(+), 13 deletions(-) |
| |
| --- a/net/sched/sch_taprio.c |
| +++ b/net/sched/sch_taprio.c |
| @@ -1444,6 +1444,19 @@ static int taprio_change(struct Qdisc *s |
| |
| taprio_set_picos_per_byte(dev, q); |
| |
| + if (mqprio) { |
| + netdev_set_num_tc(dev, mqprio->num_tc); |
| + for (i = 0; i < mqprio->num_tc; i++) |
| + netdev_set_tc_queue(dev, i, |
| + mqprio->count[i], |
| + mqprio->offset[i]); |
| + |
| + /* Always use supplied priority mappings */ |
| + for (i = 0; i <= TC_BITMASK; i++) |
| + netdev_set_prio_tc_map(dev, i, |
| + mqprio->prio_tc_map[i]); |
| + } |
| + |
| if (FULL_OFFLOAD_IS_ENABLED(taprio_flags)) |
| err = taprio_enable_offload(dev, mqprio, q, new_admin, extack); |
| else |
| @@ -1471,19 +1484,6 @@ static int taprio_change(struct Qdisc *s |
| q->advance_timer.function = advance_sched; |
| } |
| |
| - if (mqprio) { |
| - netdev_set_num_tc(dev, mqprio->num_tc); |
| - for (i = 0; i < mqprio->num_tc; i++) |
| - netdev_set_tc_queue(dev, i, |
| - mqprio->count[i], |
| - mqprio->offset[i]); |
| - |
| - /* Always use supplied priority mappings */ |
| - for (i = 0; i <= TC_BITMASK; i++) |
| - netdev_set_prio_tc_map(dev, i, |
| - mqprio->prio_tc_map[i]); |
| - } |
| - |
| if (FULL_OFFLOAD_IS_ENABLED(taprio_flags)) { |
| q->dequeue = taprio_dequeue_offload; |
| q->peek = taprio_peek_offload; |