[ovs-dev] [PATCH] ofproto: Fix statistics of datapath operations.
If 'stats->n_packets' is less than 'op->ukey->stats.n_packets', the calculation result will be wrong. 'stats->n_bytes' is the same. Signed-off-by: zhaozhanxu --- ofproto/ofproto-dpif-upcall.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 5e08ef10d..80678f843 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2385,8 +2385,12 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops) transition_ukey(op->ukey, UKEY_EVICTED); push->used = MAX(stats->used, op->ukey->stats.used); push->tcp_flags = stats->tcp_flags | op->ukey->stats.tcp_flags; -push->n_packets = stats->n_packets - op->ukey->stats.n_packets; -push->n_bytes = stats->n_bytes - op->ukey->stats.n_bytes; +push->n_packets = (stats->n_packets > op->ukey->stats.n_packets + ? stats->n_packets - op->ukey->stats.n_packets + : 0); +push->n_bytes = (stats->n_bytes > op->ukey->stats.n_bytes + ? stats->n_bytes - op->ukey->stats.n_bytes + : 0); ovs_mutex_unlock(>ukey->mutex); } else { push = stats; -- 2.20.1 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH V3] Add offload packets statistics
Hi Simon, Thanks very much for your advice. V3===>V4: 1. Modify the parameter from '-m/--more' to '--offload-stats'. 2. Rename the structure from 'pkts_stats' to 'pkt_stats'. 3. Change the position of some code comments. 4. Rename from 'verbosity' to 'offload_stats'. 5. Some modifications based on the rest of your advice. The patch link:https://mail.openvswitch.org/pipermail/ovs-dev/2019-December/365559.html At 2019-12-04 20:23:23, "Simon Horman" wrote: >On Mon, Oct 28, 2019 at 08:19:48PM +0800, zhaozhanxu wrote: >> Add argument '-m' or '--more' for command ovs-appctl bridge/dump-flows >> to display the offloaded packets statistics. > >Hi zhaozhanxu, > >thanks for this patch. > >Overall this looks good to me. I have added a few minor comments below. > >> The commands display as below: >> >> orignal command: >> >> ovs-appctl bridge/dump-flows br0 >> >> duration=574s, n_packets=1152, n_bytes=110768, priority=0,actions=NORMAL >> table_id=254, duration=574s, n_packets=0, n_bytes=0, >> priority=2,recirc_id=0,actions=drop >> table_id=254, duration=574s, n_packets=0, n_bytes=0, >> priority=0,reg0=0x1,actions=controller(reason=) >> table_id=254, duration=574s, n_packets=0, n_bytes=0, >> priority=0,reg0=0x2,actions=drop >> table_id=254, duration=574s, n_packets=0, n_bytes=0, >> priority=0,reg0=0x3,actions=drop >> >> new command with argument '-m' or '--more' >> >> Notice: 'n_offload_packets' are a subset of n_packets and 'n_offload_bytes' >> are >> a subset of n_bytes. >> >> ovs-appctl bridge/dump-flows -m br0 >> >> duration=576s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, >> n_offload_bytes=107992, priority=0,actions=NORMAL >> table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=2,recirc_id=0,actions=drop >> table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) >> table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x2,actions=drop >> table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x3,actions=drop >> >> ovs-appctl bridge/dump-flows --more br0 >> >> duration=582s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, >> n_offload_bytes=107992, priority=0,actions=NORMAL >> table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=2,recirc_id=0,actions=drop >> table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) >> table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x2,actions=drop >> table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, >> n_offload_bytes=0, priority=0,reg0=0x3,actions=drop >> >> Signed-off-by: zhaozhanxu >> --- >> NEWS | 2 ++ >> lib/dpif.h | 10 ++ >> ofproto/bond.c | 7 ++-- >> ofproto/ofproto-dpif-upcall.c | 11 +++--- >> ofproto/ofproto-dpif-xlate-cache.c | 8 ++--- >> ofproto/ofproto-dpif-xlate-cache.h | 6 ++-- >> ofproto/ofproto-dpif-xlate.c | 6 ++-- >> ofproto/ofproto-dpif.c | 29 ++-- >> ofproto/ofproto-dpif.h | 4 +-- >> ofproto/ofproto-provider.h | 11 -- >> ofproto/ofproto.c | 55 ++ >> ofproto/ofproto.h | 2 +- >> vswitchd/bridge.c | 15 +--- >> vswitchd/ovs-vswitchd.8.in | 3 +- >> 14 files changed, 108 insertions(+), 61 deletions(-) >> >> diff --git a/NEWS b/NEWS >> index 330ab3832..14023fcf7 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -81,6 +81,8 @@ v2.12.0 - 03 Sep 2019 >> * Add support for conntrack zone-based timeout policy. >> - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded >> flows. >> 'ovs-appctl dpctl/dump-flows' should be used instead. >> + - Add new argument '-m | --more' for command 'ovs-appctl >> bridge/dump-flows', >> + so it can display offloaded packets statistics. >> - Add L2 GRE tunnel over IPv6 support. >> >> v2.11.0 - 19 Feb 2019 >> diff --git a/lib/dpif.h b/lib/dpif.h >> index 289d574a0..7d82a28be 10
[ovs-dev] [PATCH V4] Add offload packets statistics
Add argument '--offload-stats' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=574s, n_packets=1152, n_bytes=110768, priority=0,actions=NORMAL table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '--offload-stats' Notice: 'n_offload_packets' are a subset of n_packets and 'n_offload_bytes' are a subset of n_bytes. ovs-appctl bridge/dump-flows --offload-stats br0 duration=582s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, n_offload_bytes=107992, priority=0,actions=NORMAL table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop Signed-off-by: zhaozhanxu --- NEWS | 3 ++ lib/dpif.h | 12 +++ ofproto/bond.c | 7 ++-- ofproto/ofproto-dpif-upcall.c | 11 --- ofproto/ofproto-dpif-xlate-cache.c | 8 ++--- ofproto/ofproto-dpif-xlate-cache.h | 6 ++-- ofproto/ofproto-dpif-xlate.c | 6 ++-- ofproto/ofproto-dpif.c | 29 +--- ofproto/ofproto-dpif.h | 4 +-- ofproto/ofproto-provider.h | 11 +-- ofproto/ofproto.c | 53 +- ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 17 +++--- vswitchd/ovs-vswitchd.8.in | 5 ++- 14 files changed, 112 insertions(+), 62 deletions(-) diff --git a/NEWS b/NEWS index 330ab3832..d4e0fcb6a 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,9 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. + - Add new argument '--offload-stats' for command + 'ovs-appctl bridge/dump-flows', + so it can display offloaded packets statistics. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 diff --git a/lib/dpif.h b/lib/dpif.h index 289d574a0..e04252f43 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -496,6 +496,18 @@ struct dpif_flow_stats { uint16_t tcp_flags; }; +/* more statistics info for offloaded packets and bytes */ +struct dpif_flow_detailed_stats { +uint64_t n_packets; +uint64_t n_bytes; +/* n_offload_packets are a subset of n_packets */ +uint64_t n_offload_packets; +/* n_offload_bytes are a subset of n_bytes */ +uint64_t n_offload_bytes; +long long int used; +uint16_t tcp_flags; +}; + struct dpif_flow_attrs { bool offloaded; /* True if flow is offloaded to HW. */ const char *dp_layer; /* DP layer the flow is handled in. */ diff --git a/ofproto/bond.c b/ofproto/bond.c index c5d5f2c03..5021ab06e 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -946,13 +946,12 @@ bond_recirculation_account(struct bond *bond) struct rule *rule = entry->pr_rule; if (rule) { -uint64_t n_packets OVS_UNUSED; +struct pkt_stats stats; long long int used OVS_UNUSED; -uint64_t n_bytes; rule->ofproto->ofproto_class->rule_get_stats( -rule, _packets, _bytes, ); -bond_entry_account(entry, n_bytes); +rule, , ); +bond_entry_account(entry, stats.n_bytes); } } } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 657aa7f79..5fdba5b65 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2260,7 +2260,7 @@ static enum reval_result revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, const struct dpif_flow_stats *stats, struct ofpbuf *odp_actions, uint64_t reval_seq, -struct recirc_refs *recircs) +struct recirc_refs *recircs, bool offloaded) OVS_REQUIRES(ukey->mutex) { bool need_revalidate = ukey->reval_seq != reval_seq; @@ -2295,7 +2295,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, /* Stats for deleted flows will be attributed upon flow deletion. Skip. */ if (res
Re: [ovs-dev] [PATCH V2] Add offload packets statistics
Please help me reviewing the code, thanks very much. At 2019-10-28 20:44:51, "zhaozhanxu" wrote: Thanks for your reply. I already modified some of them, and I think the others need to discuss. V2===>V3: 1. Make the n_offload_packets to be a subset of n_packets, and n_offload_bytes to be a subset of n_bytes. 2. Add a new structure 'dpif_flow_detailed_stats' to store the offload statistics, so all the functions you mentioned don't need to modify. I don't think that function 'parse_tc_flower_to_match' should display new fields, all the commands called function 'parse_tc_flower_to_match' are display the datapath flows. The datapath flow would be either non-offloaded or offloaded, so that the statistics are offloaded or non-offloaded depends on datapath flows. The patch link: https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/363942.html At 2019-10-25 08:53:35, "Ben Pfaff" wrote: >On Tue, Oct 15, 2019 at 02:56:23PM +0800, zhaozhanxu wrote: >> Add argument '-m' for command ovs-appctl bridge/dump-flows >> to display the offloaded packets statistics. > >Thanks for the updated patch. > >Are n_offload_packets a subset of n_packets, or in addition to them? If >they are a subset, then n_offload_packets should always be less than or >equal to n_packets; if they are in addition, then there is no >relationship between the two. Either way, this should be explained in >comments on struct dpif_flow_stats. > >I guess that "subset" makes more sense--after all, offloaded packets are >still packets--but then we need to update a few places, like >rule_dpif_credit_stats__(). If we take the "additional" choice, then we >need to change other places: I think most places that n_packets is >referenced, we need to write n_packets + n_offload_packets instead. > >Please also update the documentation for bridge/dump-flows in >ovs-vswitchd(8). > >get_dpif_flow_stats(), in lib/dpif-netdev.c, should initialize '*stats'. >I don't think it initializes the new members, but it should. > >dpif_netdev_flow_put() adds together dpif_flow_stats. Currently I think >those dpif_flow_stats always have zero in n_offload_*, but it might be a >good idea to add them together anyway. > >Actually dpif_netdev_flow_del() does the same thing. Probably that >means it would be a good idea to factor out the code that adds these >things together into a new helper function since there's already >duplicate code and this adds more of it. > >dpif_netlink_flow_get_stats() needs to initialize the new fields. > >dpif_flow_stats_extract() needs to initialize the new fields. > >I imagine that dpif_flow_stats_format() should display the new >fields--perhaps only if they are nonzero? > >Should parse_tc_flower_to_match() set n_offload_* instead of packets and >bytes? (Or both of them to the same values, if n_offload_* is a subset >of the regular values.) > >Ditto for netdev_tc_flow_del(). > >upcall_xlate() should initialize n_offload_*. > >Ditto for revalidate_ukey() and push_dp_ops(). > >Thanks, > >Ben. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH V2] Add offload packets statistics
Thanks for your reply. I already modified some of them, and I think the others need to discuss. V2===>V3: 1. Make the n_offload_packets to be a subset of n_packets, and n_offload_bytes to be a subset of n_bytes. 2. Add a new structure 'dpif_flow_detailed_stats' to store the offload statistics, so all the functions you mentioned don't need to modify. I don't think that function 'parse_tc_flower_to_match' should display new fields, all the commands called function 'parse_tc_flower_to_match' are display the datapath flows. The datapath flow would be either non-offloaded or offloaded, so that the statistics are offloaded or non-offloaded depends on datapath flows. The patch link: https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/363942.html At 2019-10-25 08:53:35, "Ben Pfaff" wrote: >On Tue, Oct 15, 2019 at 02:56:23PM +0800, zhaozhanxu wrote: >> Add argument '-m' for command ovs-appctl bridge/dump-flows >> to display the offloaded packets statistics. > >Thanks for the updated patch. > >Are n_offload_packets a subset of n_packets, or in addition to them? If >they are a subset, then n_offload_packets should always be less than or >equal to n_packets; if they are in addition, then there is no >relationship between the two. Either way, this should be explained in >comments on struct dpif_flow_stats. > >I guess that "subset" makes more sense--after all, offloaded packets are >still packets--but then we need to update a few places, like >rule_dpif_credit_stats__(). If we take the "additional" choice, then we >need to change other places: I think most places that n_packets is >referenced, we need to write n_packets + n_offload_packets instead. > >Please also update the documentation for bridge/dump-flows in >ovs-vswitchd(8). > >get_dpif_flow_stats(), in lib/dpif-netdev.c, should initialize '*stats'. >I don't think it initializes the new members, but it should. > >dpif_netdev_flow_put() adds together dpif_flow_stats. Currently I think >those dpif_flow_stats always have zero in n_offload_*, but it might be a >good idea to add them together anyway. > >Actually dpif_netdev_flow_del() does the same thing. Probably that >means it would be a good idea to factor out the code that adds these >things together into a new helper function since there's already >duplicate code and this adds more of it. > >dpif_netlink_flow_get_stats() needs to initialize the new fields. > >dpif_flow_stats_extract() needs to initialize the new fields. > >I imagine that dpif_flow_stats_format() should display the new >fields--perhaps only if they are nonzero? > >Should parse_tc_flower_to_match() set n_offload_* instead of packets and >bytes? (Or both of them to the same values, if n_offload_* is a subset >of the regular values.) > >Ditto for netdev_tc_flow_del(). > >upcall_xlate() should initialize n_offload_*. > >Ditto for revalidate_ukey() and push_dp_ops(). > >Thanks, > >Ben. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH V3] Add offload packets statistics
Add argument '-m' or '--more' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=574s, n_packets=1152, n_bytes=110768, priority=0,actions=NORMAL table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '-m' or '--more' Notice: 'n_offload_packets' are a subset of n_packets and 'n_offload_bytes' are a subset of n_bytes. ovs-appctl bridge/dump-flows -m br0 duration=576s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, n_offload_bytes=107992, priority=0,actions=NORMAL table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=576s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop ovs-appctl bridge/dump-flows --more br0 duration=582s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, n_offload_bytes=107992, priority=0,actions=NORMAL table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop Signed-off-by: zhaozhanxu --- NEWS | 2 ++ lib/dpif.h | 10 ++ ofproto/bond.c | 7 ++-- ofproto/ofproto-dpif-upcall.c | 11 +++--- ofproto/ofproto-dpif-xlate-cache.c | 8 ++--- ofproto/ofproto-dpif-xlate-cache.h | 6 ++-- ofproto/ofproto-dpif-xlate.c | 6 ++-- ofproto/ofproto-dpif.c | 29 ++-- ofproto/ofproto-dpif.h | 4 +-- ofproto/ofproto-provider.h | 11 -- ofproto/ofproto.c | 55 ++ ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 15 +--- vswitchd/ovs-vswitchd.8.in | 3 +- 14 files changed, 108 insertions(+), 61 deletions(-) diff --git a/NEWS b/NEWS index 330ab3832..14023fcf7 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. + - Add new argument '-m | --more' for command 'ovs-appctl bridge/dump-flows', + so it can display offloaded packets statistics. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 diff --git a/lib/dpif.h b/lib/dpif.h index 289d574a0..7d82a28be 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -496,6 +496,16 @@ struct dpif_flow_stats { uint16_t tcp_flags; }; +/* more statistics info for offloaded packets and bytes */ +struct dpif_flow_detailed_stats { +uint64_t n_packets; /* n_offload_packets are a subset of n_packets */ +uint64_t n_bytes; /* n_offload_bytes are a subset of n_bytes */ +uint64_t n_offload_packets; +uint64_t n_offload_bytes; +long long int used; +uint16_t tcp_flags; +}; + struct dpif_flow_attrs { bool offloaded; /* True if flow is offloaded to HW. */ const char *dp_layer; /* DP layer the flow is handled in. */ diff --git a/ofproto/bond.c b/ofproto/bond.c index c5d5f2c03..03de1eec9 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -946,13 +946,12 @@ bond_recirculation_account(struct bond *bond) struct rule *rule = entry->pr_rule; if (rule) { -uint64_t n_packets OVS_UNUSED; +struct pkts_stats stats; long long int used OVS_UNUSED; -uint64_t n_bytes; rule->ofproto->ofproto_class->rule_get_stats( -rule, _packets, _bytes, ); -bond_entry_account(entry, n_bytes); +rule, , ); +bond_entry_account(entry, stats.n_bytes); } } } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 657aa7f79..5fdba5b65 100644 --- a/ofproto/ofproto-dpif-up
Re: [ovs-dev] [PATCH V1] Add offload packets statistics
Thanks for your advise, I modified the parameters form 'uint64_t packet_count' and 'uint64_t byte_count' to 'struct pkts_stats'. New commit: https://mail.openvswitch.org/pipermail/ovs-dev/2019-October/363518.html At 2019-10-15 03:15:55, "Ben Pfaff" wrote: >On Fri, Oct 11, 2019 at 11:46:29AM +0800, zhaozhanxu wrote: >> Add argument '-m' for command ovs-appctl bridge/dump-flows >> to display the offloaded packets statistics. > >This seems like a reasonable addition, and the code looks OK too. > >Before, with 2 pointers as function parameters, it was OK to have them >individually. I am less comfortable with 4 pointers as function >parameters. Did you consider defining a structure? It might make the >code better. > >Thanks, > >Ben. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH V2] Add offload packets statistics
Add argument '-m' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=243589s, n_packets=214752, n_bytes=223673384, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '-m' ovs-appctl bridge/dump-flows -m br0 duration=243589s, n_packets=140, n_bytes=69284, n_offload_packets=214612, n_offload_bytes=223604100, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop Signed-off-by: zhaozhanxu --- NEWS | 2 + lib/dpif.h | 2 + ofproto/bond.c | 8 ++-- ofproto/ofproto-dpif-upcall.c | 11 +++--- ofproto/ofproto-dpif-xlate-cache.c | 8 ++-- ofproto/ofproto-dpif-xlate-cache.h | 6 ++- ofproto/ofproto-dpif-xlate.c | 6 +-- ofproto/ofproto-dpif.c | 34 ++--- ofproto/ofproto-dpif.h | 2 +- ofproto/ofproto-provider.h | 11 +- ofproto/ofproto.c | 59 +++--- ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 15 ++-- 13 files changed, 105 insertions(+), 61 deletions(-) diff --git a/NEWS b/NEWS index 330ab3832..bf36c3520 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. + - Add new argument '-m' for command 'ovs-appctl bridge/dump-flows', + so it can display offloaded packets statistics. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 diff --git a/lib/dpif.h b/lib/dpif.h index 289d574a0..9a63398a2 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -492,6 +492,8 @@ void dpif_port_poll_wait(const struct dpif *); struct dpif_flow_stats { uint64_t n_packets; uint64_t n_bytes; +uint64_t n_offload_packets; +uint64_t n_offload_bytes; long long int used; uint16_t tcp_flags; }; diff --git a/ofproto/bond.c b/ofproto/bond.c index c5d5f2c03..66642792c 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -946,13 +946,13 @@ bond_recirculation_account(struct bond *bond) struct rule *rule = entry->pr_rule; if (rule) { -uint64_t n_packets OVS_UNUSED; +struct pkts_stats stats; long long int used OVS_UNUSED; -uint64_t n_bytes; rule->ofproto->ofproto_class->rule_get_stats( -rule, _packets, _bytes, ); -bond_entry_account(entry, n_bytes); +rule, , ); +bond_entry_account(entry, + stats.n_bytes + stats.n_offload_bytes); } } } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 657aa7f79..5fdba5b65 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2260,7 +2260,7 @@ static enum reval_result revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, const struct dpif_flow_stats *stats, struct ofpbuf *odp_actions, uint64_t reval_seq, -struct recirc_refs *recircs) +struct recirc_refs *recircs, bool offloaded) OVS_REQUIRES(ukey->mutex) { bool need_revalidate = ukey->reval_seq != reval_seq; @@ -2295,7 +2295,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, /* Stats for deleted flows will be attributed upon flow deletion. Skip. */ if (result != UKEY_DELETE) { -xlate_push_stats(ukey->xcache, ); +xlate_push_stats(ukey->xcache, , offloaded); ukey->stats = *stats; ukey->reval_seq = reval_seq; } @@ -2408,7 +2408,7 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops) if (op->ukey)
[ovs-dev] [PATCH V1] Add offload packets statistics
Add argument '-m' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=243589s, n_packets=214752, n_bytes=223673384, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '-m' ovs-appctl bridge/dump-flows -m br0 duration=243589s, n_packets=140, n_bytes=69284, n_offload_packets=214612, n_offload_bytes=223604100, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop Signed-off-by: zhaozhanxu --- NEWS | 2 + lib/dpif.h | 2 + ofproto/bond.c | 7 +++- ofproto/ofproto-dpif-upcall.c | 11 +++--- ofproto/ofproto-dpif-xlate-cache.c | 8 ++-- ofproto/ofproto-dpif-xlate-cache.h | 6 ++- ofproto/ofproto-dpif-xlate.c | 6 +-- ofproto/ofproto-dpif.c | 29 ++- ofproto/ofproto-dpif.h | 2 +- ofproto/ofproto-provider.h | 5 ++- ofproto/ofproto.c | 59 +++--- ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 15 ++-- 13 files changed, 109 insertions(+), 45 deletions(-) diff --git a/NEWS b/NEWS index 330ab3832..bf36c3520 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. + - Add new argument '-m' for command 'ovs-appctl bridge/dump-flows', + so it can display offloaded packets statistics. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 diff --git a/lib/dpif.h b/lib/dpif.h index 289d574a0..9a63398a2 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -492,6 +492,8 @@ void dpif_port_poll_wait(const struct dpif *); struct dpif_flow_stats { uint64_t n_packets; uint64_t n_bytes; +uint64_t n_offload_packets; +uint64_t n_offload_bytes; long long int used; uint16_t tcp_flags; }; diff --git a/ofproto/bond.c b/ofproto/bond.c index c5d5f2c03..afe6c48aa 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -947,12 +947,15 @@ bond_recirculation_account(struct bond *bond) if (rule) { uint64_t n_packets OVS_UNUSED; +uint64_t n_offload_packets OVS_UNUSED; long long int used OVS_UNUSED; uint64_t n_bytes; +uint64_t n_offload_bytes; rule->ofproto->ofproto_class->rule_get_stats( -rule, _packets, _bytes, ); -bond_entry_account(entry, n_bytes); +rule, _packets, _bytes, _offload_packets, +_offload_bytes, ); +bond_entry_account(entry, n_bytes + n_offload_bytes); } } } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 657aa7f79..5fdba5b65 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2260,7 +2260,7 @@ static enum reval_result revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, const struct dpif_flow_stats *stats, struct ofpbuf *odp_actions, uint64_t reval_seq, -struct recirc_refs *recircs) +struct recirc_refs *recircs, bool offloaded) OVS_REQUIRES(ukey->mutex) { bool need_revalidate = ukey->reval_seq != reval_seq; @@ -2295,7 +2295,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, /* Stats for deleted flows will be attributed upon flow deletion. Skip. */ if (result != UKEY_DELETE) { -xlate_push_stats(ukey->xcache, ); +xlate_push_stats(ukey->xcache, , offloaded); ukey->stats = *stats; ukey->reval_seq = reval_seq; } @@ -2408,7 +2408,7 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops
[ovs-dev] [PATCH 1/1] Add offload packets statistics
Add argument '-m' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=243589s, n_packets=214752, n_bytes=223673384, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '-m' ovs-appctl bridge/dump-flows -m br0 duration=243589s, n_packets=140, n_bytes=69284, n_offload_packets=214612, n_offload_bytes=223604100, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop Signed-off-by: zhaozhanxu --- NEWS | 2 ++ lib/dpif.h | 2 ++ ofproto/bond.c | 7 +++-- ofproto/ofproto-dpif-upcall.c | 10 +++ ofproto/ofproto-dpif-xlate-cache.c | 8 +++--- ofproto/ofproto-dpif-xlate-cache.h | 6 ++-- ofproto/ofproto-dpif-xlate.c | 6 ++-- ofproto/ofproto-dpif.c | 29 +-- ofproto/ofproto-dpif.h | 2 +- ofproto/ofproto-provider.h | 5 +++- ofproto/ofproto.c | 58 +- ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 15 +++--- 13 files changed, 107 insertions(+), 45 deletions(-) diff --git a/NEWS b/NEWS index 330ab3832..bf36c3520 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ v2.12.0 - 03 Sep 2019 * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. + - Add new argument '-m' for command 'ovs-appctl bridge/dump-flows', + so it can display offloaded packets statistics. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 diff --git a/lib/dpif.h b/lib/dpif.h index 289d574a0..9a63398a2 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -492,6 +492,8 @@ void dpif_port_poll_wait(const struct dpif *); struct dpif_flow_stats { uint64_t n_packets; uint64_t n_bytes; +uint64_t n_offload_packets; +uint64_t n_offload_bytes; long long int used; uint16_t tcp_flags; }; diff --git a/ofproto/bond.c b/ofproto/bond.c index c5d5f2c03..afe6c48aa 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -947,12 +947,15 @@ bond_recirculation_account(struct bond *bond) if (rule) { uint64_t n_packets OVS_UNUSED; +uint64_t n_offload_packets OVS_UNUSED; long long int used OVS_UNUSED; uint64_t n_bytes; +uint64_t n_offload_bytes; rule->ofproto->ofproto_class->rule_get_stats( -rule, _packets, _bytes, ); -bond_entry_account(entry, n_bytes); +rule, _packets, _bytes, _offload_packets, +_offload_bytes, ); +bond_entry_account(entry, n_bytes + n_offload_bytes); } } } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 657aa7f79..8ead98115 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2260,7 +2260,7 @@ static enum reval_result revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, const struct dpif_flow_stats *stats, struct ofpbuf *odp_actions, uint64_t reval_seq, -struct recirc_refs *recircs) +struct recirc_refs *recircs, bool offloaded) OVS_REQUIRES(ukey->mutex) { bool need_revalidate = ukey->reval_seq != reval_seq; @@ -2295,7 +2295,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, /* Stats for deleted flows will be attributed upon flow deletion. Skip. */ if (result != UKEY_DELETE) { -xlate_push_stats(ukey->xcache, ); +xlate_push_stats(ukey->xcache, , offloaded); ukey->stats = *stats; ukey->reval_seq = reval_seq; } @@ -2408,7 +2408,7 @@ push_dp_ops(struct udpif *udpif, struct
[ovs-dev] [PATCH 0/1] Add offload packets statistics
Add argument '-m' for command ovs-appctl bridge/dump-flows to display the offloaded packets statistics. The commands display as below: orignal command: ovs-appctl bridge/dump-flows br0 duration=243589s, n_packets=214752, n_bytes=223673384, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop new command with argument '-m' ovs-appctl bridge/dump-flows -m br0 duration=243589s, n_packets=140, n_bytes=69284, n_offload_packets=214612, n_offload_bytes=223604100, priority=0,actions=NORMAL table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=) table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop table_id=254, duration=243589s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop zhaozhanxu (1): Add offload packets statistics NEWS | 2 ++ lib/dpif.h | 2 ++ ofproto/bond.c | 7 +++-- ofproto/ofproto-dpif-upcall.c | 10 +++ ofproto/ofproto-dpif-xlate-cache.c | 8 +++--- ofproto/ofproto-dpif-xlate-cache.h | 6 ++-- ofproto/ofproto-dpif-xlate.c | 6 ++-- ofproto/ofproto-dpif.c | 29 +-- ofproto/ofproto-dpif.h | 2 +- ofproto/ofproto-provider.h | 5 +++- ofproto/ofproto.c | 58 +- ofproto/ofproto.h | 2 +- vswitchd/bridge.c | 15 +++--- 13 files changed, 107 insertions(+), 45 deletions(-) -- 2.14.1 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH v2 0/4] netdev-dpdk: Support the multi-queue QoS for dpdk datapath
This patch adds similar QoS construction with kernel datapath. Original command as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048` New command as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048 \ queues:123=@q123 queues:234=@q234 -- \ --id=@q123 create queue \ other-config:cir=1280 other-config:cbs=2048 -- \ --id=@q234 create queue \ other-config:cir=2560 other-config:cbs=2048` Through new command, QoS and multi-queue will to be set, then use OpenFlow to direct packet to queues: $ ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal $ ovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal Finally, show QoS and its queues information through command as below: $ ovs-appctl -t ovs-vswitchd qos/show vhost-user0 I respined the patches based on review feedback at: https://mail.openvswitch.org/pipermail/ovs-dev/2017-July/336141.html Patch 1: Add multi-queue QoS configuration. Patch 2: Add multi-queue QoS function. Patch 3: Add QoS queues information to show. Patch 4: Modify QoS configuration command. -- V1->V2: 1. modified some code style error for every patch noticed by Ian. 2. modified some patch error for patch 1-3 noticed for by Ian. 3. modified documents error for patch 4. zhaozhanxu (4): netdev-dpdk.c: Support the multi-queue QoS configuration for dpdk datapath netdev-dpdk.c: Support multi-queue QoS rate limitation function for dpdk datapath netdev-dpdk.c: Support to show multi-queue qos info for dpdk datapath dpdk.rst: Modify QoS configure documents for ovs-dpdk Documentation/howto/dpdk.rst | 14 +- lib/netdev-dpdk.c| 387 +-- 2 files changed, 389 insertions(+), 12 deletions(-) -- 2.7.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH v2 3/4] netdev-dpdk.c: Support to show multi-queue qos info for dpdk datapath
This patch support command `ovs-appctl -t ovs-vswitchd qos/show vhost-user0` to show QoS and its queues information. It adds some functions whitch is pointed by `get_queue_stats`, `queue_dump_start`, `queue_dump_next` and `queue_dump_done` of structure `netdev_class` to show queue information. Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/netdev-dpdk.c | 155 -- 1 file changed, 150 insertions(+), 5 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 85f077e..641ddfa 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -284,6 +284,10 @@ struct dpdk_qos_ops { */ int (*qos_queue_get)(struct smap *details, uint32_t queue_id, const struct qos_conf *conf); + +/* Retrieves statistics of QoS Queue configuration into 'details'. */ +int (*qos_queue_get_stats)(const struct qos_conf *conf, uint32_t queue_id, + struct netdev_queue_stats *stats); }; /* dpdk_qos_ops for each type of user space QoS implementation */ @@ -3079,6 +3083,28 @@ netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id) return 0; } +static int +netdev_dpdk_get_queue_stats(const struct netdev *netdev, uint32_t queue_id, +struct netdev_queue_stats *stats) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get_stats) { +qos_conf->ops->qos_queue_get_stats(qos_conf, queue_id, stats); +} else { +error = EOPNOTSUPP; +} + +ovs_mutex_unlock(>mutex); + +return error; +} + /* egress-policer details */ struct egress_policer { @@ -3088,13 +3114,100 @@ struct egress_policer { struct hmap queue; }; +struct egress_queue_stats { +uint64_t tx_bytes; +uint64_t tx_packets; +uint64_t tx_errors; + +long long int created; +}; + struct egress_queue_policer { struct hmap_node hmap_node; uint32_t queue_id; struct rte_meter_srtcm_params app_srtcm_params; struct rte_meter_srtcm egress_meter; +struct egress_queue_stats stats; +}; + +struct netdev_dpdk_queue_state { +uint32_t *queues; +size_t cur_queue; +size_t n_queues; }; +static int +netdev_dpdk_queue_dump_start(const struct netdev *netdev, void **statep) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf) { +struct netdev_dpdk_queue_state *state; +struct egress_policer *policer = +CONTAINER_OF(qos_conf, struct egress_policer, qos_conf); + +*statep = state = xmalloc(sizeof *state); +state->n_queues = hmap_count(>queue); +state->cur_queue = 0; +state->queues = xmalloc(state->n_queues * sizeof *state->queues); + +uint32_t i = 0; +struct egress_queue_policer *queue_policer; +HMAP_FOR_EACH (queue_policer, hmap_node, >queue) { +state->queues[i++] = queue_policer->queue_id; +} +} else { +error = EOPNOTSUPP; +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_queue_dump_next(const struct netdev *netdev, void *state_, +uint32_t *queue_idp, struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct netdev_dpdk_queue_state *state = state_; +struct qos_conf *qos_conf; +int error = EOF; + +ovs_mutex_lock(>mutex); + +while (state->cur_queue < state->n_queues) { +uint32_t queue_id = state->queues[state->cur_queue++]; + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get) { +*queue_idp = queue_id; +error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf); +break; +} +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_queue_dump_done(const struct netdev *netdev OVS_UNUSED, +void *state_) +{ +struct netdev_dpdk_queue_state *state = state_; + +free(state->queues); +free(state); +return 0; +} + static struct egress_queue_policer * egress_policer_qos_find_queue(struct egress_policer *policer, uint32_t queue_id); @@ -3185,7 +3298,11 @@ egress_policer_pkt_handle(struct egress_policer *policer, if (queue_policer) { if (rte_meter_srtcm_color_blind_check(_policer->egress_meter,
[ovs-dev] [PATCH v2 1/4] netdev-dpdk.c: Support the multi-queue QoS configuration for dpdk datapath
This patch adds similar QoS configration with kernel datapath. It adds some functions whitch is pointed by `get_queue`, `set_queue` and `delete_queue` of structure `netdev_class` to support configuration. Then the configuration command changed from command A(see below) to command B, but it only support to configure and rate limitation function is not ready now. Command A: (original command) $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048` Command B: (new command) $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048 \ queues:123=@q123 queues:234=@q234 -- \ --id=@q123 create queue \ other-config:cir=1280 other-config:cbs=2048 -- \ --id=@q234 create queue \ other-config:cir=2560 other-config:cbs=2048` Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/netdev-dpdk.c | 197 -- 1 file changed, 193 insertions(+), 4 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index ea17b97..089ad64 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -259,6 +259,31 @@ struct dpdk_qos_ops { */ int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts, int pkt_cnt); + +/* Called to construct a QoS Queue. The implementation should make + * the appropriate calls to configure QoS Queue according to 'details'. + * + * The contents of 'details' should be documented as valid for 'ovs_name' + * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml + * (which is built as ovs-vswitchd.conf.db(8)). + * + * This function must return 0 if and only if it constructs + * qos queue successfully. + */ +int (*qos_queue_construct)(const struct smap *details, + uint32_t queue_id, struct qos_conf *conf); + +/* Destroys the Qos Queue */ +void (*qos_queue_destruct)(struct qos_conf *conf, uint32_t queue_id); + +/* Retrieves details of QoS Queue configuration into 'details'. + * + * The contents of 'details' should be documented as valid for 'ovs_name' + * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml + * (which is built as ovs-vswitchd.conf.db(8)). + */ +int (*qos_queue_get)(struct smap *details, uint32_t queue_id, + const struct qos_conf *conf); }; /* dpdk_qos_ops for each type of user space QoS implementation */ @@ -2986,14 +3011,94 @@ netdev_dpdk_set_qos(struct netdev *netdev, const char *type, return error; } +static int +netdev_dpdk_get_queue(const struct netdev *netdev, uint32_t queue_id, + struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_get) { +error = EOPNOTSUPP; +} else { +error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf); +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_set_queue(struct netdev *netdev, uint32_t queue_id, + const struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_construct) { +error = EOPNOTSUPP; +} else { +error = qos_conf->ops->qos_queue_construct(details, queue_id, + qos_conf); +} + +if (error) { +VLOG_ERR("Failed to set QoS queue %d on port %s: %s", + queue_id, netdev->name, rte_strerror(error)); +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_destruct) { +qos_conf->ops->qos_queue_destruct(qos_conf, queue_id); +} + +ovs_mutex_unlock(>mutex); + +return 0; +} + /* egress-policer details */ struct egress_policer { struct qos_conf qos_conf; struct rte_meter_srtcm_params app_srtcm_params; struct rte_meter_srtcm egress_meter; +struct hmap queue
[ovs-dev] [PATCH 3/4] Support to show multi-queue qos info
Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/netdev-dpdk.c | 147 -- 1 file changed, 142 insertions(+), 5 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 49816ca..9d6a87c 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -284,6 +284,11 @@ struct dpdk_qos_ops { */ int (*qos_queue_get)(struct smap *details, uint32_t queue_id, const struct qos_conf *conf); + +/* Retrieves statistics of QoS Queue configuration into 'details'. + */ +int (*qos_queue_get_stats)(const struct qos_conf *conf, uint32_t queue_id, + struct netdev_queue_stats *stats); }; /* dpdk_qos_ops for each type of user space QoS implementation */ @@ -3078,6 +3083,28 @@ netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id) return 0; } +static int +netdev_dpdk_get_queue_stats(const struct netdev *netdev, uint32_t queue_id, +struct netdev_queue_stats *stats) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get_stats) { +qos_conf->ops->qos_queue_get_stats(qos_conf, queue_id, stats); +} else { +error = EOPNOTSUPP; +} + +ovs_mutex_unlock(>mutex); + +return error; +} + /* egress-policer details */ struct egress_policer { @@ -3087,6 +3114,14 @@ struct egress_policer { struct hmap queue; }; +struct egress_queue_stats { +uint64_t tx_bytes; +uint64_t tx_packets; +uint64_t tx_errors; + +long long int created; +}; + struct egress_queue_policer { struct hmap_node hmap_node; uint32_t queue_id; @@ -3095,6 +3130,83 @@ struct egress_queue_policer { struct egress_queue_stats stats; }; +struct netdev_dpdk_queue_state { +uint32_t *queues; +size_t cur_queue; +size_t n_queues; +}; + +static int +netdev_dpdk_queue_dump_start(const struct netdev *netdev, void **statep) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf) { +struct netdev_dpdk_queue_state *state; +struct egress_policer *policer = CONTAINER_OF(qos_conf, struct egress_policer, + qos_conf); + +*statep = state = xmalloc(sizeof *state); +state->n_queues = hmap_count(>queue); +state->cur_queue = 0; +state->queues = xmalloc(state->n_queues * sizeof *state->queues); + +uint32_t i = 0; +struct egress_queue_policer *queue_policer; +HMAP_FOR_EACH (queue_policer, hmap_node, >queue) { +state->queues[i++] = queue_policer->queue_id; +} +} else { +error = EOPNOTSUPP; +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_queue_dump_next(const struct netdev *netdev, void *state_, +uint32_t *queue_idp, struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct netdev_dpdk_queue_state *state = state_; +struct qos_conf *qos_conf; +int error = EOF; + +ovs_mutex_lock(>mutex); + +while (state->cur_queue < state->n_queues) { +uint32_t queue_id = state->queues[state->cur_queue++]; + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get) { +*queue_idp = queue_id; +error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf); +break; +} +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_queue_dump_done(const struct netdev *netdev OVS_UNUSED, void *state_) +{ +struct netdev_dpdk_queue_state *state = state_; + +free(state->queues); +free(state); +return 0; +} + static struct egress_queue_policer * egress_policer_qos_find_queue(struct egress_policer *policer, uint32_t queue_id); @@ -3286,6 +3398,30 @@ egress_policer_qos_queue_get(struct smap *details, uint32_t queue_id, const stru return 0; } +static int +egress_policer_qos_queue_get_stats(const struct qos_conf *conf, uint32_t queue_id, + struct netdev_queue_stats *stats) +{ +struct egress_policer *policer = +CONTAINER_OF(conf, struct egress_policer, qos_conf); + +struct egress_queue_policer *queue_policer; +queue_policer = egress_policer_qos_find_queue(policer, queue_id); +if (!queue_policer) { +
[ovs-dev] [PATCH 2/4] Support multi-queue rate limit function for ovs-dpdk Qos.
Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/netdev-dpdk.c | 40 ++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index f0d9842..49816ca 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -3171,14 +3171,50 @@ egress_policer_qos_is_equal(const struct qos_conf *conf, return !memcmp(, >app_srtcm_params, sizeof params); } +static inline bool +egress_policer_pkt_handle(struct egress_policer *policer, struct rte_mbuf *pkt, uint64_t time) +{ +struct egress_queue_policer *queue_policer; +uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt) - sizeof(struct ether_hdr); + +queue_policer = egress_policer_qos_find_queue(policer, + ((struct dp_packet *)pkt)->md.skb_priority); +if (queue_policer) { +if (rte_meter_srtcm_color_blind_check(_policer->egress_meter, time, pkt_len) != + e_RTE_METER_GREEN) { +queue_policer->stats.tx_errors ++; +return false; +} else { +queue_policer->stats.tx_bytes += pkt_len; +queue_policer->stats.tx_packets ++; +} +} + +return rte_meter_srtcm_color_blind_check(>egress_meter, time, pkt_len) == +e_RTE_METER_GREEN; +} + static int egress_policer_run(struct qos_conf *conf, struct rte_mbuf **pkts, int pkt_cnt) { -int cnt = 0; +int i = 0, cnt = 0; +struct rte_mbuf *pkt = NULL; +uint64_t current_time = rte_rdtsc(); struct egress_policer *policer = CONTAINER_OF(conf, struct egress_policer, qos_conf); -cnt = netdev_dpdk_policer_run(>egress_meter, pkts, pkt_cnt); +for (i = 0; i < pkt_cnt; i++) { +pkt = pkts[i]; +/* Handle current packet */ +if (egress_policer_pkt_handle(policer, pkt, current_time)) { +if (cnt != i) { +pkts[cnt] = pkt; +} +cnt++; +} else { +rte_pktmbuf_free(pkt); +} +} return cnt; } -- 2.7.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH 4/4] Modify QoS configure documents for ovs-dpdk
Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- Documentation/howto/dpdk.rst | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index af01d3e..bb60f83 100644 --- a/Documentation/howto/dpdk.rst +++ b/Documentation/howto/dpdk.rst @@ -126,8 +126,16 @@ of size 64 bytes, the following command would limit the egress transmission rate of the port to ~1,000,000 packets per second:: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ ---id=@newqos create qos type=egress-policer other-config:cir=4600 \ -other-config:cbs=2048` +--id=@newqos create qos type=egress-policer \ +other-config:cir=4600 other-config:cbs=2048` \ +queues:123=@q123 queues:234=@q234 -- \ +--id=@q0 create queue other-config:cir=1280 other-config:cbs=2048 -- \ +--id=@q2 create queue other-config:cir=2560 other-config:cbs=2048` + +To direct packets to queues, run:: + +$ ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal +$ ovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal To examine the QoS configuration of the port, run:: -- 2.7.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH 1/4] Support multi-queue for ovs-dpdk QoS.
Original command is as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer other-config:cir=4600 \ other-config:cbs=2048` Now it can support command as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048` \ queues:123=@q123 queues:234=@q234 -- \ --id=@q123 create queue other-config:cir=1280 other-config:cbs=2048 -- \ --id=@q234 create queue other-config:cir=2560 other-config:cbs=2048` Then, we can use OpenFlow to direct packet to queues: $ ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal $ ovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal Finally, it only support to configure now, QoS rate limit function is not ready. Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/netdev-dpdk.c | 189 -- 1 file changed, 185 insertions(+), 4 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index ea17b97..f0d9842 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -259,6 +259,31 @@ struct dpdk_qos_ops { */ int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts, int pkt_cnt); + +/* Called to construct a QoS Queue. The implementation should make + * the appropriate calls to configure QoS Queue according to 'details'. + * + * The contents of 'details' should be documented as valid for 'ovs_name' + * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml + * (which is built as ovs-vswitchd.conf.db(8)). + * + * This function must return 0 if and only if construct qos queue successfully. + */ +int (*qos_queue_construct)(const struct smap *details, + uint32_t queue_id, struct qos_conf *conf); + +/* Destroys the Qos Queue + */ +void (*qos_queue_destruct)(struct qos_conf *conf, uint32_t queue_id); + +/* Retrieves details of QoS Queue configuration into 'details'. + * + * The contents of 'details' should be documented as valid for 'ovs_name' + * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml + * (which is built as ovs-vswitchd.conf.db(8)). + */ +int (*qos_queue_get)(struct smap *details, uint32_t queue_id, + const struct qos_conf *conf); }; /* dpdk_qos_ops for each type of user space QoS implementation */ @@ -2986,14 +3011,93 @@ netdev_dpdk_set_qos(struct netdev *netdev, const char *type, return error; } +static int +netdev_dpdk_get_queue(const struct netdev *netdev, uint32_t queue_id, + struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_get) { +error = EOPNOTSUPP; +} else { +error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf); +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_set_queue(struct netdev *netdev, uint32_t queue_id, + const struct smap *details) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; +int error = 0; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (!qos_conf || !qos_conf->ops || !qos_conf->ops->qos_queue_construct) { +error = EOPNOTSUPP; +} else { +error = qos_conf->ops->qos_queue_construct(details, queue_id, qos_conf); +} + +if (error) { +VLOG_ERR("Failed to set QoS queue %d on port %s: %s", + queue_id, netdev->name, rte_strerror(error)); +} + +ovs_mutex_unlock(>mutex); + +return error; +} + +static int +netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id) +{ +struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); +struct qos_conf *qos_conf; + +ovs_mutex_lock(>mutex); + +qos_conf = ovsrcu_get_protected(struct qos_conf *, >qos_conf); +if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_destruct) { +qos_conf->ops->qos_queue_destruct(qos_conf, queue_id); +} + +ovs_mutex_unlock(>mutex); + +return 0; +} + /* egress-policer details */ struct egress_policer { struct qos_conf qos_conf; struct rte_meter_srtcm_params app_srtcm_params; struct rte_meter_srtcm egress_meter; +struct hmap queue; }; +struct egress_queue_policer { +struct hmap_node hmap_node; +uint32_t queue_id; +struct rte_meter_srtcm
[ovs-dev] [PATCH 0/4] netdev-dpdk: Support multi-queue for ovs-dpdk QoS
Original command is as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer other-config:cir=4600 \ other-config:cbs=2048` Now it can support command as below: $ ovs-vsctl set port vhost-user0 qos=@newqos -- \ --id=@newqos create qos type=egress-policer \ other-config:cir=4600 other-config:cbs=2048` \ queues:123=@q123 queues:234=@q234 -- \ --id=@q123 create queue other-config:cir=1280 other-config:cbs=2048 -- \ --id=@q234 create queue other-config:cir=2560 other-config:cbs=2048` Then, we can use OpenFlow to direct packet to queues: $ ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal $ ovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal Finally, we can use command `ovs-appctl -t ovs-vswitchd qos/show vhost-user0` to show QoS queue information. Signed-off-by: zhaozhanxu <zhaozha...@163.com> zhaozhanxu (4): Support multi-queue for ovs-dpdk QoS. Support multi-queue rate limit function for ovs-dpdk Qos. Support to show multi-queue qos info Modify QoS configure documents for ovs-dpdk Documentation/howto/dpdk.rst | 12 +- lib/netdev-dpdk.c| 374 +-- 2 files changed, 374 insertions(+), 12 deletions(-) -- 2.7.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH] tnl-ports.c: Fix bug that ovs-dpdk has no listening tunnel ports when delete one tunnel port.
Bug is below: 1. When ovs-dpdk has some tunnel ports, I can see the listening ports through the command `ovs-appctl tnl/ports/show -v`. 2. When one tunnel port is deleted, the listening ports are deleted also. 3. This will cause ovs-dpdk can't de-encapsulates packets, then network barrier between two hosts finally. Signed-off-by: zhaozhanxu <zhaozha...@163.com> --- lib/tnl-ports.c | 24 ++-- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index 4a07dcb..70f6c3b 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -51,6 +51,7 @@ static struct ovs_list addr_list; struct tnl_port { odp_port_t port; +struct ovs_refcount ref_cnt; ovs_be16 tp_port; uint8_t nw_proto; char dev_name[IFNAMSIZ]; @@ -195,7 +196,8 @@ tnl_port_map_insert(odp_port_t port, ovs_be16 tp_port, ovs_mutex_lock(); LIST_FOR_EACH(p, node, _list) { if (tp_port == p->tp_port && p->nw_proto == nw_proto) { - goto out; +ovs_refcount_ref(>ref_cnt); +goto out; } } @@ -204,6 +206,7 @@ tnl_port_map_insert(odp_port_t port, ovs_be16 tp_port, p->tp_port = tp_port; p->nw_proto = nw_proto; ovs_strlcpy(p->dev_name, dev_name, sizeof p->dev_name); +ovs_refcount_init(>ref_cnt); ovs_list_insert(_list, >node); LIST_FOR_EACH(ip_dev, node, _list) { @@ -256,29 +259,22 @@ tnl_port_map_delete(ovs_be16 tp_port, const char type[]) { struct tnl_port *p, *next; struct ip_device *ip_dev; -bool found = false; uint8_t nw_proto; nw_proto = tnl_type_to_nw_proto(type); ovs_mutex_lock(); LIST_FOR_EACH_SAFE(p, next, node, _list) { -if (p->tp_port == tp_port && p->nw_proto == nw_proto) { +if (p->tp_port == tp_port && p->nw_proto == nw_proto && +ovs_refcount_unref_relaxed(>ref_cnt) == 1) { ovs_list_remove(>node); -found = true; +LIST_FOR_EACH(ip_dev, node, _list) { +ipdev_map_delete(ip_dev, p->tp_port, p->nw_proto); +} +free(p); break; } } - -if (!found) { -goto out; -} -LIST_FOR_EACH(ip_dev, node, _list) { -ipdev_map_delete(ip_dev, p->tp_port, p->nw_proto); -} - -free(p); -out: ovs_mutex_unlock(); } -- 2.7.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev