aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/selftest.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index febe2a9e6211..dc330b9d9168 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -25,6 +25,16 @@
25#include "selftest.h" 25#include "selftest.h"
26#include "workarounds.h" 26#include "workarounds.h"
27 27
28/* IRQ latency can be enormous because:
29 * - All IRQs may be disabled on a CPU for a *long* time by e.g. a
30 * slow serial console or an old IDE driver doing error recovery
31 * - The PREEMPT_RT patches mostly deal with this, but also allow a
32 * tasklet or normal task to be given higher priority than our IRQ
33 * threads
34 * Try to avoid blaming the hardware for this.
35 */
36#define IRQ_TIMEOUT HZ
37
28/* 38/*
29 * Loopback test packet structure 39 * Loopback test packet structure
30 * 40 *
@@ -77,6 +87,9 @@ struct efx_loopback_state {
77 struct efx_loopback_payload payload; 87 struct efx_loopback_payload payload;
78}; 88};
79 89
90/* How long to wait for all the packets to arrive (in ms) */
91#define LOOPBACK_TIMEOUT_MS 1000
92
80/************************************************************************** 93/**************************************************************************
81 * 94 *
82 * MII, NVRAM and register tests 95 * MII, NVRAM and register tests
@@ -130,6 +143,7 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
130static int efx_test_interrupts(struct efx_nic *efx, 143static int efx_test_interrupts(struct efx_nic *efx,
131 struct efx_self_tests *tests) 144 struct efx_self_tests *tests)
132{ 145{
146 unsigned long timeout, wait;
133 int cpu; 147 int cpu;
134 148
135 netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n"); 149 netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n");
@@ -140,13 +154,18 @@ static int efx_test_interrupts(struct efx_nic *efx,
140 smp_wmb(); 154 smp_wmb();
141 155
142 efx_nic_generate_interrupt(efx); 156 efx_nic_generate_interrupt(efx);
157 timeout = jiffies + IRQ_TIMEOUT;
158 wait = 1;
143 159
144 /* Wait for arrival of test interrupt. */ 160 /* Wait for arrival of test interrupt. */
145 netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n"); 161 netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n");
146 schedule_timeout_uninterruptible(HZ / 10); 162 do {
147 cpu = ACCESS_ONCE(efx->last_irq_cpu); 163 schedule_timeout_uninterruptible(wait);
148 if (cpu >= 0) 164 cpu = ACCESS_ONCE(efx->last_irq_cpu);
149 goto success; 165 if (cpu >= 0)
166 goto success;
167 wait *= 2;
168 } while (time_before(jiffies, timeout));
150 169
151 netif_err(efx, drv, efx->net_dev, "timed out waiting for interrupt\n"); 170 netif_err(efx, drv, efx->net_dev, "timed out waiting for interrupt\n");
152 return -ETIMEDOUT; 171 return -ETIMEDOUT;
@@ -165,29 +184,37 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
165 struct efx_nic *efx = channel->efx; 184 struct efx_nic *efx = channel->efx;
166 unsigned int read_ptr; 185 unsigned int read_ptr;
167 bool napi_ran, dma_seen, int_seen; 186 bool napi_ran, dma_seen, int_seen;
187 unsigned long timeout, wait;
168 188
169 read_ptr = channel->eventq_read_ptr; 189 read_ptr = channel->eventq_read_ptr;
170 channel->last_irq_cpu = -1; 190 channel->last_irq_cpu = -1;
171 smp_wmb(); 191 smp_wmb();
172 192
173 efx_nic_generate_test_event(channel); 193 efx_nic_generate_test_event(channel);
194 timeout = jiffies + IRQ_TIMEOUT;
195 wait = 1;
174 196
175 /* Wait for arrival of interrupt. NAPI processing may or may 197 /* Wait for arrival of interrupt. NAPI processing may or may
176 * not complete in time, but we can cope in any case. 198 * not complete in time, but we can cope in any case.
177 */ 199 */
178 msleep(10); 200 do {
179 napi_disable(&channel->napi_str); 201 schedule_timeout_uninterruptible(wait);
180 if (channel->eventq_read_ptr != read_ptr) { 202
181 napi_ran = true; 203 napi_disable(&channel->napi_str);
182 dma_seen = true; 204 if (channel->eventq_read_ptr != read_ptr) {
183 int_seen = true; 205 napi_ran = true;
184 } else { 206 dma_seen = true;
185 napi_ran = false; 207 int_seen = true;
186 dma_seen = efx_nic_event_present(channel); 208 } else {
187 int_seen = ACCESS_ONCE(channel->last_irq_cpu) >= 0; 209 napi_ran = false;
188 } 210 dma_seen = efx_nic_event_present(channel);
189 napi_enable(&channel->napi_str); 211 int_seen = ACCESS_ONCE(channel->last_irq_cpu) >= 0;
190 efx_nic_eventq_read_ack(channel); 212 }
213 napi_enable(&channel->napi_str);
214 efx_nic_eventq_read_ack(channel);
215
216 wait *= 2;
217 } while (!(dma_seen && int_seen) && time_before(jiffies, timeout));
191 218
192 tests->eventq_dma[channel->channel] = dma_seen ? 1 : -1; 219 tests->eventq_dma[channel->channel] = dma_seen ? 1 : -1;
193 tests->eventq_int[channel->channel] = int_seen ? 1 : -1; 220 tests->eventq_int[channel->channel] = int_seen ? 1 : -1;
@@ -516,10 +543,10 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
516 begin_rc = efx_begin_loopback(tx_queue); 543 begin_rc = efx_begin_loopback(tx_queue);
517 544
518 /* This will normally complete very quickly, but be 545 /* This will normally complete very quickly, but be
519 * prepared to wait up to 100 ms. */ 546 * prepared to wait much longer. */
520 msleep(1); 547 msleep(1);
521 if (!efx_poll_loopback(efx)) { 548 if (!efx_poll_loopback(efx)) {
522 msleep(100); 549 msleep(LOOPBACK_TIMEOUT_MS);
523 efx_poll_loopback(efx); 550 efx_poll_loopback(efx);
524 } 551 }
525 552