Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gve: Fix case where desc_cnt and data_cnt can get out of sync

desc_cnt and data_cnt should always be equal. In the case of a dropped
packet desc_cnt was still getting updated (correctly), data_cnt
was not. To eliminate this bug and prevent it from recurring this
patch combines them into one ring level cnt.

Signed-off-by: Catherine Sullivan <csully@google.com>
Reviewed-by: Sagi Shahar <sagis@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Catherine Sullivan and committed by
David S. Miller
438b43bd cff6a327

+20 -26
+3 -5
drivers/net/ethernet/google/gve/gve.h
··· 31 31 struct gve_rx_desc_queue { 32 32 struct gve_rx_desc *desc_ring; /* the descriptor ring */ 33 33 dma_addr_t bus; /* the bus for the desc_ring */ 34 - u32 cnt; /* free-running total number of completed packets */ 35 - u32 fill_cnt; /* free-running total number of descriptors posted */ 36 - u32 mask; /* masks the cnt to the size of the ring */ 37 34 u8 seqno; /* the next expected seqno for this desc*/ 38 35 }; 39 36 ··· 57 60 dma_addr_t data_bus; /* dma mapping of the slots */ 58 61 struct gve_rx_slot_page_info *page_info; /* page info of the buffers */ 59 62 struct gve_queue_page_list *qpl; /* qpl assigned to this queue */ 60 - u32 mask; /* masks the cnt to the size of the ring */ 61 - u32 cnt; /* free-running total number of completed packets */ 62 63 }; 63 64 64 65 struct gve_priv; ··· 68 73 struct gve_rx_data_queue data; 69 74 u64 rbytes; /* free-running bytes received */ 70 75 u64 rpackets; /* free-running packets received */ 76 + u32 cnt; /* free-running total number of completed packets */ 77 + u32 fill_cnt; /* free-running total number of descs and buffs posted */ 78 + u32 mask; /* masks the cnt and fill_cnt to the size of the ring */ 71 79 u32 q_num; /* queue index */ 72 80 u32 ntfy_id; /* notification block index */ 73 81 struct gve_queue_resources *q_resources; /* head and tail pointer idx */
+2 -2
drivers/net/ethernet/google/gve/gve_ethtool.c
··· 138 138 for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) { 139 139 struct gve_rx_ring *rx = &priv->rx[ring]; 140 140 141 - data[i++] = rx->desc.cnt; 142 - data[i++] = rx->desc.fill_cnt; 141 + data[i++] = rx->cnt; 142 + data[i++] = rx->fill_cnt; 143 143 } 144 144 } else { 145 145 i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS;
+15 -19
drivers/net/ethernet/google/gve/gve_rx.c
··· 37 37 rx->data.qpl = NULL; 38 38 kvfree(rx->data.page_info); 39 39 40 - slots = rx->data.mask + 1; 40 + slots = rx->mask + 1; 41 41 bytes = sizeof(*rx->data.data_ring) * slots; 42 42 dma_free_coherent(dev, bytes, rx->data.data_ring, 43 43 rx->data.data_bus); ··· 64 64 /* Allocate one page per Rx queue slot. Each page is split into two 65 65 * packet buffers, when possible we "page flip" between the two. 66 66 */ 67 - slots = rx->data.mask + 1; 67 + slots = rx->mask + 1; 68 68 69 69 rx->data.page_info = kvzalloc(slots * 70 70 sizeof(*rx->data.page_info), GFP_KERNEL); ··· 111 111 rx->q_num = idx; 112 112 113 113 slots = priv->rx_pages_per_qpl; 114 - rx->data.mask = slots - 1; 114 + rx->mask = slots - 1; 115 115 116 116 /* alloc rx data ring */ 117 117 bytes = sizeof(*rx->data.data_ring) * slots; ··· 125 125 err = -ENOMEM; 126 126 goto abort_with_slots; 127 127 } 128 - rx->desc.fill_cnt = filled_pages; 128 + rx->fill_cnt = filled_pages; 129 129 /* Ensure data ring slots (packet buffers) are visible. */ 130 130 dma_wmb(); 131 131 ··· 156 156 err = -ENOMEM; 157 157 goto abort_with_q_resources; 158 158 } 159 - rx->desc.mask = slots - 1; 160 - rx->desc.cnt = 0; 159 + rx->mask = slots - 1; 160 + rx->cnt = 0; 161 161 rx->desc.seqno = 1; 162 162 gve_rx_add_to_block(priv, idx); 163 163 ··· 213 213 { 214 214 u32 db_idx = be32_to_cpu(rx->q_resources->db_index); 215 215 216 - iowrite32be(rx->desc.fill_cnt, &priv->db_bar2[db_idx]); 216 + iowrite32be(rx->fill_cnt, &priv->db_bar2[db_idx]); 217 217 } 218 218 219 219 static enum pkt_hash_types gve_rss_type(__be16 pkt_flags) ··· 273 273 } 274 274 275 275 static bool gve_rx(struct gve_rx_ring *rx, struct gve_rx_desc *rx_desc, 276 - netdev_features_t feat) 276 + netdev_features_t feat, u32 idx) 277 277 { 278 278 struct gve_rx_slot_page_info *page_info; 279 279 struct gve_priv *priv = rx->gve; ··· 282 282 struct sk_buff *skb; 283 283 int pagecount; 284 284 u16 len; 285 - u32 idx; 286 285 287 286 /* drop this packet */ 288 287 if (unlikely(rx_desc->flags_seq & GVE_RXF_ERR)) 289 288 return true; 290 289 291 290 len = be16_to_cpu(rx_desc->len) - GVE_RX_PAD; 292 - idx = rx->data.cnt & rx->data.mask; 293 291 page_info = &rx->data.page_info[idx]; 294 292 295 293 /* gvnic can only receive into registered segments. If the buffer ··· 338 340 if (!skb) 339 341 return true; 340 342 341 - rx->data.cnt++; 342 - 343 343 if (likely(feat & NETIF_F_RXCSUM)) { 344 344 /* NIC passes up the partial sum */ 345 345 if (rx_desc->csum) ··· 366 370 __be16 flags_seq; 367 371 u32 next_idx; 368 372 369 - next_idx = rx->desc.cnt & rx->desc.mask; 373 + next_idx = rx->cnt & rx->mask; 370 374 desc = rx->desc.desc_ring + next_idx; 371 375 372 376 flags_seq = desc->flags_seq; ··· 381 385 { 382 386 struct gve_priv *priv = rx->gve; 383 387 struct gve_rx_desc *desc; 384 - u32 cnt = rx->desc.cnt; 385 - u32 idx = cnt & rx->desc.mask; 388 + u32 cnt = rx->cnt; 389 + u32 idx = cnt & rx->mask; 386 390 u32 work_done = 0; 387 391 u64 bytes = 0; 388 392 ··· 397 401 rx->q_num, GVE_SEQNO(desc->flags_seq), 398 402 rx->desc.seqno); 399 403 bytes += be16_to_cpu(desc->len) - GVE_RX_PAD; 400 - if (!gve_rx(rx, desc, feat)) 404 + if (!gve_rx(rx, desc, feat, idx)) 401 405 gve_schedule_reset(priv); 402 406 cnt++; 403 - idx = cnt & rx->desc.mask; 407 + idx = cnt & rx->mask; 404 408 desc = rx->desc.desc_ring + idx; 405 409 rx->desc.seqno = gve_next_seqno(rx->desc.seqno); 406 410 work_done++; ··· 413 417 rx->rpackets += work_done; 414 418 rx->rbytes += bytes; 415 419 u64_stats_update_end(&rx->statss); 416 - rx->desc.cnt = cnt; 417 - rx->desc.fill_cnt += work_done; 420 + rx->cnt = cnt; 421 + rx->fill_cnt += work_done; 418 422 419 423 /* restock desc ring slots */ 420 424 dma_wmb(); /* Ensure descs are visible before ringing doorbell */