Skip to content

Commit

Permalink
igc: Lift TAPRIO schedule restriction
Browse files Browse the repository at this point in the history
Add support for Qbv schedules where one queue stays open
in consecutive entries. Currently that's not supported.

Example schedule:

|tc qdisc replace dev ${INTERFACE} handle 100 parent root taprio num_tc 3 \
|   map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 \
|   queues 1@0 1@1 2@2 \
|   base-time ${BASETIME} \
|   sched-entry S 0x01 300000 \ # Stream High/Low
|   sched-entry S 0x06 500000 \ # Management and Best Effort
|   sched-entry S 0x04 200000 \ # Best Effort
|   flags 0x02

Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Tested-by: Naama Meir <naamax.meir@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
shifty91 authored and anguy11 committed Jul 18, 2022
1 parent 6e693a1 commit a5fd394
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions drivers/net/ethernet/intel/igc/igc_main.c
Expand Up @@ -5813,9 +5813,10 @@ static bool validate_schedule(struct igc_adapter *adapter,
return false;

for (n = 0; n < qopt->num_entries; n++) {
const struct tc_taprio_sched_entry *e;
const struct tc_taprio_sched_entry *e, *prev;
int i;

prev = n ? &qopt->entries[n - 1] : NULL;
e = &qopt->entries[n];

/* i225 only supports "global" frame preemption
Expand All @@ -5828,7 +5829,12 @@ static bool validate_schedule(struct igc_adapter *adapter,
if (e->gate_mask & BIT(i))
queue_uses[i]++;

if (queue_uses[i] > 1)
/* There are limitations: A single queue cannot be
* opened and closed multiple times per cycle unless the
* gate stays open. Check for it.
*/
if (queue_uses[i] > 1 &&
!(prev->gate_mask & BIT(i)))
return false;
}
}
Expand Down Expand Up @@ -5872,6 +5878,7 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)
static int igc_save_qbv_schedule(struct igc_adapter *adapter,
struct tc_taprio_qopt_offload *qopt)
{
bool queue_configured[IGC_MAX_TX_QUEUES] = { };
u32 start_time = 0, end_time = 0;
size_t n;

Expand All @@ -5887,9 +5894,6 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
adapter->cycle_time = qopt->cycle_time;
adapter->base_time = qopt->base_time;

/* FIXME: be a little smarter about cases when the gate for a
* queue stays open for more than one entry.
*/
for (n = 0; n < qopt->num_entries; n++) {
struct tc_taprio_sched_entry *e = &qopt->entries[n];
int i;
Expand All @@ -5902,8 +5906,15 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
if (!(e->gate_mask & BIT(i)))
continue;

ring->start_time = start_time;
/* Check whether a queue stays open for more than one
* entry. If so, keep the start and advance the end
* time.
*/
if (!queue_configured[i])
ring->start_time = start_time;
ring->end_time = end_time;

queue_configured[i] = true;
}

start_time += e->interval;
Expand Down

0 comments on commit a5fd394

Please sign in to comment.