mbuf: provide bulk allocation
rte_pktmbuf_alloc_bulk allocates a bulk of packet mbufs. There is related thread about this bulk API. http://dpdk.org/dev/patchwork/patch/4718/ Thanks to Konstantin's loop unrolling. Attached the wiki page about duff's device. It explains the performance optimization through loop unwinding, and also the most dramatic use of case label fall-through. https://en.wikipedia.org/wiki/Duff%27s_device In this implementation, while() loop is used because we could not assume count is strictly positive. Using while() loop saves one line of check. Signed-off-by: Gerald Rogers <gerald.rogers@intel.com> Signed-off-by: Huawei Xie <huawei.xie@intel.com> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com> Acked-by: Olivier Matz <olivier.matz@6wind.com>
This commit is contained in:
parent
bb66588304
commit
9ec201f5d6
@ -35,6 +35,11 @@ This section should contain new features added in this release. Sample format:
|
||||
|
||||
Refer to the previous release notes for examples.
|
||||
|
||||
* **Enabled bulk allocation of mbufs.**
|
||||
|
||||
A new function ``rte_pktmbuf_alloc_bulk()`` has been added to allow the user
|
||||
to allocate a bulk of mbufs.
|
||||
|
||||
* **Virtio 1.0.**
|
||||
|
||||
Enabled virtio 1.0 support for virtio pmd driver.
|
||||
|
@ -1335,6 +1335,61 @@ static inline struct rte_mbuf *rte_pktmbuf_alloc(struct rte_mempool *mp)
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a bulk of mbufs, initialize refcnt and reset the fields to default
|
||||
* values.
|
||||
*
|
||||
* @param pool
|
||||
* The mempool from which mbufs are allocated.
|
||||
* @param mbufs
|
||||
* Array of pointers to mbufs
|
||||
* @param count
|
||||
* Array size
|
||||
* @return
|
||||
* - 0: Success
|
||||
*/
|
||||
static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,
|
||||
struct rte_mbuf **mbufs, unsigned count)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
int rc;
|
||||
|
||||
rc = rte_mempool_get_bulk(pool, (void **)mbufs, count);
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
|
||||
/* To understand duff's device on loop unwinding optimization, see
|
||||
* https://en.wikipedia.org/wiki/Duff's_device.
|
||||
* Here while() loop is used rather than do() while{} to avoid extra
|
||||
* check if count is zero.
|
||||
*/
|
||||
switch (count % 4) {
|
||||
case 0:
|
||||
while (idx != count) {
|
||||
RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 0);
|
||||
rte_mbuf_refcnt_set(mbufs[idx], 1);
|
||||
rte_pktmbuf_reset(mbufs[idx]);
|
||||
idx++;
|
||||
case 3:
|
||||
RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 0);
|
||||
rte_mbuf_refcnt_set(mbufs[idx], 1);
|
||||
rte_pktmbuf_reset(mbufs[idx]);
|
||||
idx++;
|
||||
case 2:
|
||||
RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 0);
|
||||
rte_mbuf_refcnt_set(mbufs[idx], 1);
|
||||
rte_pktmbuf_reset(mbufs[idx]);
|
||||
idx++;
|
||||
case 1:
|
||||
RTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 0);
|
||||
rte_mbuf_refcnt_set(mbufs[idx], 1);
|
||||
rte_pktmbuf_reset(mbufs[idx]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach packet mbuf to another packet mbuf.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user