On Thu, Jan 21, 2021 at 5:44 PM <[email protected]> wrote: > > From: Tonghao Zhang <[email protected]> > > When setting the meter rate to 4.3+Gbps, there is an overflow, the > meters don't work as expected. > > $ ovs-ofctl -O OpenFlow13 add-meter br-int "meter=1 kbps stats > bands=type=drop rate=4294968" > > Before the patch, the buckets of meters was stored in its burst_size > of ofputil_meter_band. It was overflow when we set the rate to 4294968. > This patch don't change the public API and structure. This patch remove > the "up" from dp_meter_band, and introduce the type, rate to datapath's > meter bands. Then datapath don't depend upper layer. > > Signed-off-by: Tonghao Zhang <[email protected]> ping > --- > lib/dpif-netdev.c | 42 ++++++++++++++++++++---------------------- > 1 file changed, 20 insertions(+), 22 deletions(-) > > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index e3fd0a07f..c281f9ac6 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -279,8 +279,10 @@ static bool dpcls_lookup(struct dpcls *cls, > ( 1 << OFPMBT13_DROP ) > > struct dp_meter_band { > - struct ofputil_meter_band up; /* type, prec_level, pad, rate, burst_size > */ > - uint32_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) > */ > + uint16_t type; > + uint32_t rate; > + uint32_t burst_size; > + uint64_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) > */ > uint64_t packet_count; > uint64_t byte_count; > }; > @@ -6199,12 +6201,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct > dp_packet_batch *packets_, > /* Update all bands and find the one hit with the highest rate for each > * packet (if any). */ > for (int m = 0; m < meter->n_bands; ++m) { > - band = &meter->bands[m]; > + uint64_t max_bucket_size; > > + band = &meter->bands[m]; > /* Update band's bucket. */ > - band->bucket += delta_t * band->up.rate; > - if (band->bucket > band->up.burst_size) { > - band->bucket = band->up.burst_size; > + max_bucket_size = band->rate * 1000ULL; > + band->bucket += (uint64_t)delta_t * band->rate; > + if (band->bucket > max_bucket_size) { > + band->bucket = max_bucket_size; > } > > /* Drain the bucket for all the packets, if possible. */ > @@ -6222,8 +6226,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct > dp_packet_batch *packets_, > * (Only one band will be fired by a packet, and that > * can be different for each packet.) */ > for (int i = band_exceeded_pkt; i < cnt; i++) { > - if (band->up.rate > exceeded_rate[i]) { > - exceeded_rate[i] = band->up.rate; > + if (band->rate > exceeded_rate[i]) { > + exceeded_rate[i] = band->rate; > exceeded_band[i] = m; > } > } > @@ -6242,8 +6246,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct > dp_packet_batch *packets_, > /* Update the exceeding band for the exceeding > packet. > * (Only one band will be fired by a packet, and that > * can be different for each packet.) */ > - if (band->up.rate > exceeded_rate[i]) { > - exceeded_rate[i] = band->up.rate; > + if (band->rate > exceeded_rate[i]) { > + exceeded_rate[i] = band->rate; > exceeded_band[i] = m; > } > } > @@ -6320,21 +6324,15 @@ dpif_netdev_meter_set(struct dpif *dpif, > ofproto_meter_id meter_id, > for (i = 0; i < config->n_bands; ++i) { > uint32_t band_max_delta_t; > > - /* Set burst size to a workable value if none specified. */ > - if (config->bands[i].burst_size == 0) { > - config->bands[i].burst_size = config->bands[i].rate; > - } > - > - meter->bands[i].up = config->bands[i]; > - /* Convert burst size to the bucket units: */ > - /* pkts => 1/1000 packets, kilobits => bits. */ > - meter->bands[i].up.burst_size *= 1000; > - /* Initialize bucket to empty. */ > - meter->bands[i].bucket = 0; > + meter->bands[i].type = config->bands[i].type; > + meter->bands[i].rate = config->bands[i].rate; > + meter->bands[i].burst_size = config->bands[i].burst_size; > + /* Start with a full bucket. */ > + meter->bands[i].bucket = meter->bands[i].rate * 1000ULL; > > /* Figure out max delta_t that is enough to fill any bucket. */ > band_max_delta_t > - = meter->bands[i].up.burst_size / meter->bands[i].up.rate; > + = meter->bands[i].bucket / meter->bands[i].rate; > if (band_max_delta_t > meter->max_delta_t) { > meter->max_delta_t = band_max_delta_t; > } > -- > 2.14.1 >
-- Best regards, Tonghao _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
