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]> --- Notes: v3->v4: split to 4 patches, this is 1/4 of the previous patch 5 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; + } + 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); } -- 2.43.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
