summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAditya Garg <gargaditya@linux.microsoft.com>2026-08-07 13:56:36 -0700
committerPaolo Abeni <pabeni@redhat.com>2026-08-13 13:42:48 +0200
commit23adfc77c22cb959ac84e08dc8a77bac656f1caa (patch)
treea91df54b31dc49bc9d158dcb838daaa60f882d07 /include
parent1da1a037bc60c3744a6cdcb7610917a20ba1a318 (diff)
downloadlinux-23adfc77c22cb959ac84e08dc8a77bac656f1caa.tar.gz
linux-23adfc77c22cb959ac84e08dc8a77bac656f1caa.zip
net: mana: Fall back to scattered pages for GDMA queues
Each GDMA queue ring is one dma_alloc_coherent() of the whole ring size. Such high-order allocations fail first under memory fragmentation, so queue setup can fail with memory still free. The hardware does not need the ring physically contiguous: mana_gd_create_dma_region() already maps it as a list of MANA_PAGE_SIZE (4K) device addresses. Only the driver's linear CPU view needs contiguity, and it goes through mana_gd_ring_ptr() and mana_gd_ring_contig_avail(); change both to map offsets onto scattered pages. Add a fallback in mana_gd_alloc_memory(): data-path queues pass allow_scatter=true, so when the contiguous allocation fails the ring is backed by a vector of scattered PAGE_SIZE (order-0) coherent pages, presenting the same DMA page-list layout to the device. The HW channel bootstrap keeps allow_scatter=false, and the debugfs ring dumper reads scattered rings through the same helpers. Signed-off-by: Aditya Garg <gargaditya@linux.microsoft.com> Link: https://patch.msgid.link/20260807210002.1695263-3-gargaditya@linux.microsoft.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/net/mana/gdma.h19
1 files changed, 17 insertions, 2 deletions
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 70a7f1fee5d3..9d57a0ea0e5e 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -241,6 +241,14 @@ struct gdma_mem_info {
void *virt_addr;
u64 length;
+ /* Scattered fallback: when @nr_pages > 0 the ring is that many
+ * PAGE_SIZE coherent allocations in @pages_va/@pages_dma, not
+ * @virt_addr/@dma_handle.
+ */
+ void **pages_va;
+ dma_addr_t *pages_dma;
+ unsigned int nr_pages;
+
/* Allocated by the PF driver */
u64 dma_region_handle;
};
@@ -516,6 +524,9 @@ int mana_gd_poll_cq(struct gdma_queue *cq, struct gdma_comp *comp, int num_cqe);
void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit);
+ssize_t mana_gd_read_ring(struct gdma_queue *q, char __user *buf,
+ size_t count, loff_t *pos);
+
int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type);
void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld,
@@ -672,6 +683,9 @@ enum {
/* Driver supports dynamic interrupt moderation - DIM */
#define GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(28)
+/* Driver supports non-contiguous queue buffers */
+#define GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS BIT(30)
+
#define GDMA_DRV_CAP_FLAGS1 \
(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
@@ -688,7 +702,8 @@ enum {
GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT | \
- GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION)
+ GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION | \
+ GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS)
#define GDMA_DRV_CAP_FLAGS2 0
@@ -1049,7 +1064,7 @@ void mana_gd_wq_ring_doorbell(struct gdma_context *gc,
struct gdma_queue *queue);
int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length,
- struct gdma_mem_info *gmi);
+ struct gdma_mem_info *gmi, bool allow_scatter);
void mana_gd_free_memory(struct gdma_mem_info *gmi);