Skip to content

Commit

Permalink
taprio: Fix using wrong queues in gate mask
Browse files Browse the repository at this point in the history
Since commit 9c66d15 ("taprio: Add support for hardware
offloading") there's a bit of inconsistency when offloading schedules
to the hardware:

In software mode, the gate masks are specified in terms of traffic
classes, so if say "sched-entry S 03 20000", it means that the traffic
classes 0 and 1 are open for 20us; when taprio is offloaded to
hardware, the gate masks are specified in terms of hardware queues.

The idea here is to fix hardware offloading, so schedules in hardware
and software mode have the same behavior. What's needed to do is to
map traffic classes to queues when applying the offload to the driver.

Fixes: 9c66d15 ("taprio: Add support for hardware offloading")
Signed-off-by: Vinicius Costa Gomes <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
vcgomes authored and davem330 committed Aug 26, 2020
1 parent 5fd99b5 commit 09e31cf
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions net/sched/sch_taprio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,9 +1176,27 @@ static void taprio_offload_config_changed(struct taprio_sched *q)
spin_unlock(&q->current_entry_lock);
}

static void taprio_sched_to_offload(struct taprio_sched *q,
static u32 tc_map_to_queue_mask(struct net_device *dev, u32 tc_mask)
{
u32 i, queue_mask = 0;

for (i = 0; i < dev->num_tc; i++) {
u32 offset, count;

if (!(tc_mask & BIT(i)))
continue;

offset = dev->tc_to_txq[i].offset;
count = dev->tc_to_txq[i].count;

queue_mask |= GENMASK(offset + count - 1, offset);
}

return queue_mask;
}

static void taprio_sched_to_offload(struct net_device *dev,
struct sched_gate_list *sched,
const struct tc_mqprio_qopt *mqprio,
struct tc_taprio_qopt_offload *offload)
{
struct sched_entry *entry;
Expand All @@ -1193,15 +1211,15 @@ static void taprio_sched_to_offload(struct taprio_sched *q,

e->command = entry->command;
e->interval = entry->interval;
e->gate_mask = entry->gate_mask;
e->gate_mask = tc_map_to_queue_mask(dev, entry->gate_mask);

i++;
}

offload->num_entries = i;
}

static int taprio_enable_offload(struct net_device *dev,
struct tc_mqprio_qopt *mqprio,
struct taprio_sched *q,
struct sched_gate_list *sched,
struct netlink_ext_ack *extack)
Expand All @@ -1223,7 +1241,7 @@ static int taprio_enable_offload(struct net_device *dev,
return -ENOMEM;
}
offload->enable = 1;
taprio_sched_to_offload(q, sched, mqprio, offload);
taprio_sched_to_offload(dev, sched, offload);

err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
if (err < 0) {
Expand Down Expand Up @@ -1485,7 +1503,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
}

if (FULL_OFFLOAD_IS_ENABLED(q->flags))
err = taprio_enable_offload(dev, mqprio, q, new_admin, extack);
err = taprio_enable_offload(dev, q, new_admin, extack);
else
err = taprio_disable_offload(dev, q, extack);
if (err)
Expand Down

0 comments on commit 09e31cf

Please sign in to comment.