net: nbuf: Let's remove inner type

It's possible to know from which pool the nbuf comes from so
let's reduce nbuf size by removing its internal type attribute which
becomes then useless.

When a data buffer is not coming from nbuf data buffer pool, let's call
it "EXTERNAL", just to make debugging handling a little simple in the
code.

Change-Id: I6931394c8c4f594137f6380be0a0ba5cea371040
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-12-29 12:17:03 +01:00
commit 2e95186eff
2 changed files with 96 additions and 148 deletions

View file

@ -43,14 +43,6 @@ extern "C" {
struct net_context;
/** @cond ignore */
enum net_nbuf_type {
NET_NBUF_RX = 0,
NET_NBUF_TX = 1,
NET_NBUF_DATA = 2,
};
/** @endcond */
struct net_nbuf {
/** Network connection context */
struct net_context *context;
@ -71,8 +63,6 @@ struct net_nbuf {
struct net_linkaddr lladdr_src;
struct net_linkaddr lladdr_dst;
enum net_nbuf_type type;
uint16_t appdatalen;
uint16_t reserve; /* length of the protocol headers */
uint8_t ll_reserve; /* link layer header length */
@ -132,16 +122,6 @@ static inline void net_nbuf_set_iface(struct net_buf *buf, struct net_if *iface)
((struct net_nbuf *)net_buf_user_data(buf))->iface = iface;
}
static inline enum net_nbuf_type net_nbuf_type(struct net_buf *buf)
{
return ((struct net_nbuf *)net_buf_user_data(buf))->type;
}
static inline void net_nbuf_set_type(struct net_buf *buf, uint8_t type)
{
((struct net_nbuf *)net_buf_user_data(buf))->type = type;
}
static inline uint8_t net_nbuf_family(struct net_buf *buf)
{
return ((struct net_nbuf *)net_buf_user_data(buf))->family;

View file

@ -89,6 +89,22 @@
#error "Too small net_buf fragment size"
#endif
/* The RX and TX pools do not store any data. Only bearer / protocol
* related data is stored here.
*/
static inline void free_rx_bufs_func(struct net_buf *buf);
static inline void free_tx_bufs_func(struct net_buf *buf);
static inline void free_data_bufs_func(struct net_buf *buf);
NET_BUF_POOL_DEFINE(rx_buffers, NBUF_RX_COUNT, 0, sizeof(struct net_nbuf),
free_rx_bufs_func);
NET_BUF_POOL_DEFINE(tx_buffers, NBUF_TX_COUNT, 0, sizeof(struct net_nbuf),
free_tx_bufs_func);
/* The data fragment pool is for storing network data. */
NET_BUF_POOL_DEFINE(data_buffers, NBUF_DATA_COUNT, NBUF_DATA_LEN,
NBUF_USER_DATA_LEN, free_data_bufs_func);
#if NET_DEBUG
#define NET_BUF_CHECK_IF_IN_USE(buf, ref) \
@ -189,24 +205,31 @@ static inline void inc_free_data_bufs(struct net_buf *buf)
}
}
static inline int get_frees(enum net_nbuf_type type)
static inline void dec_free_bufs(struct net_buf_pool *pool,
struct net_buf *buf)
{
switch (type) {
case NET_NBUF_RX:
if (pool == &rx_buffers) {
dec_free_rx_bufs(buf);
} else if (pool == &tx_buffers) {
dec_free_tx_bufs(buf);
} else {
dec_free_data_bufs(buf);
}
}
static inline int get_frees(struct net_buf_pool *pool)
{
if (pool == &rx_buffers) {
return num_free_rx_bufs;
case NET_NBUF_TX:
} else if (pool == &tx_buffers) {
return num_free_tx_bufs;
case NET_NBUF_DATA:
} else if (pool == &data_buffers) {
return num_free_data_bufs;
}
return 0xffffffff;
}
#define inc_free_rx_bufs_func inc_free_rx_bufs
#define inc_free_tx_bufs_func inc_free_tx_bufs
#define inc_free_data_bufs_func inc_free_data_bufs
#else /* NET_DEBUG */
#define dec_free_rx_bufs(...)
#define inc_free_rx_bufs(...)
@ -214,64 +237,49 @@ static inline int get_frees(enum net_nbuf_type type)
#define inc_free_tx_bufs(...)
#define dec_free_data_bufs(...)
#define inc_free_data_bufs(...)
#define inc_free_rx_bufs_func(...)
#define inc_free_tx_bufs_func(...)
#define inc_free_data_bufs_func(...)
#define dec_free_bufs(...)
#define NET_BUF_CHECK_IF_IN_USE(buf, ref)
#define NET_BUF_CHECK_IF_NOT_IN_USE(buf, ref)
#endif /* NET_DEBUG */
static inline void free_rx_bufs_func(struct net_buf *buf)
{
inc_free_rx_bufs_func(buf);
net_buf_destroy(buf);
}
static inline void free_tx_bufs_func(struct net_buf *buf)
{
inc_free_tx_bufs_func(buf);
net_buf_destroy(buf);
}
static inline void free_data_bufs_func(struct net_buf *buf)
{
inc_free_data_bufs_func(buf);
net_buf_destroy(buf);
}
/* The RX and TX pools do not store any data. Only bearer / protocol
* related data is stored here.
*/
NET_BUF_POOL_DEFINE(rx_buffers, NBUF_RX_COUNT, 0, sizeof(struct net_nbuf),
free_rx_bufs_func);
NET_BUF_POOL_DEFINE(tx_buffers, NBUF_TX_COUNT, 0, sizeof(struct net_nbuf),
free_tx_bufs_func);
/* The data fragment pool is for storing network data. */
NET_BUF_POOL_DEFINE(data_buffers, NBUF_DATA_COUNT, NBUF_DATA_LEN,
NBUF_USER_DATA_LEN, free_data_bufs_func);
static inline bool is_from_data_pool(struct net_buf *buf)
{
return (buf->pool == &data_buffers);
}
#if NET_DEBUG
static inline const char *type2str(enum net_nbuf_type type)
static inline void free_rx_bufs_func(struct net_buf *buf)
{
switch (type) {
case NET_NBUF_RX:
inc_free_rx_bufs(buf);
net_buf_destroy(buf);
}
static inline void free_tx_bufs_func(struct net_buf *buf)
{
inc_free_tx_bufs(buf);
net_buf_destroy(buf);
}
static inline void free_data_bufs_func(struct net_buf *buf)
{
inc_free_data_bufs(buf);
net_buf_destroy(buf);
}
#if NET_DEBUG
static inline const char *pool2str(struct net_buf_pool *pool)
{
if (pool == &rx_buffers) {
return "RX";
case NET_NBUF_TX:
} else if (pool == &tx_buffers) {
return "TX";
case NET_NBUF_DATA:
} else if (pool == &data_buffers) {
return "DATA";
}
return NULL;
return "EXTERNAL";
}
void net_nbuf_print_frags(struct net_buf *buf)
@ -306,12 +314,12 @@ void net_nbuf_print_frags(struct net_buf *buf)
count * ll_overhead, (total * 100) / (count * frag_size));
}
static struct net_buf *net_nbuf_get_reserve_debug(enum net_nbuf_type type,
static struct net_buf *net_nbuf_get_reserve_debug(struct net_buf_pool *pool,
uint16_t reserve_head,
const char *caller,
int line)
#else
static struct net_buf *net_nbuf_get_reserve(enum net_nbuf_type type,
static struct net_buf *net_nbuf_get_reserve(struct net_buf_pool *pool,
uint16_t reserve_head)
#endif
{
@ -321,48 +329,24 @@ static struct net_buf *net_nbuf_get_reserve(enum net_nbuf_type type,
* The reserve_head variable in the function will tell
* the size of the link layer headers if there are any.
*/
switch (type) {
case NET_NBUF_RX:
buf = net_buf_alloc(&rx_buffers, K_FOREVER);
memset(net_buf_user_data(buf), 0, sizeof(struct net_nbuf));
NET_ASSERT_INFO(buf->ref, "RX buf %p ref %d", buf, buf->ref);
dec_free_rx_bufs(buf);
net_nbuf_set_type(buf, type);
break;
case NET_NBUF_TX:
buf = net_buf_alloc(&tx_buffers, K_FOREVER);
memset(net_buf_user_data(buf), 0, sizeof(struct net_nbuf));
NET_ASSERT_INFO(buf->ref, "TX buf %p ref %d", buf, buf->ref);
dec_free_tx_bufs(buf);
net_nbuf_set_type(buf, type);
break;
case NET_NBUF_DATA:
buf = net_buf_alloc(&data_buffers, K_FOREVER);
NET_ASSERT_INFO(buf->ref, "DATA buf %p ref %d", buf, buf->ref);
buf = net_buf_alloc(pool, K_FOREVER);
if (pool == &data_buffers) {
/* The buf->data will point to the start of the L3
* header (like IPv4 or IPv6 packet header).
*/
net_buf_reserve(buf, reserve_head);
dec_free_data_bufs(buf);
break;
default:
NET_ERR("Invalid type %d for net_buf", type);
return NULL;
} else {
memset(net_buf_user_data(buf), 0, sizeof(struct net_nbuf));
}
dec_free_bufs(pool, buf);
NET_BUF_CHECK_IF_NOT_IN_USE(buf, buf->ref + 1);
NET_DBG("%s [%d] buf %p reserve %u ref %d (%s():%d)",
type2str(type), get_frees(type),
pool2str(pool), get_frees(pool),
buf, reserve_head, buf->ref, caller, line);
return buf;
@ -372,21 +356,21 @@ static struct net_buf *net_nbuf_get_reserve(enum net_nbuf_type type,
struct net_buf *net_nbuf_get_reserve_rx_debug(uint16_t reserve_head,
const char *caller, int line)
{
return net_nbuf_get_reserve_debug(NET_NBUF_RX, reserve_head,
return net_nbuf_get_reserve_debug(&rx_buffers, reserve_head,
caller, line);
}
struct net_buf *net_nbuf_get_reserve_tx_debug(uint16_t reserve_head,
const char *caller, int line)
{
return net_nbuf_get_reserve_debug(NET_NBUF_TX, reserve_head,
return net_nbuf_get_reserve_debug(&tx_buffers, reserve_head,
caller, line);
}
struct net_buf *net_nbuf_get_reserve_data_debug(uint16_t reserve_head,
const char *caller, int line)
{
return net_nbuf_get_reserve_debug(NET_NBUF_DATA, reserve_head,
return net_nbuf_get_reserve_debug(&data_buffers, reserve_head,
caller, line);
}
@ -394,28 +378,28 @@ struct net_buf *net_nbuf_get_reserve_data_debug(uint16_t reserve_head,
struct net_buf *net_nbuf_get_reserve_rx(uint16_t reserve_head)
{
return net_nbuf_get_reserve(NET_NBUF_RX, reserve_head);
return net_nbuf_get_reserve(&rx_buffers, reserve_head);
}
struct net_buf *net_nbuf_get_reserve_tx(uint16_t reserve_head)
{
return net_nbuf_get_reserve(NET_NBUF_TX, reserve_head);
return net_nbuf_get_reserve(&tx_buffers, reserve_head);
}
struct net_buf *net_nbuf_get_reserve_data(uint16_t reserve_head)
{
return net_nbuf_get_reserve(NET_NBUF_DATA, reserve_head);
return net_nbuf_get_reserve(&data_buffers, reserve_head);
}
#endif /* NET_DEBUG */
#if NET_DEBUG
static struct net_buf *net_nbuf_get_debug(enum net_nbuf_type type,
static struct net_buf *net_nbuf_get_debug(struct net_buf_pool *pool,
struct net_context *context,
const char *caller, int line)
#else
static struct net_buf *net_nbuf_get(enum net_nbuf_type type,
static struct net_buf *net_nbuf_get(struct net_buf_pool *pool,
struct net_context *context)
#endif /* NET_DEBUG */
{
@ -434,15 +418,15 @@ static struct net_buf *net_nbuf_get(enum net_nbuf_type type,
reserve = net_if_get_ll_reserve(iface, addr6);
#if NET_DEBUG
buf = net_nbuf_get_reserve_debug(type, reserve, caller, line);
buf = net_nbuf_get_reserve_debug(pool, reserve, caller, line);
#else
buf = net_nbuf_get_reserve(type, reserve);
buf = net_nbuf_get_reserve(pool, reserve);
#endif
if (!buf) {
return buf;
}
if (type != NET_NBUF_DATA) {
if (pool != &data_buffers) {
net_nbuf_set_context(buf, context);
net_nbuf_set_ll_reserve(buf, reserve);
net_nbuf_set_family(buf, net_context_get_family(context));
@ -456,19 +440,19 @@ static struct net_buf *net_nbuf_get(enum net_nbuf_type type,
struct net_buf *net_nbuf_get_rx_debug(struct net_context *context,
const char *caller, int line)
{
return net_nbuf_get_debug(NET_NBUF_RX, context, caller, line);
return net_nbuf_get_debug(&rx_buffers, context, caller, line);
}
struct net_buf *net_nbuf_get_tx_debug(struct net_context *context,
const char *caller, int line)
{
return net_nbuf_get_debug(NET_NBUF_TX, context, caller, line);
return net_nbuf_get_debug(&tx_buffers, context, caller, line);
}
struct net_buf *net_nbuf_get_data_debug(struct net_context *context,
const char *caller, int line)
{
return net_nbuf_get_debug(NET_NBUF_DATA, context, caller, line);
return net_nbuf_get_debug(&data_buffers, context, caller, line);
}
#else /* NET_DEBUG */
@ -477,21 +461,21 @@ struct net_buf *net_nbuf_get_rx(struct net_context *context)
{
NET_ASSERT_INFO(context, "RX context not set");
return net_nbuf_get(NET_NBUF_RX, context);
return net_nbuf_get(&rx_buffers, context);
}
struct net_buf *net_nbuf_get_tx(struct net_context *context)
{
NET_ASSERT_INFO(context, "TX context not set");
return net_nbuf_get(NET_NBUF_TX, context);
return net_nbuf_get(&tx_buffers, context);
}
struct net_buf *net_nbuf_get_data(struct net_context *context)
{
NET_ASSERT_INFO(context, "Data context not set");
return net_nbuf_get(NET_NBUF_DATA, context);
return net_nbuf_get(&data_buffers, context);
}
#endif /* NET_DEBUG */
@ -517,17 +501,9 @@ void net_nbuf_unref(struct net_buf *buf)
return;
}
if (!is_from_data_pool(buf)) {
NET_DBG("%s [%d] buf %p ref %d frags %p (%s():%d)",
type2str(net_nbuf_type(buf)),
get_frees(net_nbuf_type(buf)),
buf, buf->ref - 1, buf->frags, caller, line);
} else {
NET_DBG("%s [%d] buf %p ref %d frags %p (%s():%d)",
type2str(NET_NBUF_DATA),
get_frees(NET_NBUF_DATA),
buf, buf->ref - 1, buf->frags, caller, line);
}
NET_DBG("%s [%d] buf %p ref %d frags %p (%s():%d)",
pool2str(buf->pool), get_frees(buf->pool),
buf, buf->ref - 1, buf->frags, caller, line);
#if NET_DEBUG
if (buf->ref > 1) {
@ -540,8 +516,7 @@ void net_nbuf_unref(struct net_buf *buf)
frag = buf->frags;
while (frag) {
NET_DBG("%s [%d] buf %p ref %d frags %p (%s():%d)",
type2str(NET_NBUF_DATA),
get_frees(NET_NBUF_DATA),
pool2str(buf->pool), get_frees(buf->pool),
frag, frag->ref - 1, frag->frags, caller, line);
if (!frag->ref) {
@ -570,16 +545,9 @@ struct net_buf *net_nbuf_ref(struct net_buf *buf)
return NULL;
}
if (!is_from_data_pool(buf)) {
NET_DBG("%s [%d] buf %p ref %d (%s():%d)",
type2str(net_nbuf_type(buf)),
get_frees(net_nbuf_type(buf)),
buf, buf->ref + 1, caller, line);
} else {
NET_DBG("%s buf %p ref %d (%s():%d)",
type2str(NET_NBUF_DATA),
buf, buf->ref + 1, caller, line);
}
NET_DBG("%s [%d] buf %p ref %d (%s():%d)",
pool2str(buf->pool), get_frees(buf->pool),
buf, buf->ref + 1, caller, line);
return net_buf_ref(buf);
}
@ -1355,9 +1323,9 @@ void net_nbuf_get_info(size_t *tx_size, size_t *rx_size, size_t *data_size,
}
#if NET_DEBUG
*tx = get_frees(NET_NBUF_TX);
*rx = get_frees(NET_NBUF_RX);
*data = get_frees(NET_NBUF_DATA);
*tx = get_frees(&tx_buffers);
*rx = get_frees(&rx_buffers);
*data = get_frees(&data_buffers);
#else
*tx = BIT(31);
*rx = BIT(31);