rte_pktmbuf_chain rte_pktmbuf_clone

 https://www.yuque.com/zzqcn/opensource/oirzxh

    m = rte_pktmbuf_alloc(mpool);
    rte_pktmbuf_append(m, 1000);
    mbuf_dump(m);

    m2 = rte_pktmbuf_alloc(mpool);
    rte_pktmbuf_append(m2, 500);
    mbuf_dump(m2);

    rte_pktmbuf_chain(m, m2);
    printf("after m  rte_pktmbuf_chain \n");
    mbuf_dump(m);

 

RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f919c00
m->refcnt: 1
m->buf_addr: 0x13f919c90
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 1000
m->data_len: 1000
m->nb_segs: 1
m->next: (nil)
m->buf_addr+m->data_off: 0x13f919d10
rte_pktmbuf_mtod(m): 0x13f919d10
rte_pktmbuf_data_len(m): 1000
rte_pktmbuf_pkt_len(m): 1000
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 518
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f919480
m->refcnt: 1
m->buf_addr: 0x13f919510
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 500
m->data_len: 500
m->nb_segs: 1
m->next: (nil)
m->buf_addr+m->data_off: 0x13f919590
rte_pktmbuf_mtod(m): 0x13f919590
rte_pktmbuf_data_len(m): 500
rte_pktmbuf_pkt_len(m): 500
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 1018
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

================== after m  rte_pktmbuf_chain ===================== 
RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f919c00
m->refcnt: 1
m->buf_addr: 0x13f919c90
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 1500
m->data_len: 1000
m->nb_segs: 2
m->next: 0x13f919480
m->buf_addr+m->data_off: 0x13f919d10
rte_pktmbuf_mtod(m): 0x13f919d10
rte_pktmbuf_data_len(m): 1000
rte_pktmbuf_pkt_len(m): 1500
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 518
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

 

 

rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
{
        struct rte_mbuf *mc, *mi, **prev;
        uint32_t pktlen;
        uint16_t nseg;

        mc = rte_pktmbuf_alloc(mp);
        if (unlikely(mc == NULL))
                return NULL;

        mi = mc;
        prev = &mi->next;
        pktlen = md->pkt_len;
        nseg = 0;

        do {
                nseg++;
                rte_pktmbuf_attach(mi, md);
                *prev = mi;
                prev = &mi->next;
        } while ((md = md->next) != NULL &&
            (mi = rte_pktmbuf_alloc(mp)) != NULL);

        *prev = NULL;
        mc->nb_segs = nseg;
        mc->pkt_len = pktlen;

        /* Allocation of new indirect segment failed */
        if (unlikely(mi == NULL)) {
                rte_pktmbuf_free(mc);
        }

        __rte_mbuf_sanity_check(mc, 1);
        return mc;
}

 

static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
{
        RTE_ASSERT(RTE_MBUF_DIRECT(mi) &&
            rte_mbuf_refcnt_read(mi) == 1);

        if (RTE_MBUF_HAS_EXTBUF(m)) {
                rte_mbuf_ext_refcnt_update(m->shinfo, 1);
                mi->ol_flags = m->ol_flags;
                mi->shinfo = m->shinfo;
        } else {
                /* if m is not direct, get the mbuf that embeds the data */
                rte_mbuf_refcnt_update(rte_mbuf_from_indirect(m), 1);
                mi->priv_size = m->priv_size;
                mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
        }

        __rte_pktmbuf_copy_hdr(mi, m);

        mi->data_off = m->data_off;
        mi->data_len = m->data_len;
        mi->buf_iova = m->buf_iova;
        mi->buf_addr = m->buf_addr;
        mi->buf_len = m->buf_len;

        mi->next = NULL;
        mi->pkt_len = mi->data_len;
        mi->nb_segs = 1;

        __rte_mbuf_sanity_check(mi, 1);
        __rte_mbuf_sanity_check(m, 0);
}

 

 m = rte_pktmbuf_alloc(mpool);
    rte_pktmbuf_append(m, 1000);
    mbuf_dump(m);
    printf("================== after m  rte_pktmbuf_clone===================== \n");
    m2 = rte_pktmbuf_clone(m, mpool);
    mbuf_dump(m2);
    m3 = rte_pktmbuf_clone(m, mpool);
    printf("================== after m  rte_pktmbuf_clone===================== \n");
    mbuf_dump(m3);

 

 

 

 

 

 

RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f919480
m->refcnt: 1
m->buf_addr: 0x13f919510
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 1000
m->data_len: 1000
m->nb_segs: 1
m->next: (nil)
m->buf_addr+m->data_off: 0x13f919590
rte_pktmbuf_mtod(m): 0x13f919590
rte_pktmbuf_data_len(m): 1000
rte_pktmbuf_pkt_len(m): 1000
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 518
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

================== after m  rte_pktmbuf_clone===================== 
RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f919c00
m->refcnt: 1
m->buf_addr: 0x13f919510  ---同m1
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 1000
m->data_len: 1000
m->nb_segs: 1
m->next: (nil)
m->buf_addr+m->data_off: 0x13f919590
rte_pktmbuf_mtod(m): 0x13f919590
rte_pktmbuf_data_len(m): 1000
rte_pktmbuf_pkt_len(m): 1000
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 518
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

================== after m  rte_pktmbuf_clone===================== 
RTE_PKTMBUF_HEADROOM: 128
sizeof(mbuf): 128
m: 0x13f918d00
m->refcnt: 1
m->buf_addr: 0x13f919510 ---同m1
m->data_off: 128
m->buf_len: 1646
m->pkt_len: 1000
m->data_len: 1000
m->nb_segs: 1
m->next: (nil)
m->buf_addr+m->data_off: 0x13f919590
rte_pktmbuf_mtod(m): 0x13f919590
rte_pktmbuf_data_len(m): 1000
rte_pktmbuf_pkt_len(m): 1000
rte_pktmbuf_headroom(m): 128
rte_pktmbuf_tailroom(m): 518
rte_pktmbuf_data_room_size(mpool): 1646
rte_pktmbuf_priv_size(mpool): 16

 

    printf("mempool count before free: %u\n", rte_mempool_avail_count(mpool));
    printf("m->refcnt: %u\n", m->refcnt);
    rte_pktmbuf_free(m);
    printf("mempool count after free: %u\n", rte_mempool_avail_count(mpool));
    printf("m->refcnt: %u\n", m->refcnt);
    rte_pktmbuf_free(m3);
    printf("mempool count after free: %u\n", rte_mempool_avail_count(mpool));
    printf("m->refcnt: %u\n", m->refcnt);
    rte_pktmbuf_free(m2);
    printf("mempool count after free: %u\n", rte_mempool_avail_count(mpool));
    printf("m->refcnt: %u\n", m->refcnt);
    rte_pktmbuf_free(m);
    printf("mempool count after free: %u\n", rte_mempool_avail_count(mpool));
    printf("m->refcnt: %u\n", m->refcnt);

 

mempool count before free: 1020
m->refcnt: 3
mempool count after free: 1020
m->refcnt: 2   //free(m)
mempool count after free: 1021
m->refcnt: 1   // free(m3)
mempool count after free: 1023
m->refcnt: 1   //free(m2)
mempool count after free: 1023
m->refcnt: 1  //free(m)

 

  • rte_pktmbuf_free 回收mbuf或mbuf chain, 可以处理引用计数等内部细节
  • rte_pktmbuf_free_seg 回收单个mbuf, 但不处理mbuf chain. 可以处理引用计数等内部细节

 

static inline void rte_pktmbuf_free(struct rte_mbuf *m)
{
        struct rte_mbuf *m_next;

        if (m != NULL)
                __rte_mbuf_sanity_check(m, 1);

        while (m != NULL) {
                m_next = m->next;
                rte_pktmbuf_free_seg(m);
                m = m_next;
        }
}
static __rte_always_inline void
rte_pktmbuf_free_seg(struct rte_mbuf *m)
{
        m = rte_pktmbuf_prefree_seg(m);
        if (likely(m != NULL))
                rte_mbuf_raw_free(m);
}

 

 

static __rte_always_inline struct rte_mbuf *
rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
{
        __rte_mbuf_sanity_check(m, 0);

        if (likely(rte_mbuf_refcnt_read(m) == 1)) {


                if (!RTE_MBUF_DIRECT(m))
                        rte_pktmbuf_detach(m);

                if (m->next != NULL) {
                        m->next = NULL;
                        m->nb_segs = 1;
                }

                return m;

        } else if (__rte_mbuf_refcnt_update(m, -1) == 0) {

                if (!RTE_MBUF_DIRECT(m))
                        rte_pktmbuf_detach(m);

                if (m->next != NULL) {
                        m->next = NULL;
                        m->nb_segs = 1;
                }
                rte_mbuf_refcnt_set(m, 1);

                return m;
        }
        return NULL;
}

 

 

 

 

/* internal */
static inline uint16_t
__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
{
        m->refcnt = (uint16_t)(m->refcnt + value);
        return m->refcnt;
}

 

 

 

 

/**
 * Returns TRUE if given mbuf is direct, or FALSE otherwise.
 *
 * If a mbuf embeds its own data after the rte_mbuf structure, this mbuf
 * can be defined as a direct mbuf.
 */
#define RTE_MBUF_DIRECT(mb) \
        (!((mb)->ol_flags & (IND_ATTACHED_MBUF | EXT_ATTACHED_MBUF)))

 

 

 

static __rte_always_inline void
rte_mbuf_raw_free(struct rte_mbuf *m)
{
        RTE_ASSERT(RTE_MBUF_DIRECT(m));
        RTE_ASSERT(rte_mbuf_refcnt_read(m) == 1);
        RTE_ASSERT(m->next == NULL);
        RTE_ASSERT(m->nb_segs == 1);
        __rte_mbuf_sanity_check(m, 0);
        rte_mempool_put(m->pool, m);
}

 

posted on 2020-09-28 12:09  tycoon3  阅读(981)  评论(0)    收藏  举报

导航