Skip to content

Commit

Permalink
Merge branch '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…tnguy/net-queue

Tony Nguyen says:

====================
igc: Fix corner cases for TSN offload

Florian Kauer says:

The igc driver supports several different offloading capabilities
relevant in the TSN context. Recent patches in this area introduced
regressions for certain corner cases that are fixed in this series.

Each of the patches (except the first one) addresses a different
regression that can be separately reproduced. Still, they have
overlapping code changes so they should not be separately applied.

Especially #4 and #6 address the same observation,
but both need to be applied to avoid TX hang occurrences in
the scenario described in the patches.
====================

Signed-off-by: Florian Kauer <[email protected]>
Reviewed-by: Kurt Kanzenbach <[email protected]>
Acked-by: Vinicius Costa Gomes <[email protected]>
Reviewed-by: Muhammad Husaini Zulkifli <[email protected]>
Signed-off-by: Tony Nguyen <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jul 12, 2023
2 parents e522c1b + 0bcc628 commit b6c9ebd
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 19 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ struct igc_adapter {
int tc_setup_type;
ktime_t base_time;
ktime_t cycle_time;
bool qbv_enable;
bool taprio_offload_enable;
u32 qbv_config_change_errors;
bool qbv_transition;
unsigned int qbv_count;
Expand Down
24 changes: 9 additions & 15 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
ktime_t base_time = adapter->base_time;
ktime_t now = ktime_get_clocktai();
ktime_t baset_est, end_of_cycle;
u32 launchtime;
s32 launchtime;
s64 n;

n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
Expand All @@ -1029,7 +1029,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
*first_flag = true;
ring->last_ff_cycle = baset_est;

if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
if (ktime_compare(end_of_cycle, ring->last_tx_cycle) > 0)
*insert_empty = true;
}
}
Expand Down Expand Up @@ -6097,6 +6097,7 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)

adapter->base_time = 0;
adapter->cycle_time = NSEC_PER_SEC;
adapter->taprio_offload_enable = false;
adapter->qbv_config_change_errors = 0;
adapter->qbv_transition = false;
adapter->qbv_count = 0;
Expand Down Expand Up @@ -6124,31 +6125,24 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
size_t n;
int i;

switch (qopt->cmd) {
case TAPRIO_CMD_REPLACE:
adapter->qbv_enable = true;
break;
case TAPRIO_CMD_DESTROY:
adapter->qbv_enable = false;
break;
default:
return -EOPNOTSUPP;
}

if (!adapter->qbv_enable)
if (qopt->cmd == TAPRIO_CMD_DESTROY)
return igc_tsn_clear_schedule(adapter);

if (qopt->cmd != TAPRIO_CMD_REPLACE)
return -EOPNOTSUPP;

if (qopt->base_time < 0)
return -ERANGE;

if (igc_is_device_id_i225(hw) && adapter->base_time)
if (igc_is_device_id_i225(hw) && adapter->taprio_offload_enable)
return -EALREADY;

if (!validate_schedule(adapter, qopt))
return -EINVAL;

adapter->cycle_time = qopt->cycle_time;
adapter->base_time = qopt->base_time;
adapter->taprio_offload_enable = true;

igc_ptp_read(adapter, &now);

Expand Down
26 changes: 23 additions & 3 deletions drivers/net/ethernet/intel/igc/igc_tsn.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
{
unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;

if (adapter->qbv_enable)
if (adapter->taprio_offload_enable)
new_flags |= IGC_FLAG_TSN_QBV_ENABLED;

if (is_any_launchtime(adapter))
Expand Down Expand Up @@ -132,8 +132,28 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
wr32(IGC_STQT(i), ring->start_time);
wr32(IGC_ENDQT(i), ring->end_time);

txqctl |= IGC_TXQCTL_STRICT_CYCLE |
IGC_TXQCTL_STRICT_END;
if (adapter->taprio_offload_enable) {
/* If taprio_offload_enable is set we are in "taprio"
* mode and we need to be strict about the
* cycles: only transmit a packet if it can be
* completed during that cycle.
*
* If taprio_offload_enable is NOT true when
* enabling TSN offload, the cycle should have
* no external effects, but is only used internally
* to adapt the base time register after a second
* has passed.
*
* Enabling strict mode in this case would
* unnecessarily prevent the transmission of
* certain packets (i.e. at the boundary of a
* second) and thus interfere with the launchtime
* feature that promises transmission at a
* certain point in time.
*/
txqctl |= IGC_TXQCTL_STRICT_CYCLE |
IGC_TXQCTL_STRICT_END;
}

if (ring->launchtime_enable)
txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
Expand Down

0 comments on commit b6c9ebd

Please sign in to comment.