Commit ca6ef9f0 authored by Dragos Tatulea's avatar Dragos Tatulea Committed by Saeed Mahameed

net/mlx5e: RX, Store SHAMPO header pages in array

Save allocated SHAMPO header pages to an array to which the
mlx5e_dma_info page will point to.

This change is a preparation for introducing mlx5e_frag_page structure
in a downstream patch. There's no new functionality introduced.
Signed-off-by: default avatarDragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent d39092ca
...@@ -670,13 +670,17 @@ struct mlx5e_rq_frags_info { ...@@ -670,13 +670,17 @@ struct mlx5e_rq_frags_info {
struct mlx5e_dma_info { struct mlx5e_dma_info {
dma_addr_t addr; dma_addr_t addr;
struct page *page; union {
struct page **pagep;
struct page *page;
};
}; };
struct mlx5e_shampo_hd { struct mlx5e_shampo_hd {
u32 mkey; u32 mkey;
struct mlx5e_dma_info *info; struct mlx5e_dma_info *info;
struct page *last_page; struct page **pages;
u16 curr_page_index;
u16 hd_per_wq; u16 hd_per_wq;
u16 hd_per_wqe; u16 hd_per_wqe;
unsigned long *bitmap; unsigned long *bitmap;
......
...@@ -262,23 +262,30 @@ static int mlx5e_rq_shampo_hd_info_alloc(struct mlx5e_rq *rq, int node) ...@@ -262,23 +262,30 @@ static int mlx5e_rq_shampo_hd_info_alloc(struct mlx5e_rq *rq, int node)
shampo->bitmap = bitmap_zalloc_node(shampo->hd_per_wq, GFP_KERNEL, shampo->bitmap = bitmap_zalloc_node(shampo->hd_per_wq, GFP_KERNEL,
node); node);
if (!shampo->bitmap)
return -ENOMEM;
shampo->info = kvzalloc_node(array_size(shampo->hd_per_wq, shampo->info = kvzalloc_node(array_size(shampo->hd_per_wq,
sizeof(*shampo->info)), sizeof(*shampo->info)),
GFP_KERNEL, node); GFP_KERNEL, node);
if (!shampo->info) { shampo->pages = kvzalloc_node(array_size(shampo->hd_per_wq,
kvfree(shampo->bitmap); sizeof(*shampo->pages)),
return -ENOMEM; GFP_KERNEL, node);
} if (!shampo->bitmap || !shampo->info || !shampo->pages)
goto err_nomem;
return 0; return 0;
err_nomem:
kvfree(shampo->info);
kvfree(shampo->bitmap);
kvfree(shampo->pages);
return -ENOMEM;
} }
static void mlx5e_rq_shampo_hd_info_free(struct mlx5e_rq *rq) static void mlx5e_rq_shampo_hd_info_free(struct mlx5e_rq *rq)
{ {
kvfree(rq->mpwqe.shampo->bitmap); kvfree(rq->mpwqe.shampo->bitmap);
kvfree(rq->mpwqe.shampo->info); kvfree(rq->mpwqe.shampo->info);
kvfree(rq->mpwqe.shampo->pages);
} }
static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int node) static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int node)
......
...@@ -586,10 +586,11 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, ...@@ -586,10 +586,11 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;
u16 entries, pi, header_offset, err, wqe_bbs, new_entries; u16 entries, pi, header_offset, err, wqe_bbs, new_entries;
u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey; u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey;
struct page *page = shampo->last_page; u16 page_index = shampo->curr_page_index;
u64 addr = shampo->last_addr; u64 addr = shampo->last_addr;
struct mlx5e_dma_info *dma_info; struct mlx5e_dma_info *dma_info;
struct mlx5e_umr_wqe *umr_wqe; struct mlx5e_umr_wqe *umr_wqe;
struct page **pagep;
int headroom, i; int headroom, i;
headroom = rq->buff.headroom; headroom = rq->buff.headroom;
...@@ -600,6 +601,8 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, ...@@ -600,6 +601,8 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
umr_wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi); umr_wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi);
build_klm_umr(sq, umr_wqe, shampo->key, index, entries, wqe_bbs); build_klm_umr(sq, umr_wqe, shampo->key, index, entries, wqe_bbs);
pagep = &shampo->pages[page_index];
for (i = 0; i < entries; i++, index++) { for (i = 0; i < entries; i++, index++) {
dma_info = &shampo->info[index]; dma_info = &shampo->info[index];
if (i >= klm_entries || (index < shampo->pi && shampo->pi - index < if (i >= klm_entries || (index < shampo->pi && shampo->pi - index <
...@@ -608,17 +611,20 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, ...@@ -608,17 +611,20 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
header_offset = (index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) << header_offset = (index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) <<
MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE; MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE;
if (!(header_offset & (PAGE_SIZE - 1))) { if (!(header_offset & (PAGE_SIZE - 1))) {
page_index = (page_index + 1) & (shampo->hd_per_wq - 1);
pagep = &shampo->pages[page_index];
err = mlx5e_page_alloc_pool(rq, &page); err = mlx5e_page_alloc_pool(rq, pagep);
if (unlikely(err)) if (unlikely(err))
goto err_unmap; goto err_unmap;
addr = page_pool_get_dma_addr(page); addr = page_pool_get_dma_addr(*pagep);
dma_info->addr = addr; dma_info->addr = addr;
dma_info->page = page; dma_info->pagep = pagep;
} else { } else {
dma_info->addr = addr + header_offset; dma_info->addr = addr + header_offset;
dma_info->page = page; dma_info->pagep = pagep;
} }
update_klm: update_klm:
...@@ -636,7 +642,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, ...@@ -636,7 +642,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
}; };
shampo->pi = (shampo->pi + new_entries) & (shampo->hd_per_wq - 1); shampo->pi = (shampo->pi + new_entries) & (shampo->hd_per_wq - 1);
shampo->last_page = page; shampo->curr_page_index = page_index;
shampo->last_addr = addr; shampo->last_addr = addr;
sq->pc += wqe_bbs; sq->pc += wqe_bbs;
sq->doorbell_cseg = &umr_wqe->ctrl; sq->doorbell_cseg = &umr_wqe->ctrl;
...@@ -648,7 +654,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, ...@@ -648,7 +654,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
dma_info = &shampo->info[--index]; dma_info = &shampo->info[--index];
if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1))) { if (!(i & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1))) {
dma_info->addr = ALIGN_DOWN(dma_info->addr, PAGE_SIZE); dma_info->addr = ALIGN_DOWN(dma_info->addr, PAGE_SIZE);
mlx5e_page_release_dynamic(rq, dma_info->page, true); mlx5e_page_release_dynamic(rq, *dma_info->pagep, true);
} }
} }
rq->stats->buff_alloc_err++; rq->stats->buff_alloc_err++;
...@@ -783,7 +789,7 @@ void mlx5e_shampo_dealloc_hd(struct mlx5e_rq *rq, u16 len, u16 start, bool close ...@@ -783,7 +789,7 @@ void mlx5e_shampo_dealloc_hd(struct mlx5e_rq *rq, u16 len, u16 start, bool close
{ {
struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;
int hd_per_wq = shampo->hd_per_wq; int hd_per_wq = shampo->hd_per_wq;
struct page *deleted_page = NULL; struct page **deleted_page = NULL;
struct mlx5e_dma_info *hd_info; struct mlx5e_dma_info *hd_info;
int i, index = start; int i, index = start;
...@@ -796,9 +802,9 @@ void mlx5e_shampo_dealloc_hd(struct mlx5e_rq *rq, u16 len, u16 start, bool close ...@@ -796,9 +802,9 @@ void mlx5e_shampo_dealloc_hd(struct mlx5e_rq *rq, u16 len, u16 start, bool close
hd_info = &shampo->info[index]; hd_info = &shampo->info[index];
hd_info->addr = ALIGN_DOWN(hd_info->addr, PAGE_SIZE); hd_info->addr = ALIGN_DOWN(hd_info->addr, PAGE_SIZE);
if (hd_info->page != deleted_page) { if (hd_info->pagep != deleted_page) {
deleted_page = hd_info->page; deleted_page = hd_info->pagep;
mlx5e_page_release_dynamic(rq, hd_info->page, false); mlx5e_page_release_dynamic(rq, *hd_info->pagep, false);
} }
} }
...@@ -1137,7 +1143,7 @@ static void *mlx5e_shampo_get_packet_hd(struct mlx5e_rq *rq, u16 header_index) ...@@ -1137,7 +1143,7 @@ static void *mlx5e_shampo_get_packet_hd(struct mlx5e_rq *rq, u16 header_index)
struct mlx5e_dma_info *last_head = &rq->mpwqe.shampo->info[header_index]; struct mlx5e_dma_info *last_head = &rq->mpwqe.shampo->info[header_index];
u16 head_offset = (last_head->addr & (PAGE_SIZE - 1)) + rq->buff.headroom; u16 head_offset = (last_head->addr & (PAGE_SIZE - 1)) + rq->buff.headroom;
return page_address(last_head->page) + head_offset; return page_address(*last_head->pagep) + head_offset;
} }
static void mlx5e_shampo_update_ipv4_udp_hdr(struct mlx5e_rq *rq, struct iphdr *ipv4) static void mlx5e_shampo_update_ipv4_udp_hdr(struct mlx5e_rq *rq, struct iphdr *ipv4)
...@@ -2048,7 +2054,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, ...@@ -2048,7 +2054,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
void *hdr, *data; void *hdr, *data;
u32 frag_size; u32 frag_size;
hdr = page_address(head->page) + head_offset; hdr = page_address(*head->pagep) + head_offset;
data = hdr + rx_headroom; data = hdr + rx_headroom;
frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + head_size); frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + head_size);
...@@ -2063,7 +2069,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, ...@@ -2063,7 +2069,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
return NULL; return NULL;
/* queue up for recycling/reuse */ /* queue up for recycling/reuse */
page_ref_inc(head->page); page_ref_inc(*head->pagep);
} else { } else {
/* allocate SKB and copy header for large header */ /* allocate SKB and copy header for large header */
...@@ -2076,7 +2082,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, ...@@ -2076,7 +2082,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
} }
prefetchw(skb->data); prefetchw(skb->data);
mlx5e_copy_skb_header(rq, skb, head->page, head->addr, mlx5e_copy_skb_header(rq, skb, *head->pagep, head->addr,
head_offset + rx_headroom, head_offset + rx_headroom,
rx_headroom, head_size); rx_headroom, head_size);
/* skb linear part was allocated with headlen and aligned to long */ /* skb linear part was allocated with headlen and aligned to long */
...@@ -2127,8 +2133,10 @@ mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index) ...@@ -2127,8 +2133,10 @@ mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index)
u64 addr = shampo->info[header_index].addr; u64 addr = shampo->info[header_index].addr;
if (((header_index + 1) & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) == 0) { if (((header_index + 1) & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) == 0) {
shampo->info[header_index].addr = ALIGN_DOWN(addr, PAGE_SIZE); struct mlx5e_dma_info *dma_info = &shampo->info[header_index];
mlx5e_page_release_dynamic(rq, shampo->info[header_index].page, true);
dma_info->addr = ALIGN_DOWN(addr, PAGE_SIZE);
mlx5e_page_release_dynamic(rq, *dma_info->pagep, true);
} }
bitmap_clear(shampo->bitmap, header_index, 1); bitmap_clear(shampo->bitmap, header_index, 1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment