On Sun, Jun 26, 2016 at 9:54 PM, William Tu <u9012...@gmail.com> wrote:

> Hi Darrell,
>
> Thanks for you feedback!
>
> On Sun, Jun 26, 2016 at 8:02 PM, Darrell Ball <dlu...@gmail.com> wrote:
> >
> >
> > On Sat, Jun 25, 2016 at 7:44 AM, William Tu <u9012...@gmail.com> wrote:
> >>
> >> Commit 1895cc8dbb64 ("dpif-netdev: create batch object") introduces
> >> batch process functions and 'struct dp_packet_batch' to associate with
> >> batch-level metadata.  This patch applies the packet batch object to
> >> the netdev provider interface (dummy, Linux, BSD, and DPDK) so that
> >> batch APIs can be used in providers.  With batch metadata visible in
> >> providers, optimizations can be introduced at per-batch level instead
> >> of per-packet.
> >>
> >> Tested-at: https://travis-ci.org/williamtu/ovs-travis/builds/140135888
> >
> >
> > The test shows as failed ?
>
> it's due to one of the OVN testcases, which sometimes fails.
>
> >
> > The code change is replacing an array of ptrs to packets and count with a
> > packet batch and replacing some code blocks with equivalent existing
> inline
> > functions based on batchs.
> >
> > I have some comments inline.
> >
> >> @@ -681,10 +682,12 @@ netdev_bsd_rxq_drain(struct netdev_rxq *rxq_)
> >>   */
> >>  static int
> >>  netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED,
> >> -                struct dp_packet **pkts, int cnt, bool may_steal)
> >> +                struct dp_packet_batch *batch, bool may_steal)
> >>  {
> >>      struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
> >>      const char *name = netdev_get_name(netdev_);
> >> +    int cnt = batch->count;
> >> +    struct dp_packet **okts = batch->packets;
> >
> >
> >
> > "okts" is not used in the function; "pkts" is used in the function.
> > The function will no longer work.
>
> my mistake, will fix it in next version. thanks!
>

Please check that it builds and test



>
> >
> >> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
> >> index ed14a21..3b1e7fa 100644
> >> --- a/lib/netdev-dpdk.c
> >> +++ b/lib/netdev-dpdk.c
> >> @@ -1251,12 +1251,14 @@ netdev_dpdk_vhost_update_rx_counters(struct
> >> netdev_stats *stats,
> >>   */
> >>  static int
> >>  netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
> >> -                           struct dp_packet **packets, int *c)
> >> +                           struct dp_packet_batch *batch)
> >>  {
> >>      struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
> >>      struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
> >>      int qid = rxq->queue_id;
> >>      struct ingress_policer *policer =
> >> netdev_dpdk_get_ingress_policer(dev);
> >> +    struct dp_packet **packets = batch->packets;
> >> +    int *c = &batch->count;
> >
> >
> > I see this pattern throughout where extra variables are used in all
> > functions.
> > There are 2 local variables for packets and count and also the batch
> > parameter,
> > which itself already has reference to packets and count from the start of
> > the call chain
> > in netdev_*().
> >
> > Pre-change, there are two parameters for packets and count derived from
> the
> > batch
> > parameter at the start of the call chain in netdev_*().
> >
> > These functions are intended to be fast.
>
> I don't think adding these 2 extra local variables will have overhead,
> I believe it's the same because compiler will optimize it.
>

Please don't make that general assumption



>
> >> @@ -1517,7 +1519,12 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid,
> >> struct dp_packet **pkts,
> >>      }
> >>
> >>      if (dev->type == DPDK_DEV_VHOST) {
> >> -        __netdev_dpdk_vhost_send(netdev, qid, (struct dp_packet **)
> >> mbufs, newcnt, true);
> >> +        struct dp_packet_batch mbatch;
> >> +
> >> +        dp_packet_batch_init(&mbatch);
> >> +        mbatch.count = newcnt;
> >> +        memcpy(mbatch.packets, mbufs, newcnt * sizeof(struct rte_mbuf
> >> *));
> >>
> >> +        __netdev_dpdk_vhost_send(netdev, qid, &mbatch, true);
> >
> >
> > This looks more expensive to me in terms of processing performance in
> this
> > caller especially and also the callee.
> > This code is intended to be fast.
>
> This isn't copying the packet contents but only the array of 8byte
> pointers.


8 bytes vs 4 bytes vs ... depends on your system arch.


> It definitely has some overhead but should be minor.
>


To avoid any further confusion, below is the datastructure,
where the packet pointer array is sized at 32, today.

So it is a 256 bytes (for 8 byte addresses) allocation and memcpy
for each batch.

enum { NETDEV_MAX_BURST = 32 }

struct dp_packet_batch {
    int count;
    bool trunc; /* true if the batch needs truncate. */
    >>>>  struct dp_packet *packets[NETDEV_MAX_BURST]; <<<<
};

The point is this is extra overhead for code that tries to be fast.



>
> Regards,
> William
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to