> > The dp_packet_put*() function - dp_packet_put_uninit(), dp_packet_put() > and dp_packet_put_zeros() - are, in their current implementation, > operating on the data buffer of a dp_packet as if it were contiguous, > which in the case of multi-segment mbufs means they operate on the first > mbuf in the chain. However, in the case of dp_packet_put_uninit(), for > example, it is the data length of the last mbuf in the mbuf chain that > should be adjusted. These functions have thus been modified to support > multi-segment mbufs. > > Additionally, most of the core logic in dp_pcket_put_uninit() was moved > to a new helper function, dp_packet_put_uninit()_, to abstract the > implementation details from the API, since in the case of multi-seg > mbufs a new struct is returned that holds the mbuf and offset that > constitute the tail. For the single mbuf case a pointer to the byte that > constitute the tail still returned. > > Co-authored-by: Mark Kavanagh <[email protected]> > > Signed-off-by: Mark Kavanagh <[email protected]> > Signed-off-by: Tiago Lam <[email protected]> > --- > lib/dp-packet.c | 97 > +++++++++++++++++++++++++++++++++++++++++++++++++-------- > lib/dp-packet.h | 5 +++ > 2 files changed, 89 insertions(+), 13 deletions(-) > > diff --git a/lib/dp-packet.c b/lib/dp-packet.c > index 782e7c2..1b39946 100644 > --- a/lib/dp-packet.c > +++ b/lib/dp-packet.c > @@ -312,27 +312,66 @@ dp_packet_shift(struct dp_packet *b, int delta) > } > } > > -/* Appends 'size' bytes of data to the tail end of 'b', reallocating and > - * copying its data if necessary. Returns a pointer to the first byte of the > - * new data, which is left uninitialized. */
Is the function rte_pktmbuf_append() (http://dpdk.org/doc/api/rte__mbuf_8h.html#ad5b0cd686ad3bcbb83416ca8395a080b) of any use here? > -void * > -dp_packet_put_uninit(struct dp_packet *b, size_t size) > +static void * > +dp_packet_put_uninit_(struct dp_packet *b, size_t size) > { > void *p; > dp_packet_prealloc_tailroom(b, size); > +#ifdef DPDK_NETDEV > + p = dp_packet_mbuf_tail(b); > + /* In the case of multi-segment mbufs, the data length of the last mbuf > + * should be adjusted by 'size' bytes. The packet length of the entire > + * mbuf chain (stored in the first mbuf of said chain) is adjusted in > + * the normal execution path below. > + */ > + > + struct rte_mbuf *tmbuf = (struct rte_mbuf *) p; > + struct mbuf_tail *mbuf_tail = xmalloc(sizeof(*mbuf_tail)); > + size_t pkt_len = size; > + > + mbuf_tail->mbuf = tmbuf; > + mbuf_tail->ofs = tmbuf->data_len; > + > + /* Adjust size of intermediate mbufs from current tail to end */ > + while (tmbuf && pkt_len > 0) { > + tmbuf->data_len = MIN(pkt_len, tmbuf->buf_len - tmbuf->data_off); > + pkt_len -= tmbuf->data_len; > + > + tmbuf = tmbuf->next; > + } > + > + p = (void *) mbuf_tail; > +#else > p = dp_packet_tail(b); > +#endif > dp_packet_set_size(b, dp_packet_size(b) + size); > + > return p; > } > > -/* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is > - * reallocated and copied if necessary. Returns a pointer to the first byte > of > - * the data's location in the dp_packet. */ > +static void * > +dp_packet_tail_to_addr(struct dp_packet *b OVS_UNUSED, void *p) { > +#ifdef DPDK_NETDEV > + struct mbuf_tail *mbuf_tail = (struct mbuf_tail *) p; > + p = (void *) rte_pktmbuf_mtod_offset(mbuf_tail->mbuf, void *, > + mbuf_tail->ofs); > +#endif > + > + return p; > +} > + > +/* Appends 'size' bytes of data to the tail end of 'b', reallocating and > + * copying its data if necessary. Returns a pointer to the first byte of the > + * new data, which is left uninitialized. */ > void * > -dp_packet_put_zeros(struct dp_packet *b, size_t size) > +dp_packet_put_uninit(struct dp_packet *b, size_t size) > { > - void *dst = dp_packet_put_uninit(b, size); > - memset(dst, 0, size); > + void *tail = dp_packet_put_uninit_(b, size); > + > + void *dst = dp_packet_tail_to_addr(b, tail); > + > + free(tail); For the !DPDK_NETDEV case, the code remains the same (as it should) except this call to free(). It could maybe cause a problem. > + > return dst; > } > > @@ -342,8 +381,40 @@ dp_packet_put_zeros(struct dp_packet *b, size_t > size) > void * > dp_packet_put(struct dp_packet *b, const void *p, size_t size) > { > - void *dst = dp_packet_put_uninit(b, size); > - memcpy(dst, p, size); > + void *tail = dp_packet_put_uninit_(b, size); > +#ifdef DPDK_NETDEV > + struct mbuf_tail *mbuf_tail = (struct mbuf_tail *) tail; > + > + dp_packet_mbuf_write(mbuf_tail->mbuf, mbuf_tail->ofs, size, p); This function doesn't exist yet. > +#else > + memcpy(tail, p, size); > +#endif > + > + void *dst = dp_packet_tail_to_addr(b, tail); > + > + free(tail); > + > + return dst; > +} > + > +/* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is > + * reallocated and copied if necessary. Returns a pointer to the first byte > of > + * the data's location in the dp_packet. */ > +void * > +dp_packet_put_zeros(struct dp_packet *b, size_t size) > +{ > + void *dst; > +#ifdef DPDK_NETDEV > + char zeros[size]; > + memset(zeros, 0, size); > + > + dst = dp_packet_put(b, zeros, size); > + > + return dst; > +#endif > + dst = dp_packet_put_uninit(b, size); > + memset(dst, 0, size); > + > return dst; > } > > diff --git a/lib/dp-packet.h b/lib/dp-packet.h > index 4d4b420..2fa6205 100644 > --- a/lib/dp-packet.h > +++ b/lib/dp-packet.h > @@ -83,6 +83,11 @@ struct dp_packet { > #ifdef DPDK_NETDEV > #define MBUF_BUF_END(BUF_ADDR, BUF_LEN) \ > (char *) (((char *) BUF_ADDR) + BUF_LEN) > + > +struct mbuf_tail { > + struct rte_mbuf *mbuf; > + uint16_t ofs; > +}; > #endif > > static inline void *dp_packet_data(const struct dp_packet *); > -- > 2.7.4 > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
