mbuf: add a non fatal sanity check helper
Let's add a little helper that does the same as rte_mbuf_sanity_check but without the panic. Signed-off-by: David Marchand <david.marchand@6wind.com> Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Olivier Matz <olivier.matz@6wind.com>
This commit is contained in:
parent
dcd2a33d3c
commit
d4dca8fe43
@ -7,6 +7,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
|
||||
LIB = librte_mbuf.a
|
||||
|
||||
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
|
||||
CFLAGS += -DALLOW_EXPERIMENTAL_API
|
||||
|
||||
LDLIBS += -lrte_eal -lrte_mempool
|
||||
|
||||
EXPORT_MAP := rte_mbuf_version.map
|
||||
|
@ -5,3 +5,5 @@ version = 5
|
||||
sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
|
||||
headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
|
||||
deps += ['mempool']
|
||||
|
||||
allow_experimental_apis = true
|
||||
|
@ -170,48 +170,80 @@ rte_pktmbuf_pool_create(const char *name, unsigned int n,
|
||||
/* do some sanity checks on a mbuf: panic if it fails */
|
||||
void
|
||||
rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
|
||||
{
|
||||
const char *reason;
|
||||
|
||||
if (rte_mbuf_check(m, is_header, &reason))
|
||||
rte_panic("%s\n", reason);
|
||||
}
|
||||
|
||||
__rte_experimental
|
||||
int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
|
||||
const char **reason)
|
||||
{
|
||||
unsigned int nb_segs, pkt_len;
|
||||
|
||||
if (m == NULL)
|
||||
rte_panic("mbuf is NULL\n");
|
||||
if (m == NULL) {
|
||||
*reason = "mbuf is NULL";
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* generic checks */
|
||||
if (m->pool == NULL)
|
||||
rte_panic("bad mbuf pool\n");
|
||||
if (m->buf_iova == 0)
|
||||
rte_panic("bad IO addr\n");
|
||||
if (m->buf_addr == NULL)
|
||||
rte_panic("bad virt addr\n");
|
||||
if (m->pool == NULL) {
|
||||
*reason = "bad mbuf pool";
|
||||
return -1;
|
||||
}
|
||||
if (m->buf_iova == 0) {
|
||||
*reason = "bad IO addr";
|
||||
return -1;
|
||||
}
|
||||
if (m->buf_addr == NULL) {
|
||||
*reason = "bad virt addr";
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t cnt = rte_mbuf_refcnt_read(m);
|
||||
if ((cnt == 0) || (cnt == UINT16_MAX))
|
||||
rte_panic("bad ref cnt\n");
|
||||
if ((cnt == 0) || (cnt == UINT16_MAX)) {
|
||||
*reason = "bad ref cnt";
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* nothing to check for sub-segments */
|
||||
if (is_header == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* data_len is supposed to be not more than pkt_len */
|
||||
if (m->data_len > m->pkt_len)
|
||||
rte_panic("bad data_len\n");
|
||||
if (m->data_len > m->pkt_len) {
|
||||
*reason = "bad data_len";
|
||||
return -1;
|
||||
}
|
||||
|
||||
nb_segs = m->nb_segs;
|
||||
pkt_len = m->pkt_len;
|
||||
|
||||
do {
|
||||
if (m->data_off > m->buf_len)
|
||||
rte_panic("data offset too big in mbuf segment\n");
|
||||
if (m->data_off + m->data_len > m->buf_len)
|
||||
rte_panic("data length too big in mbuf segment\n");
|
||||
if (m->data_off > m->buf_len) {
|
||||
*reason = "data offset too big in mbuf segment";
|
||||
return -1;
|
||||
}
|
||||
if (m->data_off + m->data_len > m->buf_len) {
|
||||
*reason = "data length too big in mbuf segment";
|
||||
return -1;
|
||||
}
|
||||
nb_segs -= 1;
|
||||
pkt_len -= m->data_len;
|
||||
} while ((m = m->next) != NULL);
|
||||
|
||||
if (nb_segs)
|
||||
rte_panic("bad nb_segs\n");
|
||||
if (pkt_len)
|
||||
rte_panic("bad pkt_len\n");
|
||||
if (nb_segs) {
|
||||
*reason = "bad nb_segs";
|
||||
return -1;
|
||||
}
|
||||
if (pkt_len) {
|
||||
*reason = "bad pkt_len";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump a mbuf on console */
|
||||
|
@ -1049,6 +1049,29 @@ rte_mbuf_ext_refcnt_update(struct rte_mbuf_ext_shared_info *shinfo,
|
||||
void
|
||||
rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header);
|
||||
|
||||
/**
|
||||
* Sanity checks on a mbuf.
|
||||
*
|
||||
* Almost like rte_mbuf_sanity_check(), but this function gives the reason
|
||||
* if corruption is detected rather than panic.
|
||||
*
|
||||
* @param m
|
||||
* The mbuf to be checked.
|
||||
* @param is_header
|
||||
* True if the mbuf is a packet header, false if it is a sub-segment
|
||||
* of a packet (in this case, some fields like nb_segs are not checked)
|
||||
* @param reason
|
||||
* A reference to a string pointer where to store the reason why a mbuf is
|
||||
* considered invalid.
|
||||
* @return
|
||||
* - 0 if no issue has been found, reason is left untouched.
|
||||
* - -1 if a problem is detected, reason then points to a string describing
|
||||
* the reason why the mbuf is deemed invalid.
|
||||
*/
|
||||
__rte_experimental
|
||||
int rte_mbuf_check(const struct rte_mbuf *m, int is_header,
|
||||
const char **reason);
|
||||
|
||||
#define MBUF_RAW_ALLOC_CHECK(m) do { \
|
||||
RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1); \
|
||||
RTE_ASSERT((m)->next == NULL); \
|
||||
|
@ -45,3 +45,9 @@ DPDK_18.08 {
|
||||
rte_mbuf_user_mempool_ops;
|
||||
rte_pktmbuf_pool_create_by_ops;
|
||||
} DPDK_16.11;
|
||||
|
||||
EXPERIMENTAL {
|
||||
global:
|
||||
|
||||
rte_mbuf_check;
|
||||
} DPDK_18.08;
|
||||
|
Loading…
x
Reference in New Issue
Block a user