From 6dca02092e195a3ecf16ed3449be0e74d1302e9a Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Fri, 9 Apr 2021 17:38:31 +0200 Subject: avf: avoid placeholder buffer alloc in datapath Type: improvement Change-Id: I0ad0fa42f056b5797ba71d6972a44273c13bb97e Signed-off-by: Damjan Marion --- src/plugins/avf/avf.h | 2 +- src/plugins/avf/device.c | 18 ++++++++++++------ src/plugins/avf/output.c | 36 ++++++++++++------------------------ 3 files changed, 25 insertions(+), 31 deletions(-) (limited to 'src/plugins/avf') diff --git a/src/plugins/avf/avf.h b/src/plugins/avf/avf.h index f7ea407c698..ea931dc07c4 100644 --- a/src/plugins/avf/avf.h +++ b/src/plugins/avf/avf.h @@ -182,7 +182,7 @@ typedef struct volatile u32 *qtx_tail; u16 next; u16 size; - u32 ctx_desc_placeholder_bi; + u32 *ph_bufs; clib_spinlock_t lock; avf_tx_desc_t *descs; u32 *bufs; diff --git a/src/plugins/avf/device.c b/src/plugins/avf/device.c index e0c3c99453a..70ea446432c 100644 --- a/src/plugins/avf/device.c +++ b/src/plugins/avf/device.c @@ -295,6 +295,7 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size) { clib_error_t *err; avf_txq_t *txq; + u16 n; u8 bpi = vlib_buffer_pool_get_default_for_numa (vm, ad->numa_node); @@ -313,11 +314,15 @@ avf_txq_init (vlib_main_t * vm, avf_device_t * ad, u16 qid, u16 txq_size) txq->size = txq_size; txq->next = 0; - /* Prepare a placeholder buffer to maintain a 1-1 - relationship between bufs and descs when a context - descriptor is added in descs */ - if (!vlib_buffer_alloc_from_pool - (vm, &txq->ctx_desc_placeholder_bi, 1, bpi)) + /* Prepare a placeholder buffer(s) to maintain a 1-1 relationship between + * bufs and descs when a context descriptor is added in descs. Worst case + * every second descriptor is context descriptor and due to b->ref_count + * being u8 we need one for each block of 510 descriptors */ + + n = (txq->size / 510) + 1; + vec_validate_aligned (txq->ph_bufs, n, CLIB_CACHE_LINE_BYTES); + + if (!vlib_buffer_alloc_from_pool (vm, txq->ph_bufs, n, bpi)) return clib_error_return (0, "buffer allocation error"); txq->descs = vlib_physmem_alloc_aligned_on_numa (vm, txq->size * @@ -1518,7 +1523,8 @@ avf_delete_if (vlib_main_t * vm, avf_device_t * ad, int with_barrier) txq->n_enqueued); } /* Free the placeholder buffer */ - vlib_buffer_free_one(vm, txq->ctx_desc_placeholder_bi); + vlib_buffer_free (vm, txq->ph_bufs, vec_len (txq->ph_bufs)); + vec_free (txq->ph_bufs); vec_free (txq->bufs); clib_ring_free (txq->rs_slots); vec_free (txq->tmp_bufs); diff --git a/src/plugins/avf/output.c b/src/plugins/avf/output.c index 3f361f0067f..8c932ccf68d 100644 --- a/src/plugins/avf/output.c +++ b/src/plugins/avf/output.c @@ -129,28 +129,19 @@ avf_tx_prepare_cksum (vlib_buffer_t * b, u8 is_tso) return flags; } -static_always_inline int -avf_tx_fill_ctx_desc (vlib_main_t * vm, avf_txq_t * txq, avf_tx_desc_t * d, - vlib_buffer_t * b) +static_always_inline u32 +avf_tx_fill_ctx_desc (vlib_main_t *vm, avf_txq_t *txq, avf_tx_desc_t *d, + vlib_buffer_t *b) { - vlib_buffer_t *ctx_ph = vlib_get_buffer (vm, txq->ctx_desc_placeholder_bi); + vlib_buffer_t *ctx_ph; + u32 *bi = txq->ph_bufs; + +next: + ctx_ph = vlib_get_buffer (vm, bi[0]); if (PREDICT_FALSE (ctx_ph->ref_count == 255)) { - /* We need a new placeholder buffer */ - u32 new_bi; - u8 bpi = vlib_buffer_pool_get_default_for_numa (vm, vm->numa_node); - if (PREDICT_TRUE - (vlib_buffer_alloc_from_pool (vm, &new_bi, 1, bpi) == 1)) - { - /* Remove our own reference on the current placeholder buffer */ - ctx_ph->ref_count--; - /* Replace with the new placeholder buffer */ - txq->ctx_desc_placeholder_bi = new_bi; - ctx_ph = vlib_get_buffer (vm, new_bi); - } - else - /* Impossible to enqueue a ctx descriptor, fail */ - return 1; + bi++; + goto next; } /* Acquire a reference on the placeholder buffer */ @@ -163,7 +154,7 @@ avf_tx_fill_ctx_desc (vlib_main_t * vm, avf_txq_t * txq, avf_tx_desc_t * d, d[0].qword[1] = AVF_TXD_DTYP_CTX | AVF_TXD_CTX_CMD_TSO | AVF_TXD_CTX_SEG_MSS (vnet_buffer2 (b)->gso_size) | AVF_TXD_CTX_SEG_TLEN (tlen); - return 0; + return bi[0]; } static_always_inline void @@ -334,11 +325,8 @@ avf_tx_prepare (vlib_main_t *vm, vlib_node_runtime_t *node, avf_txq_t *txq, /* Enqueue a context descriptor if needed */ if (PREDICT_FALSE (is_tso)) { - if (avf_tx_fill_ctx_desc (vm, txq, d, b[0])) - /* Failure to acquire ref on ctx placeholder */ - break; tb[1] = tb[0]; - tb[0] = txq->ctx_desc_placeholder_bi; + tb[0] = avf_tx_fill_ctx_desc (vm, txq, d, b[0]); n_desc += 1; n_desc_left -= 1; d += 1; -- cgit 1.2.3-korg