Skip to content

Commit bed7b22

Browse files
committed
Merge branch 'gve-add-support-for-non-4k-page-sizes'
John Fraker says: ==================== gve: Add support for non-4k page sizes. This patch series adds support for non-4k page sizes to the driver. Prior to this patch series, the driver assumes a 4k page size in many small ways, and will crash in a kernel compiled for a different page size. This changeset aims to be a minimal changeset that unblocks certain arm platforms with large page sizes. ==================== Link: https://lore.kernel.org/r/20231128002648.320892-1-jfraker@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents f1be1e0 + da7d4b4 commit bed7b22

File tree

8 files changed

+81
-52
lines changed

8 files changed

+81
-52
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define _GVE_H_
99

1010
#include <linux/dma-mapping.h>
11+
#include <linux/dmapool.h>
1112
#include <linux/netdevice.h>
1213
#include <linux/pci.h>
1314
#include <linux/u64_stats_sync.h>
@@ -41,12 +42,16 @@
4142
#define NIC_TX_STATS_REPORT_NUM 0
4243
#define NIC_RX_STATS_REPORT_NUM 4
4344

45+
#define GVE_ADMINQ_BUFFER_SIZE 4096
46+
4447
#define GVE_DATA_SLOT_ADDR_PAGE_MASK (~(PAGE_SIZE - 1))
4548

4649
/* PTYPEs are always 10 bits. */
4750
#define GVE_NUM_PTYPES 1024
4851

49-
#define GVE_RX_BUFFER_SIZE_DQO 2048
52+
#define GVE_DEFAULT_RX_BUFFER_SIZE 2048
53+
54+
#define GVE_DEFAULT_RX_BUFFER_OFFSET 2048
5055

5156
#define GVE_XDP_ACTIONS 5
5257

@@ -672,6 +677,7 @@ struct gve_priv {
672677
/* Admin queue - see gve_adminq.h*/
673678
union gve_adminq_command *adminq;
674679
dma_addr_t adminq_bus_addr;
680+
struct dma_pool *adminq_pool;
675681
u32 adminq_mask; /* masks prod_cnt to adminq size */
676682
u32 adminq_prod_cnt; /* free-running count of AQ cmds executed */
677683
u32 adminq_cmd_fail; /* free-running count of AQ cmds failed */

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

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,19 @@ gve_process_device_options(struct gve_priv *priv,
194194

195195
int gve_adminq_alloc(struct device *dev, struct gve_priv *priv)
196196
{
197-
priv->adminq = dma_alloc_coherent(dev, PAGE_SIZE,
198-
&priv->adminq_bus_addr, GFP_KERNEL);
199-
if (unlikely(!priv->adminq))
197+
priv->adminq_pool = dma_pool_create("adminq_pool", dev,
198+
GVE_ADMINQ_BUFFER_SIZE, 0, 0);
199+
if (unlikely(!priv->adminq_pool))
200200
return -ENOMEM;
201+
priv->adminq = dma_pool_alloc(priv->adminq_pool, GFP_KERNEL,
202+
&priv->adminq_bus_addr);
203+
if (unlikely(!priv->adminq)) {
204+
dma_pool_destroy(priv->adminq_pool);
205+
return -ENOMEM;
206+
}
201207

202-
priv->adminq_mask = (PAGE_SIZE / sizeof(union gve_adminq_command)) - 1;
208+
priv->adminq_mask =
209+
(GVE_ADMINQ_BUFFER_SIZE / sizeof(union gve_adminq_command)) - 1;
203210
priv->adminq_prod_cnt = 0;
204211
priv->adminq_cmd_fail = 0;
205212
priv->adminq_timeouts = 0;
@@ -218,9 +225,20 @@ int gve_adminq_alloc(struct device *dev, struct gve_priv *priv)
218225
priv->adminq_get_ptype_map_cnt = 0;
219226

220227
/* Setup Admin queue with the device */
221-
iowrite32be(priv->adminq_bus_addr / PAGE_SIZE,
222-
&priv->reg_bar0->adminq_pfn);
223-
228+
if (priv->pdev->revision < 0x1) {
229+
iowrite32be(priv->adminq_bus_addr / PAGE_SIZE,
230+
&priv->reg_bar0->adminq_pfn);
231+
} else {
232+
iowrite16be(GVE_ADMINQ_BUFFER_SIZE,
233+
&priv->reg_bar0->adminq_length);
234+
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
235+
iowrite32be(priv->adminq_bus_addr >> 32,
236+
&priv->reg_bar0->adminq_base_address_hi);
237+
#endif
238+
iowrite32be(priv->adminq_bus_addr,
239+
&priv->reg_bar0->adminq_base_address_lo);
240+
iowrite32be(GVE_DRIVER_STATUS_RUN_MASK, &priv->reg_bar0->driver_status);
241+
}
224242
gve_set_admin_queue_ok(priv);
225243
return 0;
226244
}
@@ -230,16 +248,27 @@ void gve_adminq_release(struct gve_priv *priv)
230248
int i = 0;
231249

232250
/* Tell the device the adminq is leaving */
233-
iowrite32be(0x0, &priv->reg_bar0->adminq_pfn);
234-
while (ioread32be(&priv->reg_bar0->adminq_pfn)) {
235-
/* If this is reached the device is unrecoverable and still
236-
* holding memory. Continue looping to avoid memory corruption,
237-
* but WARN so it is visible what is going on.
238-
*/
239-
if (i == GVE_MAX_ADMINQ_RELEASE_CHECK)
240-
WARN(1, "Unrecoverable platform error!");
241-
i++;
242-
msleep(GVE_ADMINQ_SLEEP_LEN);
251+
if (priv->pdev->revision < 0x1) {
252+
iowrite32be(0x0, &priv->reg_bar0->adminq_pfn);
253+
while (ioread32be(&priv->reg_bar0->adminq_pfn)) {
254+
/* If this is reached the device is unrecoverable and still
255+
* holding memory. Continue looping to avoid memory corruption,
256+
* but WARN so it is visible what is going on.
257+
*/
258+
if (i == GVE_MAX_ADMINQ_RELEASE_CHECK)
259+
WARN(1, "Unrecoverable platform error!");
260+
i++;
261+
msleep(GVE_ADMINQ_SLEEP_LEN);
262+
}
263+
} else {
264+
iowrite32be(GVE_DRIVER_STATUS_RESET_MASK, &priv->reg_bar0->driver_status);
265+
while (!(ioread32be(&priv->reg_bar0->device_status)
266+
& GVE_DEVICE_STATUS_DEVICE_IS_RESET)) {
267+
if (i == GVE_MAX_ADMINQ_RELEASE_CHECK)
268+
WARN(1, "Unrecoverable platform error!");
269+
i++;
270+
msleep(GVE_ADMINQ_SLEEP_LEN);
271+
}
243272
}
244273
gve_clear_device_rings_ok(priv);
245274
gve_clear_device_resources_ok(priv);
@@ -251,7 +280,8 @@ void gve_adminq_free(struct device *dev, struct gve_priv *priv)
251280
if (!gve_get_admin_queue_ok(priv))
252281
return;
253282
gve_adminq_release(priv);
254-
dma_free_coherent(dev, PAGE_SIZE, priv->adminq, priv->adminq_bus_addr);
283+
dma_pool_free(priv->adminq_pool, priv->adminq, priv->adminq_bus_addr);
284+
dma_pool_destroy(priv->adminq_pool);
255285
gve_clear_admin_queue_ok(priv);
256286
}
257287

@@ -697,18 +727,7 @@ static int gve_set_desc_cnt(struct gve_priv *priv,
697727
struct gve_device_descriptor *descriptor)
698728
{
699729
priv->tx_desc_cnt = be16_to_cpu(descriptor->tx_queue_entries);
700-
if (priv->tx_desc_cnt * sizeof(priv->tx->desc[0]) < PAGE_SIZE) {
701-
dev_err(&priv->pdev->dev, "Tx desc count %d too low\n",
702-
priv->tx_desc_cnt);
703-
return -EINVAL;
704-
}
705730
priv->rx_desc_cnt = be16_to_cpu(descriptor->rx_queue_entries);
706-
if (priv->rx_desc_cnt * sizeof(priv->rx->desc.desc_ring[0])
707-
< PAGE_SIZE) {
708-
dev_err(&priv->pdev->dev, "Rx desc count %d too low\n",
709-
priv->rx_desc_cnt);
710-
return -EINVAL;
711-
}
712731
return 0;
713732
}
714733

@@ -778,16 +797,17 @@ int gve_adminq_describe_device(struct gve_priv *priv)
778797
u16 mtu;
779798

780799
memset(&cmd, 0, sizeof(cmd));
781-
descriptor = dma_alloc_coherent(&priv->pdev->dev, PAGE_SIZE,
782-
&descriptor_bus, GFP_KERNEL);
800+
descriptor = dma_pool_alloc(priv->adminq_pool, GFP_KERNEL,
801+
&descriptor_bus);
783802
if (!descriptor)
784803
return -ENOMEM;
785804
cmd.opcode = cpu_to_be32(GVE_ADMINQ_DESCRIBE_DEVICE);
786805
cmd.describe_device.device_descriptor_addr =
787806
cpu_to_be64(descriptor_bus);
788807
cmd.describe_device.device_descriptor_version =
789808
cpu_to_be32(GVE_ADMINQ_DEVICE_DESCRIPTOR_VERSION);
790-
cmd.describe_device.available_length = cpu_to_be32(PAGE_SIZE);
809+
cmd.describe_device.available_length =
810+
cpu_to_be32(GVE_ADMINQ_BUFFER_SIZE);
791811

792812
err = gve_adminq_execute_cmd(priv, &cmd);
793813
if (err)
@@ -868,8 +888,7 @@ int gve_adminq_describe_device(struct gve_priv *priv)
868888
dev_op_jumbo_frames, dev_op_dqo_qpl);
869889

870890
free_device_descriptor:
871-
dma_free_coherent(&priv->pdev->dev, PAGE_SIZE, descriptor,
872-
descriptor_bus);
891+
dma_pool_free(priv->adminq_pool, descriptor, descriptor_bus);
873892
return err;
874893
}
875894

@@ -898,6 +917,7 @@ int gve_adminq_register_page_list(struct gve_priv *priv,
898917
.page_list_id = cpu_to_be32(qpl->id),
899918
.num_pages = cpu_to_be32(num_entries),
900919
.page_address_list_addr = cpu_to_be64(page_list_bus),
920+
.page_size = cpu_to_be64(PAGE_SIZE),
901921
};
902922

903923
err = gve_adminq_execute_cmd(priv, &cmd);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,10 @@ struct gve_adminq_register_page_list {
219219
__be32 page_list_id;
220220
__be32 num_pages;
221221
__be64 page_address_list_addr;
222+
__be64 page_size;
222223
};
223224

224-
static_assert(sizeof(struct gve_adminq_register_page_list) == 16);
225+
static_assert(sizeof(struct gve_adminq_register_page_list) == 24);
225226

226227
struct gve_adminq_unregister_page_list {
227228
__be32 page_list_id;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ static int gve_set_tunable(struct net_device *netdev,
519519
case ETHTOOL_RX_COPYBREAK:
520520
{
521521
u32 max_copybreak = gve_is_gqi(priv) ?
522-
(PAGE_SIZE / 2) : priv->data_buffer_size_dqo;
522+
GVE_DEFAULT_RX_BUFFER_SIZE : priv->data_buffer_size_dqo;
523523

524524
len = *(u32 *)value;
525525
if (len > max_copybreak)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ static int gve_open(struct net_device *dev)
13281328
/* Hard code this for now. This may be tuned in the future for
13291329
* performance.
13301330
*/
1331-
priv->data_buffer_size_dqo = GVE_RX_BUFFER_SIZE_DQO;
1331+
priv->data_buffer_size_dqo = GVE_DEFAULT_RX_BUFFER_SIZE;
13321332
}
13331333
err = gve_create_rings(priv);
13341334
if (err)
@@ -1664,7 +1664,7 @@ static int verify_xdp_configuration(struct net_device *dev)
16641664
return -EOPNOTSUPP;
16651665
}
16661666

1667-
if (dev->mtu > (PAGE_SIZE / 2) - sizeof(struct ethhdr) - GVE_RX_PAD) {
1667+
if (dev->mtu > GVE_DEFAULT_RX_BUFFER_SIZE - sizeof(struct ethhdr) - GVE_RX_PAD) {
16681668
netdev_warn(dev, "XDP is not supported for mtu %d.\n",
16691669
dev->mtu);
16701670
return -EOPNOTSUPP;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,20 @@ struct gve_registers {
1818
__be32 adminq_event_counter;
1919
u8 reserved[3];
2020
u8 driver_version;
21+
__be32 adminq_base_address_hi;
22+
__be32 adminq_base_address_lo;
23+
__be16 adminq_length;
2124
};
2225

2326
enum gve_device_status_flags {
2427
GVE_DEVICE_STATUS_RESET_MASK = BIT(1),
2528
GVE_DEVICE_STATUS_LINK_STATUS_MASK = BIT(2),
2629
GVE_DEVICE_STATUS_REPORT_STATS_MASK = BIT(3),
30+
GVE_DEVICE_STATUS_DEVICE_IS_RESET = BIT(4),
31+
};
32+
33+
enum gve_driver_status_flags {
34+
GVE_DRIVER_STATUS_RUN_MASK = BIT(0),
35+
GVE_DRIVER_STATUS_RESET_MASK = BIT(1),
2736
};
2837
#endif /* _GVE_REGISTER_H_ */

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ static int gve_rx_alloc_ring(struct gve_priv *priv, int idx)
211211
{
212212
struct gve_rx_ring *rx = &priv->rx[idx];
213213
struct device *hdev = &priv->pdev->dev;
214-
u32 slots, npages;
215214
int filled_pages;
216215
size_t bytes;
216+
u32 slots;
217217
int err;
218218

219219
netif_dbg(priv, drv, priv->dev, "allocating rx ring\n");
@@ -270,12 +270,6 @@ static int gve_rx_alloc_ring(struct gve_priv *priv, int idx)
270270

271271
/* alloc rx desc ring */
272272
bytes = sizeof(struct gve_rx_desc) * priv->rx_desc_cnt;
273-
npages = bytes / PAGE_SIZE;
274-
if (npages * PAGE_SIZE != bytes) {
275-
err = -EIO;
276-
goto abort_with_q_resources;
277-
}
278-
279273
rx->desc.desc_ring = dma_alloc_coherent(hdev, bytes, &rx->desc.bus,
280274
GFP_KERNEL);
281275
if (!rx->desc.desc_ring) {
@@ -289,7 +283,7 @@ static int gve_rx_alloc_ring(struct gve_priv *priv, int idx)
289283
/* Allocating half-page buffers allows page-flipping which is faster
290284
* than copying or allocating new pages.
291285
*/
292-
rx->packet_buffer_size = PAGE_SIZE / 2;
286+
rx->packet_buffer_size = GVE_DEFAULT_RX_BUFFER_SIZE;
293287
gve_rx_ctx_clear(&rx->ctx);
294288
gve_rx_add_to_block(priv, idx);
295289

@@ -405,10 +399,10 @@ static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi,
405399

406400
static void gve_rx_flip_buff(struct gve_rx_slot_page_info *page_info, __be64 *slot_addr)
407401
{
408-
const __be64 offset = cpu_to_be64(PAGE_SIZE / 2);
402+
const __be64 offset = cpu_to_be64(GVE_DEFAULT_RX_BUFFER_OFFSET);
409403

410404
/* "flip" to other packet buffer on this page */
411-
page_info->page_offset ^= PAGE_SIZE / 2;
405+
page_info->page_offset ^= GVE_DEFAULT_RX_BUFFER_OFFSET;
412406
*(slot_addr) ^= offset;
413407
}
414408

@@ -513,8 +507,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx,
513507
return NULL;
514508

515509
gve_dec_pagecnt_bias(copy_page_info);
516-
copy_page_info->page_offset += rx->packet_buffer_size;
517-
copy_page_info->page_offset &= (PAGE_SIZE - 1);
510+
copy_page_info->page_offset ^= GVE_DEFAULT_RX_BUFFER_OFFSET;
518511

519512
if (copy_page_info->can_flip) {
520513
/* We have used both halves of this copy page, it

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ int gve_xdp_xmit_one(struct gve_priv *priv, struct gve_tx_ring *tx,
819819
return 0;
820820
}
821821

822-
#define GVE_TX_START_THRESH PAGE_SIZE
822+
#define GVE_TX_START_THRESH 4096
823823

824824
static int gve_clean_tx_done(struct gve_priv *priv, struct gve_tx_ring *tx,
825825
u32 to_do, bool try_to_wake)

0 commit comments

Comments
 (0)