@@ -3204,8 +3204,16 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
}
if (pf->oicr_misc & PFINT_OICR_TSYN_TX_M) {
- while (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING)
- usleep_range(50, 100);
+ struct ice_hw *hw = &pf->hw;
+
+ /* Process outstanding Tx timestamps. If there is more work,
+ * re-arm the interrupt to trigger again.
+ */
+ if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) {
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
+ ice_flush(hw);
+ }
+
pf->oicr_misc &= ~PFINT_OICR_TSYN_TX_M;
}
In ice_misc_intr_thread_fn(), if we do not complete all Tx timestamp work, the thread function will poll continuously forever. For E822 hardware, this wastes time as the return value from ice_ptp_process_ts() is accurate and always reports correctly that the PHY actually has new timestamp data. In addition, if we receive enough timestamps at the right pacing, we might never exit this polling and thus prevent other interrupt tasks from being processed. Fix this by instead writing to PFINT_OICR, causing an emulated interrupt to be triggered immediately. This does take slightly more processing than just re-checking the timestamps. However, it allows all of the other interrupt causes a chance to be processed first in the hard IRQ function. Note that the OICR interrupt is throttled to 8K per second, so the hardware will not let the interrupt trigger more often than once every 124 microseconds, so this should not cause a significant increase in CPU usage vs the sleeping method. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> --- drivers/net/ethernet/intel/ice/ice_main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)