Felix Huettner via dev <[email protected]> writes:

> Future patches will move more resources to a per zone scope.
> To make it easier to review we just split out the conns to a separate
> struct in here.
>
> Signed-off-by: Felix Huettner <[email protected]>
> ---
>  lib/conntrack-private.h |  6 +++-
>  lib/conntrack.c         | 74 +++++++++++++++++++++++++++++------------
>  2 files changed, 57 insertions(+), 23 deletions(-)
>
> diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h
> index 0141afd4a..a0aaf5bc3 100644
> --- a/lib/conntrack-private.h
> +++ b/lib/conntrack-private.h
> @@ -207,9 +207,13 @@ struct conntrack_zone_limit {
>      uint32_t zone_limit_seq; /* Used to disambiguate zone limit counts. */
>  };
>  
> +struct conntrack_zone {
> +    struct cmap conns;
> +};
> +
>  struct conntrack {
>      struct ovs_mutex ct_lock; /* Protects the following fields. */
> -    struct cmap conns[UINT16_MAX + 1];
> +    struct conntrack_zone zones[UINT16_MAX + 1];
>      struct rculist exp_lists[N_EXP_LISTS];
>      struct cmap zone_limits;
>      struct cmap timeout_policies;
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 1a3e87c1e..f313eaa15 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -246,6 +246,15 @@ conn_key_cmp(const struct conn_key *key1, const struct 
> conn_key *key2)
>      return 1;
>  }
>  
> +static struct conntrack_zone *
> +zone_lookup(struct conntrack *ct, int32_t zone)
> +{
> +    if (zone < MIN_ZONE || zone > MAX_ZONE) {
> +        return NULL;
> +    }

I don't think we actually even need this check.  At least by the time
the final patch lands, I can't find a way for most of the lookup paths
to find this, and we also sometimes completely bypass the lookup in the
series (by just using &ct->zones[idx] directly), and in many places we
just simply trust the return value.  If you really want a safety valve
here (could be useful going forward) we should have a single commit that
introduces this and switches all the accessors from `&ct->zones[..]` to
this call, and have a NULL check against it.

But I actually think it could be okay to just drop this helper
completely.

> +    return &ct->zones[zone];
> +}
> +
>  /* Initializes the connection tracker 'ct'.  The caller is responsible for
>   * calling 'conntrack_destroy()', when the instance is not needed anymore */
>  struct conntrack *
> @@ -267,8 +276,8 @@ conntrack_init(void)
>  
>      ovs_mutex_init_adaptive(&ct->ct_lock);
>      ovs_mutex_lock(&ct->ct_lock);
> -    for (unsigned i = 0; i < ARRAY_SIZE(ct->conns); i++) {
> -        cmap_init(&ct->conns[i]);
> +    for (unsigned i = 0; i < ARRAY_SIZE(ct->zones); i++) {
> +        cmap_init(&ct->zones[i].conns);
>      }
>      for (unsigned i = 0; i < ARRAY_SIZE(ct->exp_lists); i++) {
>          rculist_init(&ct->exp_lists[i]);
> @@ -563,20 +572,26 @@ static void
>  conn_clean__(struct conntrack *ct, struct conn *conn)
>      OVS_REQUIRES(ct->ct_lock)
>  {
> +    struct conntrack_zone *cz;
> +    uint16_t fwd_zone;
>      uint32_t hash;
>  
>      if (conn->alg) {
>          expectation_clean(ct, &conn->key_node[CT_DIR_FWD].key);
>      }
>  
> +    fwd_zone = conn->key_node[CT_DIR_FWD].key.zone;
> +    cz = zone_lookup(ct, fwd_zone);
> +
>      hash = conn_key_hash(&conn->key_node[CT_DIR_FWD].key, ct->hash_basis);
> -    cmap_remove(&ct->conns[conn->key_node[CT_DIR_FWD].key.zone],
> +    cmap_remove(&cz->conns,
>                  &conn->key_node[CT_DIR_FWD].cm_node, hash);
>  
>      if (conn->nat_action) {
> +        ovs_assert(fwd_zone == conn->key_node[CT_DIR_REV].key.zone);
>          hash = conn_key_hash(&conn->key_node[CT_DIR_REV].key,
>                               ct->hash_basis);
> -        cmap_remove(&ct->conns[conn->key_node[CT_DIR_REV].key.zone],
> +        cmap_remove(&cz->conns,
>                      &conn->key_node[CT_DIR_REV].cm_node, hash);
>      }
>  
> @@ -648,8 +663,8 @@ conntrack_destroy(struct conntrack *ct)
>      }
>  
>      ovs_mutex_lock(&ct->ct_lock);
> -    for (unsigned i = 0; i < ARRAY_SIZE(ct->conns); i++) {
> -        cmap_destroy(&ct->conns[i]);
> +    for (unsigned i = 0; i < ARRAY_SIZE(ct->zones); i++) {
> +        cmap_destroy(&ct->zones[i].conns);
>      }
>      cmap_destroy(&ct->zone_limits);
>      cmap_destroy(&ct->timeout_policies);
> @@ -670,7 +685,7 @@ conntrack_destroy(struct conntrack *ct)
>  
>  
>  static bool
> -conn_key_lookup(struct conntrack *ct, const struct conn_key *key,
> +conn_key_lookup(struct conntrack_zone *cz, const struct conn_key *key,
>                  uint32_t hash, long long now, struct conn **conn_out,
>                  bool *reply)
>  {
> @@ -678,7 +693,7 @@ conn_key_lookup(struct conntrack *ct, const struct 
> conn_key *key,
>      struct conn *conn = NULL;
>      bool found = false;
>  
> -    CMAP_FOR_EACH_WITH_HASH (keyn, cm_node, hash, &ct->conns[key->zone]) {
> +    CMAP_FOR_EACH_WITH_HASH (keyn, cm_node, hash, &cz->conns) {
>          if (keyn->dir == CT_DIR_FWD) {
>              conn = CONTAINER_OF(keyn, struct conn, key_node[CT_DIR_FWD]);
>          } else {
> @@ -710,12 +725,21 @@ out_found:
>      return found;
>  }
>  
> +static bool
> +conn_lookup_zone(struct conntrack *ct, struct conntrack_zone *cz,
> +                 const struct conn_key *key, long long now,
> +                 struct conn **conn_out, bool *reply)
> +{
> +    uint32_t hash = conn_key_hash(key, ct->hash_basis);
> +    return conn_key_lookup(cz, key, hash, now, conn_out, reply);
> +}
> +
>  static bool
>  conn_lookup(struct conntrack *ct, const struct conn_key *key,
>              long long now, struct conn **conn_out, bool *reply)
>  {
> -    uint32_t hash = conn_key_hash(key, ct->hash_basis);
> -    return conn_key_lookup(ct, key, hash, now, conn_out, reply);
> +    struct conntrack_zone *cz = &ct->zones[key->zone];
> +    return conn_lookup_zone(ct, cz, key, now, conn_out, reply);
>  }
>  
>  static void
> @@ -1024,7 +1048,8 @@ ct_verify_helper(const char *helper, enum 
> ct_alg_ctl_type ct_alg_ctl)
>  }
>  
>  static struct conn *
> -conn_insert(struct conntrack *ct, struct dp_packet *pkt,
> +conn_insert(struct conntrack *ct, struct conntrack_zone *cz,
> +            struct dp_packet *pkt,
>              struct conn_lookup_ctx *ctx, long long now,
>              const struct nat_action_info_t *nat_action_info,
>              const char *helper, const struct alg_exp_node *alg_exp,
> @@ -1107,11 +1132,11 @@ conn_insert(struct conntrack *ct, struct dp_packet 
> *pkt,
>          nat_packet(pkt, nc, false, ctx->icmp_related);
>          uint32_t rev_hash = conn_key_hash(&rev_key_node->key,
>                                            ct->hash_basis);
> -        cmap_insert(&ct->conns[ctx->key.zone],
> +        cmap_insert(&cz->conns,
>                      &rev_key_node->cm_node, rev_hash);
>      }
>  
> -    cmap_insert(&ct->conns[ctx->key.zone],
> +    cmap_insert(&cz->conns,
>                  &fwd_key_node->cm_node, ctx->hash);
>      conn_expire_push_front(ct, nc);
>      atomic_count_inc(&ct->n_conn);
> @@ -1163,6 +1188,7 @@ conn_maybe_not_found(struct conntrack *ct, struct 
> dp_packet *pkt,
>                       const char *helper, const struct alg_exp_node *alg_exp,
>                       enum ct_alg_ctl_type ct_alg_ctl, uint32_t tp_id)
>  {
> +    struct conntrack_zone *cz = zone_lookup(ct, ctx->key.zone);
>      struct conn *nc = NULL;
>  
>      COVERAGE_INC(conntrack_maybe_not_found);
> @@ -1177,18 +1203,18 @@ conn_maybe_not_found(struct conntrack *ct, struct 
> dp_packet *pkt,
>       * analysis. */
>      if (commit) {
>          ovs_mutex_lock(&ct->ct_lock);
> -        bool found = conn_lookup(ct, &ctx->key, now, NULL, NULL);
> +        bool found = conn_lookup_zone(ct, cz, &ctx->key, now, NULL, NULL);
>          if (!found) {
>              if (!pkt_validate_and_set_new_ct_state(pkt, ctx, alg_exp)) {
>                  ovs_mutex_unlock(&ct->ct_lock);
>                  return nc;
>              }
> -            nc = conn_insert(ct, pkt, ctx, now, nat_action_info,
> +            nc = conn_insert(ct, cz, pkt, ctx, now, nat_action_info,
>                               helper, alg_exp, ct_alg_ctl, tp_id);
>          }
>          ovs_mutex_unlock(&ct->ct_lock);
>      } else {
> -        bool found = conn_lookup(ct, &ctx->key, now, NULL, NULL);
> +        bool found = conn_lookup_zone(ct, cz, &ctx->key, now, NULL, NULL);
>          if (!found) {
>              pkt_validate_and_set_new_ct_state(pkt, ctx, alg_exp);
>          }
> @@ -1399,8 +1425,8 @@ initial_conn_lookup(struct conntrack *ct, struct 
> conn_lookup_ctx *ctx,
>           * reverse key. */
>          conn_key_reverse(&ctx->key);
>      }
> -
> -    conn_key_lookup(ct, &ctx->key, ctx->hash, now, &ctx->conn, &ctx->reply);
> +    struct conntrack_zone *cz = &ct->zones[ctx->key.zone];
> +    conn_key_lookup(cz, &ctx->key, ctx->hash, now, &ctx->conn, &ctx->reply);
>  
>      if (natted) {
>          if (OVS_LIKELY(ctx->conn)) {
> @@ -1427,6 +1453,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
>              const struct nat_action_info_t *nat_action_info,
>              const char *helper, uint32_t tp_id)
>  {
> +    ovs_assert(ctx->key.zone == zone);
> +
>      /* Reset ct_state whenever entering a new zone. */
>      if (pkt->md.ct_state && pkt->md.ct_zone != zone) {
>          pkt->md.ct_state = 0;
> @@ -2915,7 +2943,8 @@ conntrack_dump_start(struct conntrack *ct, struct 
> conntrack_dump *dump,
>  
>      dump->ct = ct;
>      *ptot_bkts = 1; /* Need to clean up the callers. */
> -    dump->cursor = cmap_cursor_start(&dump->ct->conns[dump->current_zone]);
> +    dump->cursor = cmap_cursor_start(
> +            &dump->ct->zones[dump->current_zone].conns);
>      return 0;
>  }
>  
> @@ -2946,7 +2975,8 @@ conntrack_dump_next(struct conntrack_dump *dump, struct 
> ct_dpif_entry *entry)
>              break;
>          }
>          dump->current_zone++;
> -        dump->cursor = 
> cmap_cursor_start(&dump->ct->conns[dump->current_zone]);
> +        dump->cursor = cmap_cursor_start(
> +                &dump->ct->zones[dump->current_zone].conns);
>      }
>  
>      return EOF;
> @@ -3016,7 +3046,7 @@ conntrack_flush_zone(struct conntrack *ct, const 
> uint16_t zone)
>      struct conn_key_node *keyn;
>      struct conn *conn;
>  
> -    CMAP_FOR_EACH (keyn, cm_node, &ct->conns[zone]) {
> +    CMAP_FOR_EACH (keyn, cm_node, &ct->zones[zone].conns) {
>          if (keyn->dir != CT_DIR_FWD) {
>              continue;
>          }
> @@ -3034,7 +3064,7 @@ conntrack_flush(struct conntrack *ct, const uint16_t 
> *zone)
>          return conntrack_flush_zone(ct, *zone);
>      }
>  
> -    for (unsigned i = 0; i < ARRAY_SIZE(ct->conns); i++) {
> +    for (unsigned i = 0; i < ARRAY_SIZE(ct->zones); i++) {
>          conntrack_flush_zone(ct, i);
>      }
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to