From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id A457F1B4B0 for ; Mon, 7 Jan 2019 09:57:23 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D16FE87632; Mon, 7 Jan 2019 08:57:22 +0000 (UTC) Received: from dmarchan.remote.csb (ovpn-117-97.ams2.redhat.com [10.36.117.97]) by smtp.corp.redhat.com (Postfix) with ESMTP id 64BEE600CC; Mon, 7 Jan 2019 08:57:21 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: olivier.matz@6wind.com, yskoh@mellanox.com, arybchenko@solarflare.com, bernard.iremonger@intel.com, David Marchand Date: Mon, 7 Jan 2019 09:57:11 +0100 Message-Id: <1546851432-19397-3-git-send-email-david.marchand@redhat.com> In-Reply-To: <1546851432-19397-1-git-send-email-david.marchand@redhat.com> References: <1546851432-19397-1-git-send-email-david.marchand@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 07 Jan 2019 08:57:22 +0000 (UTC) Subject: [dpdk-dev] [PATCH v2 2/3] mbuf: add a non fatal sanity check helper X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Jan 2019 08:57:24 -0000 From: David Marchand Let's add a little helper that does the same as rte_mbuf_sanity_check but without the panic. Signed-off-by: David Marchand Signed-off-by: David Marchand Acked-by: Olivier Matz --- lib/librte_mbuf/Makefile | 2 + lib/librte_mbuf/meson.build | 2 + lib/librte_mbuf/rte_mbuf.c | 74 ++++++++++++++++++++++++++---------- lib/librte_mbuf/rte_mbuf.h | 23 +++++++++++ lib/librte_mbuf/rte_mbuf_version.map | 6 +++ 5 files changed, 86 insertions(+), 21 deletions(-) diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile index 8c4c7d7..c8f6d26 100644 --- a/lib/librte_mbuf/Makefile +++ b/lib/librte_mbuf/Makefile @@ -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 diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build index e37da02..6cc11eb 100644 --- a/lib/librte_mbuf/meson.build +++ b/lib/librte_mbuf/meson.build @@ -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 diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 3bbd3f5..21f6f74 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -171,47 +171,79 @@ struct rte_mempool * 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 */ diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index bc562dc..564e08c 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -1052,6 +1052,29 @@ struct rte_pktmbuf_pool_private { 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); \ diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map index cae68db..2662a37 100644 --- a/lib/librte_mbuf/rte_mbuf_version.map +++ b/lib/librte_mbuf/rte_mbuf_version.map @@ -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; -- 1.8.3.1