gve: Fix bug in gve_rx_alloc/free_ring

In gve_rx_free_ring, now that we are setting the pagecount high, rather
than just freeing the page with put_page we need to make sure we
subtract off the bias first.

In gve_rx_alloc_ring, we need to unfill the ring if the allocation fails
to properly cleanup.

In gve_prefill_buffers, if a page allocation failed we weren't cleaning
up properly. In addition to freeing the page we need to reduce the page
count so we should be using free_buffer. We should also be actually
iterating over the buffers that were successfully alloced not using the
local page and addr vars.

BUG=b/184636169

Signed-off-by: Catherine Sullivan <csully@google.com>
Change-Id: Ic944a6f59ad522fb7fdd96a5e28d492bf855561a
Reviewed-on: https://cos-review.googlesource.com/c/third_party/kernel/+/14552
Reviewed-by: Oleksandr Tymoshenko <ovt@google.com>
Tested-by: Vaibhav Rustagi <vaibhavrustagi@google.com>
diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c
index 302f443..d852204 100644
--- a/drivers/net/ethernet/google/gve/gve_rx.c
+++ b/drivers/net/ethernet/google/gve/gve_rx.c
@@ -27,6 +27,25 @@
 	gve_free_page(dev, page_info->page, dma, DMA_FROM_DEVICE);
 }
 
+static void gve_rx_unfill_pages(struct gve_priv *priv, struct gve_rx_ring *rx) {
+	u32 slots = rx->mask + 1;
+	int i;
+
+	if (rx->data.raw_addressing) {
+		for (i = 0; i < slots; i++)
+			gve_rx_free_buffer(&priv->pdev->dev, &rx->data.page_info[i],
+					   &rx->data.data_ring[i]);
+	} else {
+		for (i = 0; i < slots; i++)
+			page_ref_sub(rx->data.page_info[i].page,
+				     rx->data.page_info[i].pagecnt_bias - 1);
+		gve_unassign_qpl(priv, rx->data.qpl->id);
+		rx->data.qpl = NULL;
+	}
+	kfree(rx->data.page_info);
+	rx->data.page_info = NULL;
+}
+
 static void gve_rx_free_ring(struct gve_priv *priv, int idx)
 {
 	struct gve_rx_ring *rx = &priv->rx[idx];
@@ -44,17 +63,7 @@
 			  rx->q_resources, rx->q_resources_bus);
 	rx->q_resources = NULL;
 
-	if (rx->data.raw_addressing) {
-		int i;
-
-		for (i = 0; i < slots; i++)
-			gve_rx_free_buffer(dev, &rx->data.page_info[i],
-					   &rx->data.data_ring[i]);
-	} else {
-		gve_unassign_qpl(priv, rx->data.qpl->id);
-		rx->data.qpl = NULL;
-	}
-	kfree(rx->data.page_info);
+	gve_rx_unfill_pages(priv, rx);
 
 	bytes = sizeof(*rx->data.data_ring) * slots;
 	dma_free_coherent(dev, bytes, rx->data.data_ring,
@@ -115,8 +124,9 @@
 				rx->rx_buf_alloc_fail++;
 				u64_stats_update_end(&rx->statss);
 				for (j = 0; j < i; j++)
-					gve_free_page(&priv->pdev->dev, page,
-						      addr, DMA_FROM_DEVICE);
+					gve_rx_free_buffer(&priv->pdev->dev,
+							 &rx->data.page_info[j],
+							 &rx->data.data_ring[j]);
 				return err;
 			}
 		} else {
@@ -219,7 +229,7 @@
 			  rx->q_resources, rx->q_resources_bus);
 	rx->q_resources = NULL;
 abort_filled:
-	kfree(rx->data.page_info);
+	gve_rx_unfill_pages(priv, rx);
 abort_with_slots:
 	bytes = sizeof(*rx->data.data_ring) * slots;
 	dma_free_coherent(hdev, bytes, rx->data.data_ring, rx->data.data_bus);