Commit 3b959424 authored by Haiyang Zhang's avatar Haiyang Zhang Committed by Wen Zhiwei
Browse files

net: mana: Add support for page sizes other than 4KB on ARM64

stable inclusion
from stable-v6.6.55
commit 6c95c700f2b6bade6460b2edaeb9a88724575e0c
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IB0MX4

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6c95c700f2b6bade6460b2edaeb9a88724575e0c



--------------------------------

[ Upstream commit 382d1741b5b2feffef7942dd074206372afe1a96 ]

As defined by the MANA Hardware spec, the queue size for DMA is 4KB
minimal, and power of 2. And, the HWC queue size has to be exactly
4KB.

To support page sizes other than 4KB on ARM64, define the minimal
queue size as a macro separately from the PAGE_SIZE, which we always
assumed it to be 4KB before supporting ARM64.

Also, add MANA specific macros and update code related to size
alignment, DMA region calculations, etc.

Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: default avatarMichael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/1718655446-6576-1-git-send-email-haiyangz@microsoft.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Stable-dep-of: 9e517a8e9d9a ("RDMA/mana_ib: use the correct page table index based on hardware page size")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent 447d791f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ if NET_VENDOR_MICROSOFT
config MICROSOFT_MANA
	tristate "Microsoft Azure Network Adapter (MANA) support"
	depends on PCI_MSI
	depends on X86_64 || (ARM64 && !CPU_BIG_ENDIAN && ARM64_4K_PAGES)
	depends on X86_64 || (ARM64 && !CPU_BIG_ENDIAN)
	depends on PCI_HYPERV
	select AUXILIARY_BUS
	select PAGE_POOL
+5 −5
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length,
	dma_addr_t dma_handle;
	void *buf;

	if (length < PAGE_SIZE || !is_power_of_2(length))
	if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
		return -EINVAL;

	gmi->dev = gc->dev;
@@ -720,7 +720,7 @@ EXPORT_SYMBOL_NS(mana_gd_destroy_dma_region, NET_MANA);
static int mana_gd_create_dma_region(struct gdma_dev *gd,
				     struct gdma_mem_info *gmi)
{
	unsigned int num_page = gmi->length / PAGE_SIZE;
	unsigned int num_page = gmi->length / MANA_PAGE_SIZE;
	struct gdma_create_dma_region_req *req = NULL;
	struct gdma_create_dma_region_resp resp = {};
	struct gdma_context *gc = gd->gdma_context;
@@ -730,10 +730,10 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,
	int err;
	int i;

	if (length < PAGE_SIZE || !is_power_of_2(length))
	if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
		return -EINVAL;

	if (offset_in_page(gmi->virt_addr) != 0)
	if (!MANA_PAGE_ALIGNED(gmi->virt_addr))
		return -EINVAL;

	hwc = gc->hwc.driver_data;
@@ -754,7 +754,7 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,
	req->page_addr_list_len = num_page;

	for (i = 0; i < num_page; i++)
		req->page_addr_list[i] = gmi->dma_handle +  i * PAGE_SIZE;
		req->page_addr_list[i] = gmi->dma_handle +  i * MANA_PAGE_SIZE;

	err = mana_gd_send_request(gc, req_msg_size, req, sizeof(resp), &resp);
	if (err)
+7 −7
Original line number Diff line number Diff line
@@ -366,12 +366,12 @@ static int mana_hwc_create_cq(struct hw_channel_context *hwc, u16 q_depth,
	int err;

	eq_size = roundup_pow_of_two(GDMA_EQE_SIZE * q_depth);
	if (eq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
		eq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
	if (eq_size < MANA_MIN_QSIZE)
		eq_size = MANA_MIN_QSIZE;

	cq_size = roundup_pow_of_two(GDMA_CQE_SIZE * q_depth);
	if (cq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
		cq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
	if (cq_size < MANA_MIN_QSIZE)
		cq_size = MANA_MIN_QSIZE;

	hwc_cq = kzalloc(sizeof(*hwc_cq), GFP_KERNEL);
	if (!hwc_cq)
@@ -433,7 +433,7 @@ static int mana_hwc_alloc_dma_buf(struct hw_channel_context *hwc, u16 q_depth,

	dma_buf->num_reqs = q_depth;

	buf_size = PAGE_ALIGN(q_depth * max_msg_size);
	buf_size = MANA_PAGE_ALIGN(q_depth * max_msg_size);

	gmi = &dma_buf->mem_info;
	err = mana_gd_alloc_memory(gc, buf_size, gmi);
@@ -501,8 +501,8 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc,
	else
		queue_size = roundup_pow_of_two(GDMA_MAX_SQE_SIZE * q_depth);

	if (queue_size < MINIMUM_SUPPORTED_PAGE_SIZE)
		queue_size = MINIMUM_SUPPORTED_PAGE_SIZE;
	if (queue_size < MANA_MIN_QSIZE)
		queue_size = MANA_MIN_QSIZE;

	hwc_wq = kzalloc(sizeof(*hwc_wq), GFP_KERNEL);
	if (!hwc_wq)
+4 −4
Original line number Diff line number Diff line
@@ -1902,10 +1902,10 @@ static int mana_create_txq(struct mana_port_context *apc,
	 *  to prevent overflow.
	 */
	txq_size = MAX_SEND_BUFFERS_PER_QUEUE * 32;
	BUILD_BUG_ON(!PAGE_ALIGNED(txq_size));
	BUILD_BUG_ON(!MANA_PAGE_ALIGNED(txq_size));

	cq_size = MAX_SEND_BUFFERS_PER_QUEUE * COMP_ENTRY_SIZE;
	cq_size = PAGE_ALIGN(cq_size);
	cq_size = MANA_PAGE_ALIGN(cq_size);

	gc = gd->gdma_context;

@@ -2203,8 +2203,8 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
	if (err)
		goto out;

	rq_size = PAGE_ALIGN(rq_size);
	cq_size = PAGE_ALIGN(cq_size);
	rq_size = MANA_PAGE_ALIGN(rq_size);
	cq_size = MANA_PAGE_ALIGN(cq_size);

	/* Create RQ */
	memset(&spec, 0, sizeof(spec));
+7 −6
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/io.h>
#include <linux/mm.h>

#include <net/mana/gdma.h>
#include <net/mana/shm_channel.h>

#define PAGE_FRAME_L48_WIDTH_BYTES 6
@@ -155,8 +156,8 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,
		return err;
	}

	if (!PAGE_ALIGNED(eq_addr) || !PAGE_ALIGNED(cq_addr) ||
	    !PAGE_ALIGNED(rq_addr) || !PAGE_ALIGNED(sq_addr))
	if (!MANA_PAGE_ALIGNED(eq_addr) || !MANA_PAGE_ALIGNED(cq_addr) ||
	    !MANA_PAGE_ALIGNED(rq_addr) || !MANA_PAGE_ALIGNED(sq_addr))
		return -EINVAL;

	if ((eq_msix_index & VECTOR_MASK) != eq_msix_index)
@@ -183,7 +184,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,

	/* EQ addr: low 48 bits of frame address */
	shmem = (u64 *)ptr;
	frame_addr = PHYS_PFN(eq_addr);
	frame_addr = MANA_PFN(eq_addr);
	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -191,7 +192,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,

	/* CQ addr: low 48 bits of frame address */
	shmem = (u64 *)ptr;
	frame_addr = PHYS_PFN(cq_addr);
	frame_addr = MANA_PFN(cq_addr);
	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -199,7 +200,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,

	/* RQ addr: low 48 bits of frame address */
	shmem = (u64 *)ptr;
	frame_addr = PHYS_PFN(rq_addr);
	frame_addr = MANA_PFN(rq_addr);
	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -207,7 +208,7 @@ int mana_smc_setup_hwc(struct shm_channel *sc, bool reset_vf, u64 eq_addr,

	/* SQ addr: low 48 bits of frame address */
	shmem = (u64 *)ptr;
	frame_addr = PHYS_PFN(sq_addr);
	frame_addr = MANA_PFN(sq_addr);
	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
Loading