On 14 Jul 2023, at 13:52, Eelco Chaudron wrote:

> On 1 Jul 2023, at 16:40, [email protected] wrote:
>
>> From: Lin Huang <[email protected]>
>>
>> OvS has supported packet-per-second policer which can be set at ingress
>> and egress side in kernel datapath. But the userspace datapath doesn't
>> support for ingress and egress packet-per-second policing now.
>>
>> So, this patch add support for userspace egress pps policing by using
>> native ovs token bucket library. Token bucket is accumulated by 'rate'
>> tokens per millisecond and store maximum tokens at 'burst' bucket size.
>> One token in the bucket means one packet (1 kpkts * millisecond) which
>> will drop or pass by policer.
>>
>> This patch add new configuration option 'kpkts_rate' and 'kpkts_burst'
>> for egress-policer QoS type which now supports setting packet-per-second
>> limits in addition to the previously configurable byte rate settings.
>>
>> Examples:
>> $ovs-vsctl set port vhost-user0 qos=@newqos --
>>            --id=@newqos create qos type=egress-policer \
>>            other-config:cir=123000 other-config:cbs=123000
>>            other-config:kpkts_rate=123 other-config:kpkts_burst=123
>
> Hi Lin,
>
> I did not review the code, but I’m wondering why you decided to overload the 
> existing egress-policer type which is byte-based with another packet-based 
> option. This will allow two configuration options and only one being used.
>
> I would suggest creating a new policer type for this, so it’s more clear from 
> the type what it does. For example type=pkt-policer, as we also have 
> trtcm-policer.

I was looking at some old code, so I guess your goal is to do both at the same 
time? Then it makes sense.

I will do a proper review, as I do think you need a new revision based on 
feedback on the previous patch and this:

>>  static int
>>  egress_policer_run(struct qos_conf *conf, struct rte_mbuf **pkts, int 
>> pkt_cnt,
>>                     bool should_steal)
>>  {
>> -    int cnt = 0;
>>      struct egress_policer *policer =
>>          CONTAINER_OF(conf, struct egress_policer, qos_conf);
>> +    int bps_drop = 0, pps_drop = 0;
>> +    int cnt = 0;
>>
>> -    cnt = srtcm_policer_run_single_packet(&policer->egress_meter,
>> -                                          &policer->egress_prof, pkts,
>> -                                          pkt_cnt);
>> +    if (policer->type & POLICER_BPS) {
>> +        bps_drop = srtcm_policer_run_single_packet(&policer->egress_meter,
>> +                                                   &policer->egress_prof, 
>> pkts,
>> +                                                   pkt_cnt);
>> +    }
>> +

If packets are dropped by the above, should we still pass them through the 
below? Don’t think so, or am I missing something?


Also if a packet is forwarded by srtcm, but dropped by the packet policer 
should the tokens not be returned?

>> +    if (policer->type & POLICER_PKTPS) {
>> +        pps_drop = pkts_policer_run_single_packet(&policer->egress_tb, 
>> pkt_cnt);
>> +    }

>> +    cnt = MAX(bps_drop, pps_drop);

As in the previous patch, drops might not have happened in order.

>>      if (should_steal && cnt) {
>>          rte_pktmbuf_free_bulk(&pkts[pkt_cnt - cnt], cnt);
>>      }

> Cheers,
>
> Eelco
>
>>
>> Add some unit tests for egress packet-per-second policing.
>>
>> Signed-off-by: Lin Huang <[email protected]>
>> ---
>>  Documentation/topics/dpdk/qos.rst |  15 ++-
>>  NEWS                              |   2 +
>>  lib/netdev-dpdk.c                 | 132 ++++++++++++++++----
>>  tests/system-dpdk.at              | 194 +++++++++++++++++++++++++++++-
>>  vswitchd/vswitch.xml              |  10 ++
>>  5 files changed, 327 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/topics/dpdk/qos.rst 
>> b/Documentation/topics/dpdk/qos.rst
>> index a98ec672f..5f0b1469a 100644
>> --- a/Documentation/topics/dpdk/qos.rst
>> +++ b/Documentation/topics/dpdk/qos.rst
>> @@ -36,14 +36,21 @@ QoS (Egress Policing)
>>  Single Queue Policer
>>  ~~~~~~~~~~~~~~~~~~~~
>>
>> -Assuming you have a :doc:`vhost-user port <vhost-user>` transmitting traffic
>> -consisting of packets of size 64 bytes, the following command would limit 
>> the
>> -egress transmission rate of the port to ~1,000,000 packets per second::
>> +Assuming you have a :doc:`vhost-user port <vhost-user>` transmitting 
>> traffic,
>> +the following command would limit the egress transmission rate of the port 
>> to
>> +~1,000,000 bytes per second:
>>
>>      $ ovs-vsctl set port vhost-user0 qos=@newqos -- \
>> -        --id=@newqos create qos type=egress-policer 
>> other-config:cir=46000000 \
>> +        --id=@newqos create qos type=egress-policer 
>> other-config:cir=1000000 \
>>          other-config:cbs=2048`
>>
>> +or, 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:kpkts_rate=1000 other-config:kpkts_burst=1000
>> +
>>  To examine the QoS configuration of the port, run::
>>
>>      $ ovs-appctl -t ovs-vswitchd qos/show vhost-user0
>> diff --git a/NEWS b/NEWS
>> index 0b5dc3db1..d88f490b1 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -44,6 +44,8 @@ Post-v3.1.0
>>       * IP and L4 checksum offload support is now enabled by default for
>>         interfaces that support it.  See the 'status' column in the 
>> 'interface'
>>         table to check the status.
>> +     * Added new configuration options 'kpkts_rate' and 'kpkts_burst' for
>> +      'egress-policer' to support kilo packet-per-second policing.
>>
>>
>>  v3.1.0 - 16 Feb 2023
>> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
>> index 2f7f74395..f97153665 100644
>> --- a/lib/netdev-dpdk.c
>> +++ b/lib/netdev-dpdk.c
>> @@ -19,6 +19,7 @@
>>
>>  #include <errno.h>
>>  #include <signal.h>
>> +#include <stdint.h>
>>  #include <stdlib.h>
>>  #include <string.h>
>>  #include <unistd.h>
>> @@ -59,6 +60,7 @@
>>  #include "openvswitch/ofp-parse.h"
>>  #include "openvswitch/ofp-print.h"
>>  #include "openvswitch/shash.h"
>> +#include "openvswitch/token-bucket.h"
>>  #include "openvswitch/vlog.h"
>>  #include "ovs-numa.h"
>>  #include "ovs-rcu.h"
>> @@ -91,6 +93,8 @@ static bool per_port_memory = false; /* Status of per port 
>> memory support */
>>  #define OVS_CACHE_LINE_SIZE CACHE_LINE_SIZE
>>  #define OVS_VPORT_DPDK "ovs_dpdk"
>>
>> +#define MAX_KPKTS_PARAMETER 4294967U  /* UINT32_MAX / 1000 */
>> +
>>  /*
>>   * need to reserve tons of extra space in the mbufs so we can align the
>>   * DMA addresses to 4KB.
>> @@ -400,6 +404,11 @@ struct dpdk_tx_queue {
>>      );
>>  };
>>
>> +enum policer_type {
>> +    POLICER_BPS   = 1 << 0,   /* Rate value in bytes/sec. */
>> +    POLICER_PKTPS = 1 << 1,   /* Rate value in packet/sec. */
>> +};
>> +
>>  struct ingress_policer {
>>      struct rte_meter_srtcm_params app_srtcm_params;
>>      struct rte_meter_srtcm in_policer;
>> @@ -2418,6 +2427,46 @@ srtcm_policer_run_single_packet(struct 
>> rte_meter_srtcm *meter,
>>      return cnt;
>>  }
>>
>> +static int
>> +pkts_policer_run_single_packet(struct token_bucket *tb, int pkt_cnt)
>> +{
>> +    int cnt = 0;
>> +    long long int now = time_msec();
>> +
>> +    for (int i = 0; i < pkt_cnt; i++) {
>> +        /* Handle current packet. */
>> +        if (!token_bucket_withdraw(tb, 1, now)) {
>> +            /* Count dropped packets. */
>> +            cnt++;
>> +        }
>> +    }
>> +
>> +    return cnt;
>> +}
>> +
>> +static int
>> +pkts_policer_profile_config(struct token_bucket *tb,
>> +                            uint32_t kpkts_rate, uint32_t kpkts_burst)
>> +{
>> +    if (kpkts_rate > MAX_KPKTS_PARAMETER ||
>> +        kpkts_burst > MAX_KPKTS_PARAMETER) {
>> +        return EINVAL;
>> +    }
>> +
>> +   /* Rate in kilo-packets/second, bucket 1000 packets.
>> +    * msec * kilo-packets/sec = 1 packets. */
>> +    if (kpkts_rate) {
>> +        /* Parameters between (1 ~ MAX_KPKTS_PARAMETER). */
>> +        token_bucket_init(tb, kpkts_rate, kpkts_burst * 1000);
>> +    } else {
>> +        /* Zero means not to police the traffic.
>> +         * Return a error to not set POLICER_PKTPS valid. */
>> +        return EINVAL;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>  static int
>>  ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
>>                      int pkt_cnt, bool should_steal)
>> @@ -4882,24 +4931,37 @@ netdev_dpdk_queue_dump_done(const struct netdev 
>> *netdev OVS_UNUSED,
>>
>>
>>  /* egress-policer details */
>> +struct egress_policer_params {
>> +    struct rte_meter_srtcm_params app_srtcm_params;
>> +    uint32_t kpkts_rate;
>> +    uint32_t kpkts_burst;
>> +};
>>
>>  struct egress_policer {
>>      struct qos_conf qos_conf;
>> -    struct rte_meter_srtcm_params app_srtcm_params;
>> +    enum policer_type type;
>> +    struct token_bucket egress_tb;
>> +    struct egress_policer_params params;
>>      struct rte_meter_srtcm egress_meter;
>>      struct rte_meter_srtcm_profile egress_prof;
>>  };
>>
>>  static void
>>  egress_policer_details_to_param(const struct smap *details,
>> -                                struct rte_meter_srtcm_params *params)
>> +                                struct egress_policer_params *params)
>>  {
>> -    memset(params, 0, sizeof *params);
>> -    params->cir = smap_get_ullong(details, "cir", 0);
>> -    params->cbs = smap_get_ullong(details, "cbs", 0);
>> -    params->ebs = 0;
>> +    struct rte_meter_srtcm_params *srtcm_params = &params->app_srtcm_params;
>> +
>> +    memset(srtcm_params, 0, sizeof *srtcm_params);
>> +    srtcm_params->cir = smap_get_ullong(details, "cir", 0);
>> +    srtcm_params->cbs = smap_get_ullong(details, "cbs", 0);
>> +    srtcm_params->ebs = 0;
>> +
>> +    params->kpkts_rate  = smap_get_uint(details, "kpkts_rate", 0);
>> +    params->kpkts_burst = smap_get_uint(details, "kpkts_burst", 0);
>>  }
>>
>> +
>>  static int
>>  egress_policer_qos_construct(const struct smap *details,
>>                               struct qos_conf **conf)
>> @@ -4907,23 +4969,40 @@ egress_policer_qos_construct(const struct smap 
>> *details,
>>      struct egress_policer *policer;
>>      int err = 0;
>>
>> -    policer = xmalloc(sizeof *policer);
>> +    policer = xzalloc(sizeof *policer);
>>      qos_conf_init(&policer->qos_conf, &egress_policer_ops);
>> -    egress_policer_details_to_param(details, &policer->app_srtcm_params);
>> +    egress_policer_details_to_param(details, &policer->params);
>> +
>>      err = rte_meter_srtcm_profile_config(&policer->egress_prof,
>> -                                         &policer->app_srtcm_params);
>> +                                         &policer->params.app_srtcm_params);
>>      if (!err) {
>>          err = rte_meter_srtcm_config(&policer->egress_meter,
>>                                       &policer->egress_prof);
>>      }
>> +    if (err) {
>> +        VLOG_DBG("Could not create rte meter for egress policer");
>> +        err = -err;
>> +    } else {
>> +        policer->type |= POLICER_BPS;
>> +    }
>>
>> -    if (!err) {
>> -        *conf = &policer->qos_conf;
>> +    err = pkts_policer_profile_config(&policer->egress_tb,
>> +                                      policer->params.kpkts_rate,
>> +                                      policer->params.kpkts_burst);
>> +    if (err) {
>> +        VLOG_DBG("Could not create token bucket for egress policer");
>>      } else {
>> -        VLOG_ERR("Could not create rte meter for egress policer");
>> +        policer->type |= POLICER_PKTPS;
>> +    }
>> +
>> +    if (!policer->type) {
>> +        /* Both bps and kpkts contrsruction failed.*/
>>          free(policer);
>>          *conf = NULL;
>> -        err = -err;
>> +        VLOG_INFO("Could not create qos for egress policer");
>> +    } else {
>> +        err = 0;
>> +        *conf = &policer->qos_conf;
>>      }
>>
>>      return err;
>> @@ -4942,9 +5021,12 @@ egress_policer_qos_get(const struct qos_conf *conf, 
>> struct smap *details)
>>  {
>>      struct egress_policer *policer =
>>          CONTAINER_OF(conf, struct egress_policer, qos_conf);
>> +    struct egress_policer_params *params = &policer->params;
>>
>> -    smap_add_format(details, "cir", "%"PRIu64, 
>> policer->app_srtcm_params.cir);
>> -    smap_add_format(details, "cbs", "%"PRIu64, 
>> policer->app_srtcm_params.cbs);
>> +    smap_add_format(details, "cir", "%"PRIu64, 
>> params->app_srtcm_params.cir);
>> +    smap_add_format(details, "cbs", "%"PRIu64, 
>> params->app_srtcm_params.cbs);
>> +    smap_add_format(details, "kpkts_rate", "%"PRIu32, params->kpkts_rate);
>> +    smap_add_format(details, "kpkts_burst", "%"PRIu32, params->kpkts_burst);

If it’s not configured we should not return it, as it might confuse the user?

>>
>>      return 0;
>>  }
>> @@ -4955,25 +5037,33 @@ egress_policer_qos_is_equal(const struct qos_conf 
>> *conf,
>>  {
>>      struct egress_policer *policer =
>>          CONTAINER_OF(conf, struct egress_policer, qos_conf);
>> -    struct rte_meter_srtcm_params params;
>> +    struct egress_policer_params params;
>>
>>      egress_policer_details_to_param(details, &params);
>>
>> -    return !memcmp(&params, &policer->app_srtcm_params, sizeof params);
>> +    return !memcmp(&params, &policer->params, sizeof params);
>>  }
>>
>>  static int
>>  egress_policer_run(struct qos_conf *conf, struct rte_mbuf **pkts, int 
>> pkt_cnt,
>>                     bool should_steal)
>>  {
>> -    int cnt = 0;
>>      struct egress_policer *policer =
>>          CONTAINER_OF(conf, struct egress_policer, qos_conf);
>> +    int bps_drop = 0, pps_drop = 0;
>> +    int cnt = 0;
>>
>> -    cnt = srtcm_policer_run_single_packet(&policer->egress_meter,
>> -                                          &policer->egress_prof, pkts,
>> -                                          pkt_cnt);
>> +    if (policer->type & POLICER_BPS) {
>> +        bps_drop = srtcm_policer_run_single_packet(&policer->egress_meter,
>> +                                                   &policer->egress_prof, 
>> pkts,
>> +                                                   pkt_cnt);
>> +    }
>> +
>> +    if (policer->type & POLICER_PKTPS) {
>> +        pps_drop = pkts_policer_run_single_packet(&policer->egress_tb, 
>> pkt_cnt);
>> +    }
>>
>> +    cnt = MAX(bps_drop, pps_drop);
>>      if (should_steal && cnt) {
>>          rte_pktmbuf_free_bulk(&pkts[pkt_cnt - cnt], cnt);
>>      }
>> diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at
>> index 0f58e8574..233f7e493 100644
>> --- a/tests/system-dpdk.at
>> +++ b/tests/system-dpdk.at
>> @@ -435,6 +435,7 @@ OVS_DPDK_PRE_PHY_SKIP()
>>  OVS_DPDK_START()
>>
>>  dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])

Should we still not get another error we should check for from a user 
perspective (same for all other occurrences)?


>>  AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>>  AT_CHECK([ovs-vsctl add-port br10 phy0 -- set Interface phy0 type=dpdk 
>> options:dpdk-devargs=$(cat PCI_ADDR)], [], [stdout], [stderr])
>>  OVS_WAIT_UNTIL([ovs-vsctl set port phy0 qos=@newqos -- --id=@newqos create 
>> qos type=egress-policer other-config:cir=1250000 other-config:cbs=2048])
>> @@ -453,7 +454,9 @@ AT_CHECK([grep -E 'QoS not configured on phy0' stdout], 
>> [], [stdout])
>>
>>  dnl Clean up
>>  AT_CHECK([ovs-vsctl del-port br10 phy0], [], [stdout], [stderr])
>> -OVS_VSWITCHD_STOP("[SYSTEM_DPDK_ALLOWED_LOGS]")
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@Could not create token bucket for egress policer@d
>> +])")
>>  AT_CLEANUP
>>  dnl 
>> --------------------------------------------------------------------------
>>
>> @@ -468,6 +471,7 @@ OVS_DPDK_PRE_CHECK()
>>  OVS_DPDK_START([--no-pci])
>>
>>  dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>>  AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>>  AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>>  OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:cir=1250000 \
>> @@ -493,6 +497,7 @@ AT_CHECK([grep -E 'QoS not configured on 
>> dpdkvhostuserclient0' stdout], [], [std
>>  dnl Clean up
>>  AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>>  OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@Could not create token bucket for egress policer@d
>>  \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>>  ])")
>>  AT_CLEANUP
>> @@ -509,6 +514,7 @@ OVS_DPDK_PRE_CHECK()
>>  OVS_DPDK_START([--no-pci])
>>
>>  dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>>  AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>>  AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>>  OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:cbs=2048])
>> @@ -528,6 +534,7 @@ AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], 
>> [], [stdout], [stderr])
>>  OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>>  \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>>  \@Could not create rte meter for egress policer@d
>> +\@Could not create token bucket for egress policer@d
>>  \@Failed to set QoS type egress-policer on port dpdkvhostuserclient0: 
>> Invalid argument@d
>>  ])")
>>  AT_CLEANUP
>> @@ -544,6 +551,7 @@ OVS_DPDK_PRE_CHECK()
>>  OVS_DPDK_START([--no-pci])
>>
>>  dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>>  AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>>  AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>>  OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:cir=1250000])
>> @@ -563,6 +571,7 @@ AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], 
>> [], [stdout], [stderr])
>>  OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>>  \@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>>  \@Could not create rte meter for egress policer@d
>> +\@Could not create token bucket for egress policer@d
>>  \@Failed to set QoS type egress-policer on port dpdkvhostuserclient0: 
>> Invalid argument@d
>>  ])")
>>  AT_CLEANUP
>> @@ -570,6 +579,189 @@ dnl 
>> --------------------------------------------------------------------------
>>
>>
>>

This is only testing the configuration, which can probably also be done in the 
userspace tests, however it would be nice if we can add some actual traffic 
tests.

>> +dnl 
>> --------------------------------------------------------------------------
>> +dnl QoS (kpkts) create delete vport port
>> +AT_SETUP([OVS-DPDK - QoS (kpkts) create delete vport port])
>> +AT_KEYWORDS([dpdk])
>> +
>> +OVS_DPDK_PRE_CHECK()
>> +OVS_DPDK_START()
>> +
>> +dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>> +OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:kpkts_rate=123 
>> other-config:kpkts_burst=456])
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +sleep 2
>> +
>> +dnl Parse log file
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user 
>> client: socket created" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 
>> 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) 
>> reconnecting..." ovs-vswitchd.log], [], [stdout])
>> +
>> +dnl Remove egress policer
>> +AT_CHECK([ovs-vsctl destroy QoS dpdkvhostuserclient0 -- clear Port 
>> dpdkvhostuserclient0 qos])
>> +
>> +dnl Check egress policer was removed correctly
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +AT_CHECK([grep -E 'QoS not configured on dpdkvhostuserclient0' stdout], [], 
>> [stdout])
>> +
>> +dnl Clean up
>> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>> +\@Failed to set QoS type egress-policer on port dpdkvhostuserclient0@d
>> +\@Could not create rte meter for egress policer@d
>> +])")
>> +AT_CLEANUP
>> +dnl 
>> --------------------------------------------------------------------------
>> +
>> +
>> +
>> +dnl 
>> --------------------------------------------------------------------------
>> +dnl QoS (kpkts) no rate
>> +AT_SETUP([OVS-DPDK - QoS (kpkts) no rate])
>> +AT_KEYWORDS([dpdk])
>> +
>> +OVS_DPDK_PRE_CHECK()
>> +OVS_DPDK_START()
>> +
>> +dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>> +OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:kpkts_burst=123])
>> +sleep 2
>> +
>> +dnl Parse log file
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user 
>> client: socket created" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 
>> 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) 
>> reconnecting..." ovs-vswitchd.log], [], [stdout])
>> +
>> +dnl Check egress policer was not created
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +AT_CHECK([grep -E 'QoS not configured on dpdkvhostuserclient0' stdout], [], 
>> [stdout])
>> +
>> +dnl Clean up
>> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>> +\@Could not create rte meter for egress policer@d
>> +\@Could not create token bucket for egress policer@d
>> +\@Failed to set QoS type egress-policer on port dpdkvhostuserclient0@d
>> +])")
>> +AT_CLEANUP
>> +dnl 
>> --------------------------------------------------------------------------
>> +
>> +
>> +
>> +dnl 
>> --------------------------------------------------------------------------
>> +dnl QoS (kpkts) no burst
>> +AT_SETUP([OVS-DPDK - QoS (kpkts) no burst])
>> +AT_KEYWORDS([dpdk])
>> +
>> +OVS_DPDK_PRE_CHECK()
>> +OVS_DPDK_START()
>> +
>> +dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>> +OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer other-config:kpkts_rate=123])
>> +sleep 2
>> +
>> +dnl Parse log file
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user 
>> client: socket created" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 
>> 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) 
>> reconnecting..." ovs-vswitchd.log], [], [stdout])
>> +
>> +dnl Check egress policer was created
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +AT_CHECK([grep -E 'kpkts_rate: 123' stdout], [], [stdout])
>> +
>> +dnl Clean up
>> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>> +\@Could not create rte meter for egress policer@d
>> +\@Failed to set QoS type egress-policer on port dpdkvhostuserclient0@d
>> +])")
>> +AT_CLEANUP
>> +dnl 
>> --------------------------------------------------------------------------
>> +
>> +
>> +
>> +dnl 
>> --------------------------------------------------------------------------
>> +dnl QoS (kpkts) max rate
>> +AT_SETUP([OVS-DPDK - QoS (kpkts) max rate])
>> +AT_KEYWORDS([dpdk])
>> +
>> +OVS_DPDK_PRE_CHECK()
>> +OVS_DPDK_START()
>> +
>> +dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>> +OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer 
>> other-config:kpkts_rate=42949671])
>> +sleep 2
>> +
>> +dnl Parse log file
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user 
>> client: socket created" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 
>> 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) 
>> reconnecting..." ovs-vswitchd.log], [], [stdout])
>> +
>> +dnl Check egress policer was not created
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +AT_CHECK([grep -E 'QoS not configured on dpdkvhostuserclient0' stdout], [], 
>> [stdout])
>> +
>> +dnl Clean up
>> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>> +\@Could not create rte meter for egress policer@d
>> +\@Could not create token bucket for egress policer@d
>> +\@Failed to set QoS type egress-policer on port dpdkvhostuserclient0@d
>> +])")
>> +AT_CLEANUP
>> +dnl 
>> --------------------------------------------------------------------------
>> +
>> +
>> +dnl 
>> --------------------------------------------------------------------------
>> +dnl QoS (kpkts) max burst
>> +AT_SETUP([OVS-DPDK - QoS (kpkts) max burst])
>> +AT_KEYWORDS([dpdk])
>> +
>> +OVS_DPDK_PRE_CHECK()
>> +OVS_DPDK_START()
>> +
>> +dnl Add userspace bridge and attach it to OVS and add egress policer
>> +AT_CHECK([ovs-appctl vlog/set netdev_dpdk:dbg])
>> +AT_CHECK([ovs-vsctl add-br br10 -- set bridge br10 datapath_type=netdev])
>> +AT_CHECK([ovs-vsctl add-port br10 dpdkvhostuserclient0 -- set Interface 
>> dpdkvhostuserclient0 type=dpdkvhostuserclient 
>> options:vhost-server-path=$OVS_RUNDIR/dpdkvhostclient0], [], [stdout], 
>> [stderr])
>> +OVS_WAIT_UNTIL([ovs-vsctl set port dpdkvhostuserclient0 qos=@newqos -- 
>> --id=@newqos create qos type=egress-policer 
>> other-config:kpkts_burst=42949671])
>> +sleep 2
>> +
>> +dnl Parse log file
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) vhost-user 
>> client: socket created" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 
>> 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout])
>> +AT_CHECK([grep "VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) 
>> reconnecting..." ovs-vswitchd.log], [], [stdout])
>> +
>> +dnl Check egress policer was not created
>> +AT_CHECK([ovs-appctl -t ovs-vswitchd qos/show dpdkvhostuserclient0], [], 
>> [stdout])
>> +AT_CHECK([grep -E 'QoS not configured on dpdkvhostuserclient0' stdout], [], 
>> [stdout])
>> +
>> +dnl Clean up
>> +AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], 
>> [stderr])
>> +OVS_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [
>> +\@VHOST_CONFIG: ($OVS_RUNDIR/dpdkvhostclient0) failed to connect: No such 
>> file or directory@d
>> +\@Could not create rte meter for egress policer@d
>> +\@Could not create token bucket for egress policer@d
>> +\@Failed to set QoS type egress-policer on port dpdkvhostuserclient0@d
>> +])")
>> +AT_CLEANUP
>> +dnl 
>> --------------------------------------------------------------------------
>>
>>  dnl 
>> --------------------------------------------------------------------------
>>  dnl MTU increase phy port
>> diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
>> index 59c404bbb..b94ed2d34 100644
>> --- a/vswitchd/vswitch.xml
>> +++ b/vswitchd/vswitch.xml
>> @@ -4920,6 +4920,16 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 
>> type=patch options:peer=p1 \
>>          bytes/tokens of the packet. If there are not enough tokens in the 
>> cbs
>>          bucket the packet might be dropped.
>>        </column>
>> +      <column name="other_config" key="kpkts_rate"
>> +          type='{"type": "integer", "minInteger": 0, "maxInteger": 
>> 4294967}'>
>> +        The Packets Per Second (PPS) represents the packet per second rate 
>> at
>> +        which the token bucket will be updated.
>> +      </column>
>> +      <column name="other_config" key="kpkts_burst"
>> +          type='{"type": "integer", "minInteger": 0, "maxInteger": 
>> 4294967}'>
>> +        The Packets Per Second Burst Size is measured in count and 
>> represents a
>> +        token bucket.
>> +      </column>
>>      </group>
>>
>>      <group title="Configuration for linux-sfq">
>> -- 
>> 2.39.1
>>
>> _______________________________________________
>> 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

Reply via email to