Skip to content

Commit 4c2a132

Browse files
dtatuleaSaeed Mahameed
authored andcommitted
net/mlx5e: RX, Defer page release in striding rq for better recycling
Currently, for striding RQ, fragmented pages from the page pool can get released in two ways: 1) In the mlx5e driver when trimming off the unused fragments AND the associated skb fragments have been released. This path allows recycling of pages to the page pool cache (allow_direct == true). 2) On the skb release path (last fragment release), which will always release pages to the page pool ring (allow_direct == false). Whichever is releasing the last fragment will be decisive on where the page gets released: the cache or the ring. So we obviously want to maximize for doing the release from 1. This patch does that by deferring the release of page fragments right before requesting new ones from the page pool. Extra care needs to be taken for the corner cases: * On first call, make sure that release is not called. The skip_release_bitmap is used for this purpose. * On rq shutdown, make sure that all wqes that were not in the linked list are released. For a single ring, single core, default MTU (1500) TCP stream test the number of pages allocated from the cache directly (rx_pp_recycle_cached) increases from 31 % to 98 %: +----------------------------------------------+ | Page Pool stats (/sec) | Before | After | +-------------------------+---------+----------+ |rx_pp_alloc_fast | 2137754 | 2261033 | |rx_pp_alloc_slow | 47 | 9 | |rx_pp_alloc_empty | 47 | 9 | |rx_pp_alloc_refill | 23230 | 819 | |rx_pp_alloc_waive | 0 | 0 | |rx_pp_recycle_cached | 672182 | 2209015 | |rx_pp_recycle_cache_full | 1789 | 0 | |rx_pp_recycle_ring | 1485848 | 52259 | |rx_pp_recycle_ring_full | 3003 | 584 | +----------------------------------------------+ With this patch, the performance in striding rq for the above test is back to baseline. Signed-off-by: Dragos Tatulea <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 38a36ef commit 4c2a132

File tree

4 files changed

+25
-10
lines changed

4 files changed

+25
-10
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ static int mlx5e_rx_reporter_err_icosq_cqe_recover(void *ctx)
121121

122122
mlx5e_reset_icosq_cc_pc(icosq);
123123

124-
mlx5e_free_rx_in_progress_descs(rq);
124+
mlx5e_free_rx_missing_descs(rq);
125125
if (xskrq)
126-
mlx5e_free_rx_in_progress_descs(xskrq);
126+
mlx5e_free_rx_missing_descs(xskrq);
127127

128128
clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state);
129129
mlx5e_activate_icosq(icosq);

drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ INDIRECT_CALLABLE_DECLARE(bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq));
6969
INDIRECT_CALLABLE_DECLARE(bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq));
7070
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
7171
void mlx5e_free_rx_descs(struct mlx5e_rq *rq);
72-
void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq);
72+
void mlx5e_free_rx_missing_descs(struct mlx5e_rq *rq);
7373

7474
static inline bool mlx5e_rx_hw_stamp(struct hwtstamp_config *config)
7575
{

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,15 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq, int node)
301301
if (!rq->mpwqe.info)
302302
return -ENOMEM;
303303

304+
/* For deferred page release (release right before alloc), make sure
305+
* that on first round release is not called.
306+
*/
307+
for (int i = 0; i < wq_sz; i++) {
308+
struct mlx5e_mpw_info *wi = mlx5e_get_mpw_info(rq, i);
309+
310+
bitmap_fill(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe);
311+
}
312+
304313
mlx5e_build_umr_wqe(rq, rq->icosq, &rq->mpwqe.umr_wqe);
305314

306315
return 0;
@@ -1112,7 +1121,7 @@ int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time)
11121121
return -ETIMEDOUT;
11131122
}
11141123

1115-
void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq)
1124+
void mlx5e_free_rx_missing_descs(struct mlx5e_rq *rq)
11161125
{
11171126
struct mlx5_wq_ll *wq;
11181127
u16 head;
@@ -1124,8 +1133,12 @@ void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq)
11241133
wq = &rq->mpwqe.wq;
11251134
head = wq->head;
11261135

1127-
/* Outstanding UMR WQEs (in progress) start at wq->head */
1128-
for (i = 0; i < rq->mpwqe.umr_in_progress; i++) {
1136+
/* Release WQEs that are in missing state: they have been
1137+
* popped from the list after completion but were not freed
1138+
* due to deferred release.
1139+
* Also free the linked-list reserved entry, hence the "+ 1".
1140+
*/
1141+
for (i = 0; i < mlx5_wq_ll_missing(wq) + 1; i++) {
11291142
rq->dealloc_wqe(rq, head);
11301143
head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
11311144
}
@@ -1152,7 +1165,7 @@ void mlx5e_free_rx_descs(struct mlx5e_rq *rq)
11521165
if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
11531166
struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
11541167

1155-
mlx5e_free_rx_in_progress_descs(rq);
1168+
mlx5e_free_rx_missing_descs(rq);
11561169

11571170
while (!mlx5_wq_ll_is_empty(wq)) {
11581171
struct mlx5e_rx_wqe_ll *wqe;

drivers/net/ethernet/mellanox/mlx5/core/en_rx.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,11 @@ INDIRECT_CALLABLE_SCOPE bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
983983
head = rq->mpwqe.actual_wq_head;
984984
i = missing;
985985
do {
986+
struct mlx5e_mpw_info *wi = mlx5e_get_mpw_info(rq, head);
987+
988+
/* Deferred free for better page pool cache usage. */
989+
mlx5e_free_rx_mpwqe(rq, wi, true);
990+
986991
alloc_err = rq->xsk_pool ? mlx5e_xsk_alloc_rx_mpwqe(rq, head) :
987992
mlx5e_alloc_rx_mpwqe(rq, head);
988993

@@ -1855,7 +1860,6 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64
18551860

18561861
wq = &rq->mpwqe.wq;
18571862
wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
1858-
mlx5e_free_rx_mpwqe(rq, wi, true);
18591863
mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index);
18601864
}
18611865

@@ -2173,7 +2177,6 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
21732177

21742178
wq = &rq->mpwqe.wq;
21752179
wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
2176-
mlx5e_free_rx_mpwqe(rq, wi, true);
21772180
mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index);
21782181
}
21792182

@@ -2233,7 +2236,6 @@ static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cq
22332236

22342237
wq = &rq->mpwqe.wq;
22352238
wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
2236-
mlx5e_free_rx_mpwqe(rq, wi, true);
22372239
mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index);
22382240
}
22392241

0 commit comments

Comments
 (0)