net: buf: Switch from k_fifo to k_lifo for free buffers

Using a LIFO instead of a FIFO has the potential benefit that more
recently in-use buffers may be "cache-hot" and therefore accessed
faster than least recently used (which is what we get with a FIFO).

Change-Id: I59bb083ca2e00d0d404406540f7db216742a27cf
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2016-12-14 08:24:19 +02:00
commit 692771fbe9
3 changed files with 12 additions and 13 deletions

View file

@ -39,9 +39,8 @@ buffers may also contain protocol-specific context, known as user data.
Both the maximum data and user data capacity of the buffers is Both the maximum data and user data capacity of the buffers is
compile-time defined when declaring the buffer pool. compile-time defined when declaring the buffer pool.
Since the free buffers are managed with the help of a k_fifo it means The buffers have native support for being passed through k_fifo kernel
the buffers have native support for being passed through other FIFOs objects. This is a very practical feature when the buffers need to be
as well. This is a very practical feature when the buffers need to be
passed from one thread to another. However, since a net_buf may have a passed from one thread to another. However, since a net_buf may have a
fragment chain attached to it, instead of using the :c:func:`k_fifo_put` fragment chain attached to it, instead of using the :c:func:`k_fifo_put`
and :c:func:`k_fifo_get` APIs, special :c:func:`net_buf_put` and and :c:func:`k_fifo_get` APIs, special :c:func:`net_buf_put` and

View file

@ -434,8 +434,8 @@ struct net_buf {
}; };
struct net_buf_pool { struct net_buf_pool {
/** FIFO to place the buffer into when free */ /** LIFO to place the buffer into when free */
struct k_fifo free; struct k_lifo free;
/** Number of buffers in pool */ /** Number of buffers in pool */
const uint16_t buf_count; const uint16_t buf_count;
@ -459,7 +459,7 @@ struct net_buf_pool {
#define NET_BUF_POOL_INITIALIZER(_pool, _bufs, _count, _size, _ud_size, \ #define NET_BUF_POOL_INITIALIZER(_pool, _bufs, _count, _size, _ud_size, \
_destroy) \ _destroy) \
{ \ { \
.free = K_FIFO_INITIALIZER(_pool.free), \ .free = K_LIFO_INITIALIZER(_pool.free), \
.__bufs = (struct net_buf *)_bufs, \ .__bufs = (struct net_buf *)_bufs, \
.buf_count = _count, \ .buf_count = _count, \
.uninit_count = _count, \ .uninit_count = _count, \
@ -553,7 +553,7 @@ struct net_buf *net_buf_get(struct k_fifo *fifo, int32_t timeout);
*/ */
static inline void net_buf_destroy(struct net_buf *buf) static inline void net_buf_destroy(struct net_buf *buf)
{ {
k_fifo_put(&buf->pool->free, buf); k_lifo_put(&buf->pool->free, buf);
} }
/** /**

View file

@ -95,10 +95,10 @@ struct net_buf *net_buf_alloc(struct net_buf_pool *pool, int32_t timeout)
/* If this is not the first access to the pool, we can /* If this is not the first access to the pool, we can
* be opportunistic and try to fetch a previously used * be opportunistic and try to fetch a previously used
* buffer from the FIFO with K_NO_WAIT. * buffer from the LIFO with K_NO_WAIT.
*/ */
if (pool->uninit_count < pool->buf_count) { if (pool->uninit_count < pool->buf_count) {
buf = k_fifo_get(&pool->free, K_NO_WAIT); buf = k_lifo_get(&pool->free, K_NO_WAIT);
if (buf) { if (buf) {
irq_unlock(key); irq_unlock(key);
goto success; goto success;
@ -116,17 +116,17 @@ struct net_buf *net_buf_alloc(struct net_buf_pool *pool, int32_t timeout)
#if defined(CONFIG_NET_BUF_DEBUG) #if defined(CONFIG_NET_BUF_DEBUG)
if (timeout == K_FOREVER) { if (timeout == K_FOREVER) {
buf = k_fifo_get(&pool->free, K_NO_WAIT); buf = k_lifo_get(&pool->free, K_NO_WAIT);
if (!buf) { if (!buf) {
NET_BUF_WARN("%s():%d: Pool %p low on buffers.", NET_BUF_WARN("%s():%d: Pool %p low on buffers.",
func, line, pool); func, line, pool);
buf = k_fifo_get(&pool->free, timeout); buf = k_lifo_get(&pool->free, timeout);
} }
} else { } else {
buf = k_fifo_get(&pool->free, timeout); buf = k_lifo_get(&pool->free, timeout);
} }
#else #else
buf = k_fifo_get(&pool->free, timeout); buf = k_lifo_get(&pool->free, timeout);
#endif #endif
if (!buf) { if (!buf) {
NET_BUF_ERR("%s():%d: Failed to get free buffer", func, line); NET_BUF_ERR("%s():%d: Failed to get free buffer", func, line);