Skip to content

Commit e679198

Browse files
committed
Merge branch 'gve-improvements'
Jeroen de Borst says: ==================== gve: minor code and performance improvements This patchset contains a number of independent minor code and performance improvements. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ce8bd03 + 1b4d1c9 commit e679198

File tree

7 files changed

+201
-103
lines changed

7 files changed

+201
-103
lines changed

drivers/net/ethernet/google/gve/gve.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define GVE_MIN_MSIX 3
3131

3232
/* Numbers of gve tx/rx stats in stats report. */
33-
#define GVE_TX_STATS_REPORT_NUM 5
33+
#define GVE_TX_STATS_REPORT_NUM 6
3434
#define GVE_RX_STATS_REPORT_NUM 2
3535

3636
/* Interval to schedule a stats report update, 20000ms. */
@@ -341,8 +341,8 @@ struct gve_tx_ring {
341341
union {
342342
/* GQI fields */
343343
struct {
344-
/* NIC tail pointer */
345-
__be32 last_nic_done;
344+
/* Spinlock for when cleanup in progress */
345+
spinlock_t clean_lock;
346346
};
347347

348348
/* DQO fields. */
@@ -413,7 +413,9 @@ struct gve_tx_ring {
413413
u32 q_num ____cacheline_aligned; /* queue idx */
414414
u32 stop_queue; /* count of queue stops */
415415
u32 wake_queue; /* count of queue wakes */
416+
u32 queue_timeout; /* count of queue timeouts */
416417
u32 ntfy_id; /* notification block index */
418+
u32 last_kick_msec; /* Last time the queue was kicked */
417419
dma_addr_t bus; /* dma address of the descr ring */
418420
dma_addr_t q_resources_bus; /* dma address of the queue resources */
419421
dma_addr_t complq_bus_dqo; /* dma address of the dqo.compl_ring */
@@ -821,15 +823,15 @@ netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev);
821823
bool gve_tx_poll(struct gve_notify_block *block, int budget);
822824
int gve_tx_alloc_rings(struct gve_priv *priv);
823825
void gve_tx_free_rings_gqi(struct gve_priv *priv);
824-
__be32 gve_tx_load_event_counter(struct gve_priv *priv,
825-
struct gve_tx_ring *tx);
826+
u32 gve_tx_load_event_counter(struct gve_priv *priv,
827+
struct gve_tx_ring *tx);
828+
bool gve_tx_clean_pending(struct gve_priv *priv, struct gve_tx_ring *tx);
826829
/* rx handling */
827830
void gve_rx_write_doorbell(struct gve_priv *priv, struct gve_rx_ring *rx);
828-
bool gve_rx_poll(struct gve_notify_block *block, int budget);
831+
int gve_rx_poll(struct gve_notify_block *block, int budget);
832+
bool gve_rx_work_pending(struct gve_rx_ring *rx);
829833
int gve_rx_alloc_rings(struct gve_priv *priv);
830834
void gve_rx_free_rings_gqi(struct gve_priv *priv);
831-
bool gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
832-
netdev_features_t feat);
833835
/* Reset */
834836
void gve_schedule_reset(struct gve_priv *priv);
835837
int gve_reset(struct gve_priv *priv, bool attempt_teardown);

drivers/net/ethernet/google/gve/gve_adminq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ enum gve_stat_names {
270270
TX_LAST_COMPLETION_PROCESSED = 5,
271271
RX_NEXT_EXPECTED_SEQUENCE = 6,
272272
RX_BUFFERS_POSTED = 7,
273+
TX_TIMEOUT_CNT = 8,
273274
// stats from NIC
274275
RX_QUEUE_DROP_CNT = 65,
275276
RX_NO_BUFFERS_POSTED = 66,

drivers/net/ethernet/google/gve/gve_ethtool.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
330330
data[i++] = tmp_tx_bytes;
331331
data[i++] = tx->wake_queue;
332332
data[i++] = tx->stop_queue;
333-
data[i++] = be32_to_cpu(gve_tx_load_event_counter(priv,
334-
tx));
333+
data[i++] = gve_tx_load_event_counter(priv, tx);
335334
data[i++] = tx->dma_mapping_error;
336335
/* stats from NIC */
337336
if (skip_nic_stats) {

drivers/net/ethernet/google/gve/gve_main.c

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#define GVE_VERSION "1.0.0"
2525
#define GVE_VERSION_PREFIX "GVE-"
2626

27+
// Minimum amount of time between queue kicks in msec (10 seconds)
28+
#define MIN_TX_TIMEOUT_GAP (1000 * 10)
29+
2730
const char gve_version_str[] = GVE_VERSION;
2831
static const char gve_version_prefix[] = GVE_VERSION_PREFIX;
2932

@@ -192,34 +195,40 @@ static int gve_napi_poll(struct napi_struct *napi, int budget)
192195
__be32 __iomem *irq_doorbell;
193196
bool reschedule = false;
194197
struct gve_priv *priv;
198+
int work_done = 0;
195199

196200
block = container_of(napi, struct gve_notify_block, napi);
197201
priv = block->priv;
198202

199203
if (block->tx)
200204
reschedule |= gve_tx_poll(block, budget);
201-
if (block->rx)
202-
reschedule |= gve_rx_poll(block, budget);
205+
if (block->rx) {
206+
work_done = gve_rx_poll(block, budget);
207+
reschedule |= work_done == budget;
208+
}
203209

204210
if (reschedule)
205211
return budget;
206212

207-
napi_complete(napi);
208-
irq_doorbell = gve_irq_doorbell(priv, block);
209-
iowrite32be(GVE_IRQ_ACK | GVE_IRQ_EVENT, irq_doorbell);
213+
/* Complete processing - don't unmask irq if busy polling is enabled */
214+
if (likely(napi_complete_done(napi, work_done))) {
215+
irq_doorbell = gve_irq_doorbell(priv, block);
216+
iowrite32be(GVE_IRQ_ACK | GVE_IRQ_EVENT, irq_doorbell);
210217

211-
/* Double check we have no extra work.
212-
* Ensure unmask synchronizes with checking for work.
213-
*/
214-
mb();
215-
if (block->tx)
216-
reschedule |= gve_tx_poll(block, -1);
217-
if (block->rx)
218-
reschedule |= gve_rx_poll(block, -1);
219-
if (reschedule && napi_reschedule(napi))
220-
iowrite32be(GVE_IRQ_MASK, irq_doorbell);
218+
/* Ensure IRQ ACK is visible before we check pending work.
219+
* If queue had issued updates, it would be truly visible.
220+
*/
221+
mb();
221222

222-
return 0;
223+
if (block->tx)
224+
reschedule |= gve_tx_clean_pending(priv, block->tx);
225+
if (block->rx)
226+
reschedule |= gve_rx_work_pending(block->rx);
227+
228+
if (reschedule && napi_reschedule(napi))
229+
iowrite32be(GVE_IRQ_MASK, irq_doorbell);
230+
}
231+
return work_done;
223232
}
224233

225234
static int gve_napi_poll_dqo(struct napi_struct *napi, int budget)
@@ -1115,9 +1124,47 @@ static void gve_turnup(struct gve_priv *priv)
11151124

11161125
static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue)
11171126
{
1118-
struct gve_priv *priv = netdev_priv(dev);
1127+
struct gve_notify_block *block;
1128+
struct gve_tx_ring *tx = NULL;
1129+
struct gve_priv *priv;
1130+
u32 last_nic_done;
1131+
u32 current_time;
1132+
u32 ntfy_idx;
11191133

1134+
netdev_info(dev, "Timeout on tx queue, %d", txqueue);
1135+
priv = netdev_priv(dev);
1136+
if (txqueue > priv->tx_cfg.num_queues)
1137+
goto reset;
1138+
1139+
ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue);
1140+
if (ntfy_idx > priv->num_ntfy_blks)
1141+
goto reset;
1142+
1143+
block = &priv->ntfy_blocks[ntfy_idx];
1144+
tx = block->tx;
1145+
1146+
current_time = jiffies_to_msecs(jiffies);
1147+
if (tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time)
1148+
goto reset;
1149+
1150+
/* Check to see if there are missed completions, which will allow us to
1151+
* kick the queue.
1152+
*/
1153+
last_nic_done = gve_tx_load_event_counter(priv, tx);
1154+
if (last_nic_done - tx->done) {
1155+
netdev_info(dev, "Kicking queue %d", txqueue);
1156+
iowrite32be(GVE_IRQ_MASK, gve_irq_doorbell(priv, block));
1157+
napi_schedule(&block->napi);
1158+
tx->last_kick_msec = current_time;
1159+
goto out;
1160+
} // Else reset.
1161+
1162+
reset:
11201163
gve_schedule_reset(priv);
1164+
1165+
out:
1166+
if (tx)
1167+
tx->queue_timeout++;
11211168
priv->tx_timeo_cnt++;
11221169
}
11231170

@@ -1246,6 +1293,11 @@ void gve_handle_report_stats(struct gve_priv *priv)
12461293
.value = cpu_to_be64(last_completion),
12471294
.queue_id = cpu_to_be32(idx),
12481295
};
1296+
stats[stats_idx++] = (struct stats) {
1297+
.stat_name = cpu_to_be32(TX_TIMEOUT_CNT),
1298+
.value = cpu_to_be64(priv->tx[idx].queue_timeout),
1299+
.queue_id = cpu_to_be32(idx),
1300+
};
12491301
}
12501302
}
12511303
/* rx stats */

0 commit comments

Comments
 (0)