On 30/01/2016 17:30, "Andy Zhou" <az...@ovn.org> wrote:
> > >On Thu, Jan 28, 2016 at 5:56 PM, Daniele Di Proietto ><diproiet...@vmware.com> wrote: > >When a group of packets arrives from a port, we loop through them to >initialize metadata and them we loop through them again to extract the >flow and perform the exact match classification. > >This commit combines the two loops into one, and initializes packet->md >in emc_processing() to improve performance. > >Since emc_processing() might also be called after recirculation (in >which case the metadata is already valid), an extra parameter is added >to support both cases. > >This commits also implements simple prefetching of packet metadata, >to further improve performance. > >Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com> > > > > >This patch provides significant performance boost for DPDK single core >packet forwarding rate. >I was able to verify line rate forwarding of 64 byte packets over a 10G >NIC. Nice job! > > >Acked-by: Andy Zhou <az...@ovn.org> > Thanks for the review! > > >In comments inline : s/and them/and then/. > fixed > > >Unfortunately, the code reality dropped. May be it is a small price to >pay for optimizing fast path code? >The following incremental patch may help to regain some lost code >readability. Please feel free to fold it in if you >like. I agree, it complicates the code a little bit, but I think your incremental helps, so I rolled it in. I sent a v2, since Sugesh had some comments also > > >diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c >index c38ff2d..43836d2 100644 >--- a/lib/dpif-netdev.c >+++ b/lib/dpif-netdev.c >@@ -478,8 +478,9 @@ static void dp_netdev_execute_actions(struct >dp_netdev_pmd_thread *pmd, > const struct nlattr *actions, > size_t actions_len); > static void dp_netdev_input(struct dp_netdev_pmd_thread *, >- struct dp_packet **, int cnt, >- bool mdinit, odp_port_t port_no); >+ struct dp_packet **, int cnt, odp_port_t >port_no); >+static void dp_netdev_recirculate(struct dp_netdev_pmd_thread *, >+ struct dp_packet **, int cnt); > > static void dp_netdev_disable_upcall(struct dp_netdev *); > static void dp_netdev_pmd_reload_done(struct dp_netdev_pmd_thread *pmd); >@@ -2559,7 +2560,7 @@ dp_netdev_process_rxq_port(struct >dp_netdev_pmd_thread *pmd, > *recirc_depth_get() = 0; > > cycles_count_start(pmd); >- dp_netdev_input(pmd, packets, cnt, false, port->port_no); >+ dp_netdev_input(pmd, packets, cnt, port->port_no); > cycles_count_end(pmd, PMD_CYCLES_PROCESSING); > } else if (error != EAGAIN && error != EOPNOTSUPP) { > static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); >@@ -3286,14 +3287,14 @@ dp_netdev_queue_batches(struct dp_packet *pkt, > * The function returns the number of packets that needs to be processed >in the > * 'packets' array (they have been moved to the beginning of the vector). > * >- * If 'mdinit' is false, the metadata in 'packets' is not valid and must >be >+ * If 'md_is_valid' is false, the metadata in 'packets' is not valid and >must be > * initialized by this function using 'port_no'. > */ > static inline size_t > emc_processing(struct dp_netdev_pmd_thread *pmd, struct dp_packet >**packets, > size_t cnt, struct netdev_flow_key *keys, > struct packet_batch batches[], size_t *n_batches, >- bool mdinit,odp_port_t port_no) >+ bool md_is_valid, odp_port_t port_no) > { > struct emc_cache *flow_cache = &pmd->flow_cache; > struct netdev_flow_key key; >@@ -3314,7 +3315,7 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, >struct dp_packet **packets, > pkt_metadata_prefetch_init(&packets[i+1]->md); > } > >- if (!mdinit) { >+ if (!md_is_valid) { > pkt_metadata_init(&packets[i]->md, port_no); > } > miniflow_extract(packets[i], &key.mf); >@@ -3482,11 +3483,11 @@ fast_path_processing(struct dp_netdev_pmd_thread >*pmd, > * For performance reasons a caller may choose not to initialize the >metadata > * in 'packets': in this case 'mdinit' is false and this function needs >to > * initialize it using 'port_no'. If the metadata in 'packets' is >already >- * valid, 'mdinit' must be true and 'port_no' will be ignored. */ >+ * valid, 'md_is_valid' must be true and 'port_no' will be ignored. */ > static void >-dp_netdev_input(struct dp_netdev_pmd_thread *pmd, >- struct dp_packet **packets, int cnt, >- bool mdinit, odp_port_t port_no) >+dp_netdev_input__(struct dp_netdev_pmd_thread *pmd, >+ struct dp_packet **packets, int cnt, >+ bool md_is_valid, odp_port_t port_no) > { > #if !defined(__CHECKER__) && !defined(_WIN32) > const size_t PKT_ARRAY_SIZE = cnt; >@@ -3501,7 +3502,7 @@ dp_netdev_input(struct dp_netdev_pmd_thread *pmd, > > n_batches = 0; > newcnt = emc_processing(pmd, packets, cnt, keys, batches, &n_batches, >- mdinit, port_no); >+ md_is_valid, port_no); > if (OVS_UNLIKELY(newcnt)) { > fast_path_processing(pmd, packets, newcnt, keys, batches, >&n_batches); > } >@@ -3515,6 +3516,21 @@ dp_netdev_input(struct dp_netdev_pmd_thread *pmd, > } > } > >+static void >+dp_netdev_input(struct dp_netdev_pmd_thread *pmd, >+ struct dp_packet **packets, int cnt, >+ odp_port_t port_no) >+{ >+ dp_netdev_input__(pmd, packets, cnt, false, port_no); >+} >+ >+static void >+dp_netdev_recirculate(struct dp_netdev_pmd_thread *pmd, >+ struct dp_packet **packets, int cnt) >+{ >+ dp_netdev_input__(pmd, packets, cnt, true, 0); >+} >+ > struct dp_netdev_execute_aux { > struct dp_netdev_pmd_thread *pmd; > }; >@@ -3618,7 +3634,7 @@ dp_execute_cb(void *aux_, struct dp_packet >**packets, int cnt, > err = push_tnl_action(dp, a, packets, cnt); > if (!err) { > (*depth)++; >- dp_netdev_input(pmd, packets, cnt, true, 0); >+ dp_netdev_recirculate(pmd, packets, cnt); > (*depth)--; > } else { > dp_netdev_drop_packets(tnl_pkt, cnt, !may_steal); >@@ -3649,7 +3665,7 @@ dp_execute_cb(void *aux_, struct dp_packet >**packets, int cnt, > } > > (*depth)++; >- dp_netdev_input(pmd, packets, cnt, true, 0); >+ dp_netdev_recirculate(pmd, packets, cnt); > (*depth)--; > } else { > dp_netdev_drop_packets(tnl_pkt, cnt, !may_steal); >@@ -3707,7 +3723,7 @@ dp_execute_cb(void *aux_, struct dp_packet >**packets, int cnt, > } > > (*depth)++; >- dp_netdev_input(pmd, packets, cnt, true, 0); >+ dp_netdev_recirculate(pmd, packets, cnt); > (*depth)--; > > return; > > > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev