/* uint64_t unused:8; */
};
};
+
+ /** Size of the application private data. In case of an indirect
+ * mbuf, it stores the direct mbuf private data size. */
+ uint16_t priv_size;
} __rte_cache_aligned;
+static inline uint16_t rte_pktmbuf_priv_size(struct rte_mempool *mp);
+
/**
- * Given the buf_addr returns the pointer to corresponding mbuf.
+ * Return the mbuf owning the data buffer address of an indirect mbuf.
+ *
+ * @param mi
+ * The pointer to the indirect mbuf.
+ * @return
+ * The address of the direct mbuf corresponding to buffer_addr.
*/
-#define RTE_MBUF_FROM_BADDR(ba) (((struct rte_mbuf *)(ba)) - 1)
+static inline struct rte_mbuf *
+rte_mbuf_from_indirect(struct rte_mbuf *mi)
+{
+ struct rte_mbuf *md;
+
+ /* mi->buf_addr and mi->priv_size correspond to buffer and
+ * private size of the direct mbuf */
+ md = (struct rte_mbuf *)((char *)mi->buf_addr - sizeof(*mi) -
+ mi->priv_size);
+ return md;
+}
/**
- * Given the pointer to mbuf returns an address where it's buf_addr
- * should point to.
+ * Return the buffer address embedded in the given mbuf.
+ *
+ * @param md
+ * The pointer to the mbuf.
+ * @return
+ * The address of the data buffer owned by the mbuf.
*/
-#define RTE_MBUF_TO_BADDR(mb) (((struct rte_mbuf *)(mb)) + 1)
+static inline char *
+rte_mbuf_to_baddr(struct rte_mbuf *md)
+{
+ char *buffer_addr;
+ buffer_addr = (char *)md + sizeof(*md) + rte_pktmbuf_priv_size(md->pool);
+ return buffer_addr;
+}
/**
* Returns TRUE if given mbuf is indirect, or FALSE otherwise.
/**
* Attach packet mbuf to another packet mbuf.
+ *
* After attachment we refer the mbuf we attached as 'indirect',
* while mbuf we attached to as 'direct'.
* Right now, not supported:
- * - attachment to indirect mbuf (e.g. - md has to be direct).
* - attachment for already indirect mbuf (e.g. - mi has to be direct).
* - mbuf we trying to attach (mi) is used by someone else
* e.g. it's reference counter is greater then 1.
*
* @param mi
* The indirect packet mbuf.
- * @param md
- * The direct packet mbuf.
+ * @param m
+ * The packet mbuf we're attaching to.
*/
-
-static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *md)
+static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
{
- RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(md) &&
- RTE_MBUF_DIRECT(mi) &&
+ struct rte_mbuf *md;
+
+ RTE_MBUF_ASSERT(RTE_MBUF_DIRECT(mi) &&
rte_mbuf_refcnt_read(mi) == 1);
+ /* if m is not direct, get the mbuf that embeds the data */
+ if (RTE_MBUF_DIRECT(m))
+ md = m;
+ else
+ md = rte_mbuf_from_indirect(m);
+
rte_mbuf_refcnt_update(md, 1);
- mi->buf_physaddr = md->buf_physaddr;
- mi->buf_addr = md->buf_addr;
- mi->buf_len = md->buf_len;
-
- mi->next = md->next;
- mi->data_off = md->data_off;
- mi->data_len = md->data_len;
- mi->port = md->port;
- mi->vlan_tci = md->vlan_tci;
- mi->tx_offload = md->tx_offload;
- mi->hash = md->hash;
+ mi->priv_size = m->priv_size;
+ mi->buf_physaddr = m->buf_physaddr;
+ mi->buf_addr = m->buf_addr;
+ mi->buf_len = m->buf_len;
+
+ mi->next = m->next;
+ mi->data_off = m->data_off;
+ mi->data_len = m->data_len;
+ mi->port = m->port;
+ mi->vlan_tci = m->vlan_tci;
+ mi->tx_offload = m->tx_offload;
+ mi->hash = m->hash;
mi->next = NULL;
mi->pkt_len = mi->data_len;
mi->nb_segs = 1;
- mi->ol_flags = md->ol_flags | IND_ATTACHED_MBUF;
- mi->packet_type = md->packet_type;
+ mi->ol_flags = m->ol_flags | IND_ATTACHED_MBUF;
+ mi->packet_type = m->packet_type;
__rte_mbuf_sanity_check(mi, 1);
- __rte_mbuf_sanity_check(md, 0);
+ __rte_mbuf_sanity_check(m, 0);
}
/**
- * Detach an indirect packet mbuf -
+ * Detach an indirect packet mbuf.
+ *
* - restore original mbuf address and length values.
* - reset pktmbuf data and data_len to their default values.
* All other fields of the given packet mbuf will be left intact.
* @param m
* The indirect attached packet mbuf.
*/
-
static inline void rte_pktmbuf_detach(struct rte_mbuf *m)
{
- const struct rte_mempool *mp = m->pool;
- void *buf = RTE_MBUF_TO_BADDR(m);
- uint32_t buf_len = mp->elt_size - sizeof(*m);
- m->buf_physaddr = rte_mempool_virt2phy(mp, m) + sizeof (*m);
+ struct rte_mempool *mp = m->pool;
+ uint32_t mbuf_size, buf_len, priv_size;
- m->buf_addr = buf;
- m->buf_len = (uint16_t)buf_len;
-
- m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
- RTE_PKTMBUF_HEADROOM : m->buf_len;
+ priv_size = rte_pktmbuf_priv_size(mp);
+ mbuf_size = sizeof(struct rte_mbuf) + priv_size;
+ buf_len = rte_pktmbuf_data_room_size(mp);
+ m->priv_size = priv_size;
+ m->buf_addr = (char *)m + mbuf_size;
+ m->buf_physaddr = rte_mempool_virt2phy(mp, m) + mbuf_size;
+ m->buf_len = (uint16_t)buf_len;
+ m->data_off = RTE_MIN(RTE_PKTMBUF_HEADROOM, (uint16_t)m->buf_len);
m->data_len = 0;
-
m->ol_flags = 0;
}
* - free attached mbuf segment
*/
if (RTE_MBUF_INDIRECT(m)) {
- struct rte_mbuf *md = RTE_MBUF_FROM_BADDR(m->buf_addr);
+ struct rte_mbuf *md = rte_mbuf_from_indirect(m);
rte_pktmbuf_detach(m);
if (rte_mbuf_refcnt_update(md, -1) == 0)
__rte_mbuf_raw_free(md);