From 955f4d3bf0a454bc76c6393d74d844556d61b520 Mon Sep 17 00:00:00 2001 From: John Fraker Date: Mon, 27 Nov 2023 16:26:44 -0800 Subject: gve: Perform adminq allocations through a dma_pool. This allows the adminq to be smaller than a page, paving the way for non 4k page support. This is to support platforms where PAGE_SIZE is not 4k, such as some ARM platforms. Signed-off-by: Jordan Kimbrough Signed-off-by: John Fraker Reviewed-by: Willem de Bruijn Link: https://lore.kernel.org/r/20231128002648.320892-2-jfraker@google.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/google/gve/gve.h | 4 ++++ drivers/net/ethernet/google/gve/gve_adminq.c | 28 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers/net/ethernet/google') diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h index 0d1e681be250..abc0c708b47a 100644 --- a/drivers/net/ethernet/google/gve/gve.h +++ b/drivers/net/ethernet/google/gve/gve.h @@ -8,6 +8,7 @@ #define _GVE_H_ #include +#include #include #include #include @@ -41,6 +42,8 @@ #define NIC_TX_STATS_REPORT_NUM 0 #define NIC_RX_STATS_REPORT_NUM 4 +#define GVE_ADMINQ_BUFFER_SIZE 4096 + #define GVE_DATA_SLOT_ADDR_PAGE_MASK (~(PAGE_SIZE - 1)) /* PTYPEs are always 10 bits. */ @@ -672,6 +675,7 @@ struct gve_priv { /* Admin queue - see gve_adminq.h*/ union gve_adminq_command *adminq; dma_addr_t adminq_bus_addr; + struct dma_pool *adminq_pool; u32 adminq_mask; /* masks prod_cnt to adminq size */ u32 adminq_prod_cnt; /* free-running count of AQ cmds executed */ u32 adminq_cmd_fail; /* free-running count of AQ cmds failed */ diff --git a/drivers/net/ethernet/google/gve/gve_adminq.c b/drivers/net/ethernet/google/gve/gve_adminq.c index 79db7a6d42bc..d3f3a015238d 100644 --- a/drivers/net/ethernet/google/gve/gve_adminq.c +++ b/drivers/net/ethernet/google/gve/gve_adminq.c @@ -194,12 +194,19 @@ gve_process_device_options(struct gve_priv *priv, int gve_adminq_alloc(struct device *dev, struct gve_priv *priv) { - priv->adminq = dma_alloc_coherent(dev, PAGE_SIZE, - &priv->adminq_bus_addr, GFP_KERNEL); - if (unlikely(!priv->adminq)) + priv->adminq_pool = dma_pool_create("adminq_pool", dev, + GVE_ADMINQ_BUFFER_SIZE, 0, 0); + if (unlikely(!priv->adminq_pool)) return -ENOMEM; + priv->adminq = dma_pool_alloc(priv->adminq_pool, GFP_KERNEL, + &priv->adminq_bus_addr); + if (unlikely(!priv->adminq)) { + dma_pool_destroy(priv->adminq_pool); + return -ENOMEM; + } - priv->adminq_mask = (PAGE_SIZE / sizeof(union gve_adminq_command)) - 1; + priv->adminq_mask = + (GVE_ADMINQ_BUFFER_SIZE / sizeof(union gve_adminq_command)) - 1; priv->adminq_prod_cnt = 0; priv->adminq_cmd_fail = 0; priv->adminq_timeouts = 0; @@ -251,7 +258,8 @@ void gve_adminq_free(struct device *dev, struct gve_priv *priv) if (!gve_get_admin_queue_ok(priv)) return; gve_adminq_release(priv); - dma_free_coherent(dev, PAGE_SIZE, priv->adminq, priv->adminq_bus_addr); + dma_pool_free(priv->adminq_pool, priv->adminq, priv->adminq_bus_addr); + dma_pool_destroy(priv->adminq_pool); gve_clear_admin_queue_ok(priv); } @@ -778,8 +786,8 @@ int gve_adminq_describe_device(struct gve_priv *priv) u16 mtu; memset(&cmd, 0, sizeof(cmd)); - descriptor = dma_alloc_coherent(&priv->pdev->dev, PAGE_SIZE, - &descriptor_bus, GFP_KERNEL); + descriptor = dma_pool_alloc(priv->adminq_pool, GFP_KERNEL, + &descriptor_bus); if (!descriptor) return -ENOMEM; cmd.opcode = cpu_to_be32(GVE_ADMINQ_DESCRIBE_DEVICE); @@ -787,7 +795,8 @@ int gve_adminq_describe_device(struct gve_priv *priv) cpu_to_be64(descriptor_bus); cmd.describe_device.device_descriptor_version = cpu_to_be32(GVE_ADMINQ_DEVICE_DESCRIPTOR_VERSION); - cmd.describe_device.available_length = cpu_to_be32(PAGE_SIZE); + cmd.describe_device.available_length = + cpu_to_be32(GVE_ADMINQ_BUFFER_SIZE); err = gve_adminq_execute_cmd(priv, &cmd); if (err) @@ -868,8 +877,7 @@ int gve_adminq_describe_device(struct gve_priv *priv) dev_op_jumbo_frames, dev_op_dqo_qpl); free_device_descriptor: - dma_free_coherent(&priv->pdev->dev, PAGE_SIZE, descriptor, - descriptor_bus); + dma_pool_free(priv->adminq_pool, descriptor, descriptor_bus); return err; } -- cgit