[ovs-dev] [meters 6/9] ofproto: Allocate meter bands separately from the meters themselves.
Ben Pfaff
blp at nicira.com
Thu Jun 27 22:19:41 UTC 2013
This simplifies updates since nothing has to move except the meter bands.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
ofproto/ofproto.c | 96 ++++++++++++++++------------------------------------
1 files changed, 30 insertions(+), 66 deletions(-)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 341cf10..f5be583 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -4207,7 +4207,7 @@ struct meter {
ofproto_meter_id provider_meter_id;
uint16_t flags; /* Meter flags. */
uint16_t n_bands; /* Number of meter bands. */
- struct ofputil_meter_band bands[0];
+ struct ofputil_meter_band *bands;
};
/*
@@ -4230,51 +4230,31 @@ ofproto_get_provider_meter_id(const struct ofproto * ofproto,
return UINT32_MAX;
}
-static struct meter *
-meter_create(const struct ofputil_meter_config *config)
+static void
+meter_update(struct meter *meter, const struct ofputil_meter_config *config)
{
- struct meter *meter
- = xmalloc(sizeof *meter + config->n_bands * sizeof *meter->bands);
- int i;
+ free(meter->bands);
- if (meter) {
- meter->provider_meter_id.uint32 = UINT32_MAX;
- meter->flags = config->flags;
- meter->n_bands = config->n_bands;
- meter->created = time_msec();
- list_init(&meter->rules);
- for (i = 0; i < config->n_bands; ++i) {
- meter->bands[i] = config->bands[i];
- }
- }
- return meter;
+ meter->flags = config->flags;
+ meter->n_bands = config->n_bands;
+ meter->bands = xmemdup(config->bands,
+ config->n_bands * sizeof *meter->bands);
}
-static void
-meter_update(struct ofproto *ofproto, struct meter *meter,
- struct meter *new_meter,
- const struct ofputil_meter_config *config)
-{
- if (new_meter) {
- new_meter->provider_meter_id = meter->provider_meter_id;
- /* Move rules list over. */
- if (list_is_empty(&meter->rules)) {
- list_init(&new_meter->rules);
- } else {
- new_meter->rules = meter->rules;
- list_moved(&new_meter->rules);
- }
- ofproto->meters[config->meter_id] = new_meter;
- free(meter);
- } else {
- int i;
- /* Update existing meter. */
- meter->flags = config->flags;
- meter->n_bands = config->n_bands;
- for (i = 0; i < config->n_bands; ++i) {
- meter->bands[i] = config->bands[i];
- }
- }
+static struct meter *
+meter_create(const struct ofputil_meter_config *config,
+ ofproto_meter_id provider_meter_id)
+{
+ struct meter *meter;
+
+ meter = xzalloc(sizeof *meter);
+ meter->provider_meter_id = provider_meter_id;
+ meter->created = time_msec();
+ list_init(&meter->rules);
+
+ meter_update(meter, config);
+
+ return meter;
}
static enum ofperr
@@ -4315,56 +4295,39 @@ handle_meter_mod(struct ofconn *ofconn, const struct ofp_header *oh)
switch (mm.command) {
case OFPMC13_ADD: {
- struct meter *meter;
+ ofproto_meter_id provider_meter_id = { UINT32_MAX };
if (ofproto->meters[meter_id]) {
error = OFPERR_OFPMMFC_METER_EXISTS;
break;
}
- meter = meter_create(&mm.meter);
- if (!meter) {
- error = OFPERR_OFPMMFC_OUT_OF_METERS;
- break;
- }
-
- error = ofproto->ofproto_class->meter_set(ofproto,
- &meter->provider_meter_id,
+ error = ofproto->ofproto_class->meter_set(ofproto, &provider_meter_id,
&mm.meter);
if (!error) {
- ofproto->meters[meter_id] = meter;
+ ovs_assert(provider_meter_id.uint32 != UINT32_MAX);
+ ofproto->meters[meter_id] = meter_create(&mm.meter,
+ provider_meter_id);
if (ofproto->last_meter < meter_id) {
ofproto->last_meter = meter_id;
}
- } else {
- free(meter);
}
break;
}
case OFPMC13_MODIFY: {
struct meter *meter = ofproto->meters[meter_id];
- struct meter *new_meter = NULL;
if (!meter) {
error = OFPERR_OFPMMFC_UNKNOWN_METER;
break;
}
- /* Realloc meter if number of bands increases. */
- if (mm.meter.n_bands > meter->n_bands) {
- new_meter = meter_create(&mm.meter);
- if (!new_meter) {
- error = OFPERR_OFPMMFC_OUT_OF_METERS;
- break;
- }
- }
error = ofproto->ofproto_class->meter_set(ofproto,
&meter->provider_meter_id,
&mm.meter);
+ ovs_assert(meter->provider_meter_id.uint32 != UINT32_MAX);
if (!error) {
- meter_update(ofproto, meter, new_meter, &mm.meter);
- } else if (new_meter) {
- free(new_meter);
+ meter_update(meter, &mm.meter);
}
break;
}
@@ -4421,6 +4384,7 @@ handle_meter_mod(struct ofconn *ofconn, const struct ofp_header *oh)
ofproto->meters[meter_id] = NULL;
ofproto->ofproto_class->meter_del(ofproto,
meter->provider_meter_id);
+ free(meter->bands);
free(meter);
}
--
1.7.2.5
More information about the dev
mailing list