From 2e95186eff78e08364f7ae052b7cec2c0a724b91 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Thu, 29 Dec 2016 12:17:03 +0100 Subject: [PATCH] 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 --- include/net/nbuf.h | 20 ---- subsys/net/ip/nbuf.c | 224 +++++++++++++++++++------------------------ 2 files changed, 96 insertions(+), 148 deletions(-) diff --git a/include/net/nbuf.h b/include/net/nbuf.h index 545be3875d9..a6df641d64a 100644 --- a/include/net/nbuf.h +++ b/include/net/nbuf.h @@ -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; diff --git a/subsys/net/ip/nbuf.c b/subsys/net/ip/nbuf.c index 0fccb670fda..3d7650cda4f 100644 --- a/subsys/net/ip/nbuf.c +++ b/subsys/net/ip/nbuf.c @@ -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);