I think the use of the atomic variable in this patch is a bit odd.
ofproto_max_idle, is a regular old variable, even though it can be
written and read from different threads: the flow dumper and the main
thread.  But when shared among the revalidators, then we create a
special atomic in the struct udpif.

At any rate, I think it's good enough to just read ofproto_max_idle
directly whenever we need it.  If it changes, all the threads may not
get the update at the same time, but I don't think its a big deal.
What do you think?

Ethan

On Tue, Feb 11, 2014 at 2:19 PM, Joe Stringer <joestrin...@nicira.com> wrote:
> Signed-off-by: Joe Stringer <joestrin...@nicira.com>
> ---
>  ofproto/ofproto-dpif-upcall.c |    8 +++++---
>  ofproto/ofproto-provider.h    |    4 ++++
>  ofproto/ofproto.c             |    9 +++++++++
>  ofproto/ofproto.h             |    2 ++
>  vswitchd/bridge.c             |    2 ++
>  vswitchd/vswitch.ovsschema    |    8 ++++++--
>  vswitchd/vswitch.xml          |   21 +++++++++++++++++++++
>  7 files changed, 49 insertions(+), 5 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
> index e0a5aed..399da8a 100644
> --- a/ofproto/ofproto-dpif-upcall.c
> +++ b/ofproto/ofproto-dpif-upcall.c
> @@ -41,7 +41,6 @@
>  #define MAX_QUEUE_LENGTH 512
>  #define FLOW_MISS_MAX_BATCH 50
>  #define REVALIDATE_MAX_BATCH 50
> -#define MAX_IDLE 1500
>
>  VLOG_DEFINE_THIS_MODULE(ofproto_dpif_upcall);
>
> @@ -127,6 +126,7 @@ struct udpif {
>
>      /* Following fields are accessed and modified by different threads. */
>      atomic_uint flow_limit;            /* Datapath flow hard limit. */
> +    atomic_llong max_idle;             /* Max idle time for flows. */
>
>      /* n_flows_mutex prevents multiple threads updating these concurrently. 
> */
>      atomic_uint64_t n_flows;           /* Number of flows in the datapath. */
> @@ -263,6 +263,7 @@ udpif_create(struct dpif_backer *backer, struct dpif 
> *dpif)
>      udpif->dpif = dpif;
>      udpif->backer = backer;
>      atomic_init(&udpif->flow_limit, MIN(ofproto_flow_limit, 10000));
> +    atomic_init(&udpif->max_idle, ofproto_max_idle);
>      udpif->secret = random_uint32();
>      udpif->reval_seq = seq_create();
>      udpif->dump_seq = seq_create();
> @@ -622,7 +623,8 @@ udpif_flow_dumper(void *arg)
>                        duration);
>          }
>
> -        poll_timer_wait_until(start_time + MIN(MAX_IDLE, 500));
> +        atomic_store(&udpif->max_idle, ofproto_max_idle);
> +        poll_timer_wait_until(start_time + MIN(ofproto_max_idle, 500));
>          seq_wait(udpif->reval_seq, udpif->last_reval_seq);
>          latch_wait(&udpif->exit_latch);
>          poll_block();
> @@ -1383,7 +1385,7 @@ revalidate_udumps(struct revalidator *revalidator, 
> struct list *udumps)
>      n_flows = udpif_get_n_flows(udpif);
>
>      must_del = false;
> -    max_idle = MAX_IDLE;
> +    atomic_read(&udpif->max_idle, &max_idle);
>      if (n_flows > flow_limit) {
>          must_del = n_flows > 2 * flow_limit;
>          max_idle = 100;
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index 19d1551..4911788 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -459,6 +459,10 @@ void rule_collection_destroy(struct rule_collection *);
>   * ofproto-dpif implementation. */
>  extern unsigned ofproto_flow_limit;
>
> +/* Determines how long flows may be idle in the datapath before they are
> + * expired. */
> +extern long long int ofproto_max_idle;
> +
>  /* Number of upcall handler and revalidator threads. Only affects the
>   * ofproto-dpif implementation. */
>  extern size_t n_handlers, n_revalidators;
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index a9cf221..cd027cf 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -307,6 +307,7 @@ static size_t allocated_ofproto_classes;
>  struct ovs_mutex ofproto_mutex = OVS_MUTEX_INITIALIZER;
>
>  unsigned ofproto_flow_limit = OFPROTO_FLOW_LIMIT_DEFAULT;
> +long long int ofproto_max_idle = OFPROTO_MAX_IDLE_DEFAULT;
>  enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO;
>
>  size_t n_handlers, n_revalidators;
> @@ -698,6 +699,14 @@ ofproto_set_flow_limit(unsigned limit)
>      ofproto_flow_limit = limit;
>  }
>
> +/* Sets the maximum idle time for flows in the datapath before they are
> + * evicted. */
> +void
> +ofproto_set_max_idle(long long int max_idle)
> +{
> +    ofproto_max_idle = max_idle;
> +}
> +
>  /* Sets the path for handling flow misses. */
>  void
>  ofproto_set_flow_miss_model(unsigned model)
> diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
> index 0ac4454..a5d7824 100644
> --- a/ofproto/ofproto.h
> +++ b/ofproto/ofproto.h
> @@ -214,6 +214,7 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
>          )
>
>  #define OFPROTO_FLOW_LIMIT_DEFAULT 200000
> +#define OFPROTO_MAX_IDLE_DEFAULT 1200
>
>  /* How flow misses should be handled in ofproto-dpif */
>  enum ofproto_flow_miss_model {
> @@ -243,6 +244,7 @@ void ofproto_set_extra_in_band_remotes(struct ofproto *,
>                                         const struct sockaddr_in *, size_t n);
>  void ofproto_set_in_band_queue(struct ofproto *, int queue_id);
>  void ofproto_set_flow_limit(unsigned limit);
> +void ofproto_set_max_idle(long long int max_idle);
>  void ofproto_set_flow_miss_model(unsigned model);
>  void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu);
>  void ofproto_set_mac_table_config(struct ofproto *, unsigned idle_time,
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index cde4bd0..455ba14 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -494,6 +494,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch 
> *ovs_cfg)
>
>      ofproto_set_flow_limit(smap_get_int(&ovs_cfg->other_config, "flow-limit",
>                                          OFPROTO_FLOW_LIMIT_DEFAULT));
> +    ofproto_set_max_idle(smap_get_int(&ovs_cfg->other_config, "max-idle",
> +                                      OFPROTO_MAX_IDLE_DEFAULT));
>
>      ofproto_set_threads(
>          smap_get_int(&ovs_cfg->other_config, "n-handler-threads", 0),
> diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
> index 9eb21ed..c98b561 100644
> --- a/vswitchd/vswitch.ovsschema
> +++ b/vswitchd/vswitch.ovsschema
> @@ -1,6 +1,6 @@
>  {"name": "Open_vSwitch",
> - "version": "7.4.0",
> - "cksum": "951746691 20389",
> + "version": "7.4.1",
> + "cksum": "3218236985 20562",
>   "tables": {
>     "Open_vSwitch": {
>       "columns": {
> @@ -295,6 +295,10 @@
>         "flow_limit": {
>          "type": {"key": {"type": "integer", "minInteger": 0},
>                   "min": 0, "max": 1}},
> +       "max_idle": {
> +         "type": {"key": {"type": "integer", "minInteger": 500,
> +                          "maxInteger": 10000},
> +                  "min": 0, "max": 1}},
>         "overflow_policy": {
>          "type": {"key": {"type": "string",
>                           "enum": ["set", ["refuse", "evict"]]},
> diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
> index e915caf..6847f4c 100644
> --- a/vswitchd/vswitch.xml
> +++ b/vswitchd/vswitch.xml
> @@ -136,6 +136,21 @@
>          </p>
>        </column>
>
> +      <column name="other_config" key="max-idle"
> +              type='{"type": "integer", "minInteger": 500,
> +                     "maxInteger": 10000}'>
> +        <p>
> +            The maximum idle time in milliseconds for flows to be cached in 
> the
> +            datapath. A lower value may improve flow setup performance, but
> +            decrease the number of cached flows in the datapath. Conversely, 
> a
> +            higher value allows more flows to be maintained in the cache at 
> the
> +            expense of flow setup performance.
> +        </p>
> +        <p>
> +            The default is 1200.
> +        </p>
> +      </column>
> +
>        <column name="other_config" key="force-miss-model">
>          <p>
>            Specifies userspace behaviour for handling flow misses. This takes
> @@ -2500,6 +2515,12 @@
>        performance reasons.
>      </column>
>
> +    <column name="max_idle">
> +        Limits the idle time (in milliseconds) for the datapath flow cache.
> +        Flows may be swapped out of the cache if they are idle for longer 
> than
> +        this value.
> +    </column>
> +
>      <column name="overflow_policy">
>        <p>
>          Controls the switch's behavior when an OpenFlow flow table 
> modification
> --
> 1.7.9.5
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to