mbuf: fix reset on mbuf free
authorOlivier Matz <olivier.matz@6wind.com>
Tue, 3 Nov 2020 08:01:48 +0000 (09:01 +0100)
committerOlivier Matz <olivier.matz@6wind.com>
Thu, 26 Nov 2020 10:21:22 +0000 (11:21 +0100)
m->nb_seg must be reset on mbuf free whatever the value of m->next,
because it can happen that m->nb_seg is != 1. For instance in this
case:

  m1 = rte_pktmbuf_alloc(mp);
  rte_pktmbuf_append(m1, 500);
  m2 = rte_pktmbuf_alloc(mp);
  rte_pktmbuf_append(m2, 500);
  rte_pktmbuf_chain(m1, m2);
  m0 = rte_pktmbuf_alloc(mp);
  rte_pktmbuf_append(m0, 500);
  rte_pktmbuf_chain(m0, m1);

As rte_pktmbuf_chain() does not reset nb_seg in the initial m1
segment (this is not required), after this code the mbuf chain
have 3 segments:
  - m0: next=m1, nb_seg=3
  - m1: next=m2, nb_seg=2
  - m2: next=NULL, nb_seg=1

Freeing this mbuf chain will not restore nb_seg=1 in the second
segment. This is expected that mbufs stored in pool have their
nb_seg field set to 1.

Fixes: 8f094a9ac5d7 ("mbuf: set mbuf fields while in pool")
Cc: stable@dpdk.org
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
lib/librte_mbuf/rte_mbuf.c
lib/librte_mbuf/rte_mbuf.h

index 7d09ee2..97aac5a 100644 (file)
@@ -129,10 +129,8 @@ rte_pktmbuf_free_pinned_extmem(void *addr, void *opaque)
 
        rte_mbuf_ext_refcnt_set(m->shinfo, 1);
        m->ol_flags = EXT_ATTACHED_MBUF;
-       if (m->next != NULL) {
-               m->next = NULL;
-               m->nb_segs = 1;
-       }
+       m->next = NULL;
+       m->nb_segs = 1;
        rte_mbuf_raw_free(m);
 }
 
index c4c9ebf..e31d349 100644 (file)
@@ -1340,10 +1340,8 @@ rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
                                return NULL;
                }
 
-               if (m->next != NULL) {
-                       m->next = NULL;
-                       m->nb_segs = 1;
-               }
+               m->next = NULL;
+               m->nb_segs = 1;
 
                return m;
 
@@ -1357,10 +1355,8 @@ rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
                                return NULL;
                }
 
-               if (m->next != NULL) {
-                       m->next = NULL;
-                       m->nb_segs = 1;
-               }
+               m->next = NULL;
+               m->nb_segs = 1;
                rte_mbuf_refcnt_set(m, 1);
 
                return m;