DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ferruh Yigit <ferruh.yigit@intel.com>
To: Sergey Vyazmitinov <s.vyazmitinov@brain4net.com>, olivier.matz@6wind.com
Cc: konstantin.ananyev@intel.com, stephen@networkplumber.org,
	yuanhan.liu@linux.intel.com, dev@dpdk.org, mirqus@gmail.com
Subject: Re: [dpdk-dev] [PATCH v6 2/2] kni: Use bulk functions to allocate and free mbufs
Date: Wed, 25 Jan 2017 20:10:58 +0000	[thread overview]
Message-ID: <301e337b-1d1f-c3b2-3adf-af9beb0d6ad0@intel.com> (raw)
In-Reply-To: <1484801219-1312-3-git-send-email-s.vyazmitinov@brain4net.com>

On 1/19/2017 4:46 AM, Sergey Vyazmitinov wrote:
> Optimized kni_allocate_mbufs and kni_free_mbufs by using mbuf
> bulk functions. This can improve performance more than two times.
> 
> Signed-off-by: Sergey Vyazmitinov <s.vyazmitinov@brain4net.com>
> ---
> v5:
> * use rte_pktmbuf_free_bulk for removing packets which was not
> put in alloc queue.
> v6:
> * fix c99 compilation error
> ---
>  lib/librte_kni/rte_kni.c      | 47 ++++++++++++++++++++-----------------------
>  lib/librte_kni/rte_kni_fifo.h | 18 +++++++++++++++++
>  2 files changed, 40 insertions(+), 25 deletions(-)
> 
> diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
> index a80cefd..6591f4f 100644
> --- a/lib/librte_kni/rte_kni.c
> +++ b/lib/librte_kni/rte_kni.c
> @@ -590,22 +590,21 @@ rte_kni_rx_burst(struct rte_kni *kni, struct rte_mbuf **mbufs, unsigned num)
>  static void
>  kni_free_mbufs(struct rte_kni *kni)
>  {
> -	int i, ret;
> +	unsigned int freeing;
>  	struct rte_mbuf *pkts[MAX_MBUF_BURST_NUM];
>  
> -	ret = kni_fifo_get(kni->free_q, (void **)pkts, MAX_MBUF_BURST_NUM);
> -	if (likely(ret > 0)) {
> -		for (i = 0; i < ret; i++)
> -			rte_pktmbuf_free(pkts[i]);
> +	freeing = kni_fifo_get(kni->free_q, (void **)pkts, MAX_MBUF_BURST_NUM);
> +	if (likely(freeing > 0)) {
> +		rte_pktmbuf_free_bulk(pkts, freeing);
>  	}
>  }
>  
>  static void
>  kni_allocate_mbufs(struct rte_kni *kni)
>  {
> -	int i, ret;
> -	struct rte_mbuf *pkts[MAX_MBUF_BURST_NUM];
> -	void *phys[MAX_MBUF_BURST_NUM];
> +	unsigned int count, put, i;
> +	struct rte_mbuf *pkts[KNI_FIFO_COUNT_MAX];
> +	void *phys[KNI_FIFO_COUNT_MAX];
>  
>  	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pool) !=
>  			 offsetof(struct rte_kni_mbuf, pool));
> @@ -628,28 +627,26 @@ kni_allocate_mbufs(struct rte_kni *kni)
>  		return;
>  	}
>  
> -	for (i = 0; i < MAX_MBUF_BURST_NUM; i++) {
> -		pkts[i] = rte_pktmbuf_alloc(kni->pktmbuf_pool);
> -		if (unlikely(pkts[i] == NULL)) {
> -			/* Out of memory */
> -			RTE_LOG(ERR, KNI, "Out of memory\n");
> -			break;
> -		}
> -		phys[i] = va2pa(pkts[i]);
> -	}
> +	/* Calculate alloc queue free space */
> +	count = kni_fifo_free_count(kni->alloc_q);

This seems reason of the performance loss mentioned in cover letter.
Updating this line as following recovers the performance:

count = MAX_MBUF_BURST_NUM;

kni->alloc_q is fifo shared between kernel thread, which runs on its own
core, and the rx poll core.
Getting free count and allocating that much mbuf causing worse
performance, comparing to the original behavior.



Btw, I have tried something else, which is giving conflicting results
(it was better when I first tried, now getting worse result):

kni_allocate_mbufs() called every time received some packets from
kernel, because this means kernel thread consumed some mbufs from
alloc_q, and userspace needs to fill it back again.

So, instead of allocating fixed number of mbuf, or allocating free
number of fifo mbuf, what about allocating amount of mbufs that received
by kernel.
Since kernel consumed that much, fill back that much.

make this function:
kni_allocate_mbufs(struct rte_kni *kni, unsigned int num);

rte_kni_rx_burst() calls:
kni_allocate_mbufs(kni, ret);

What do you think?
If possible can you please try this?


Thanks,
ferruh

>  
> -	/* No pkt mbuf alocated */
> -	if (i <= 0)
> +	/* Get buffers from mempool */
> +	if (rte_pktmbuf_alloc_bulk(kni->pktmbuf_pool, pkts, count) != 0) {
> +		RTE_LOG(ERR, KNI, "Can`t allocate %d mbufs\n", count);
>  		return;
> +	}
> +
> +	for (i = 0; i < count; i++)
> +		phys[i] = va2pa(pkts[i]);
>  
> -	ret = kni_fifo_put(kni->alloc_q, phys, i);
> +	/* Put buffers into alloc queue */
> +	put = kni_fifo_put(kni->alloc_q, (void **)phys, count);
>  
>  	/* Check if any mbufs not put into alloc_q, and then free them */
> -	if (ret >= 0 && ret < i && ret < MAX_MBUF_BURST_NUM) {
> -		int j;
> -
> -		for (j = ret; j < i; j++)
> -			rte_pktmbuf_free(pkts[j]);
> +	if (unlikely(put < count)) {
> +		RTE_LOG(ERR, KNI, "Free %u of %u allocated buffers\n",
> +			count - put, count);
> +		rte_pktmbuf_free_bulk(pkts + put, count - put);
>  	}
>  }
>  
> diff --git a/lib/librte_kni/rte_kni_fifo.h b/lib/librte_kni/rte_kni_fifo.h
> index 8cb8587..361ddb0 100644
> --- a/lib/librte_kni/rte_kni_fifo.h
> +++ b/lib/librte_kni/rte_kni_fifo.h
> @@ -91,3 +91,21 @@ kni_fifo_get(struct rte_kni_fifo *fifo, void **data, unsigned num)
>  	fifo->read = new_read;
>  	return i;
>  }
> +
> +/**
> + * Get the num of elements in the fifo
> + */
> +static inline unsigned
> +kni_fifo_count(struct rte_kni_fifo *fifo)
> +{
> +	return (fifo->len + fifo->write - fifo->read) & (fifo->len - 1);
> +}
> +
> +/**
> + * Get the num of available elements in the fifo
> + */
> +static inline unsigned
> +kni_fifo_free_count(struct rte_kni_fifo *fifo)
> +{
> +	return (fifo->read - fifo->write - 1) & (fifo->len - 1);
> +}
> 

  reply	other threads:[~2017-01-25 20:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-19  4:46 [dpdk-dev] [PATCH v6 0/2] kni: use " Sergey Vyazmitinov
2017-01-19  4:46 ` [dpdk-dev] [PATCH v6 1/2] kni: add bulk function to " Sergey Vyazmitinov
2017-01-23 12:59   ` Olivier Matz
2017-01-23 13:19     ` Olivier Matz
2017-01-19  4:46 ` [dpdk-dev] [PATCH v6 2/2] kni: Use bulk functions to allocate and " Sergey Vyazmitinov
2017-01-25 20:10   ` Ferruh Yigit [this message]
2017-01-25 19:04 ` [dpdk-dev] [PATCH v6 0/2] kni: use " Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=301e337b-1d1f-c3b2-3adf-af9beb0d6ad0@intel.com \
    --to=ferruh.yigit@intel.com \
    --cc=dev@dpdk.org \
    --cc=konstantin.ananyev@intel.com \
    --cc=mirqus@gmail.com \
    --cc=olivier.matz@6wind.com \
    --cc=s.vyazmitinov@brain4net.com \
    --cc=stephen@networkplumber.org \
    --cc=yuanhan.liu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).