@@ -110,7 +110,7 @@ struct conn {
/* Mutable data. */
struct ovs_mutex lock; /* Guards all mutable fields. */
ovs_u128 label;
- long long expiration;
+ atomic_llong expiration;
uint32_t mark;
int seq_skew;
@@ -257,7 +257,7 @@ conn_update_expiration(struct conntrack *ct, struct conn *conn,
ct_timeout_str[tm], conn->key_node[CT_DIR_FWD].key.zone,
conn->tp_id, val);
- conn->expiration = now + val * 1000;
+ atomic_store_relaxed(&conn->expiration, now + val * 1000);
}
/* ct_lock must be held. */
@@ -102,6 +102,7 @@ static enum ct_update_res conn_update(struct conntrack *ct, struct conn *conn,
struct dp_packet *pkt,
struct conn_lookup_ctx *ctx,
long long now);
+static long long int conn_expiration(const struct conn *conn);
static bool conn_expired(struct conn *, long long now);
static void set_mark(struct dp_packet *, struct conn *,
uint32_t val, uint32_t mask);
@@ -579,7 +580,6 @@ conn_key_lookup__(struct conntrack *ct, unsigned bucket,
conn_clean(ct, conn);
continue;
}
-
for (int i = CT_DIR_FWD; i < CT_DIR_MAX; i++) {
if (!conn_key_cmp(&conn->key_node[i].key, key)) {
found = true;
@@ -1063,13 +1063,10 @@ un_nat_packet(struct dp_packet *pkt, const struct conn *conn,
static void
conn_seq_skew_set(struct conntrack *ct, const struct conn *conn_in,
long long now, int seq_skew, bool seq_skew_dir)
- OVS_NO_THREAD_SAFETY_ANALYSIS
{
struct conn *conn;
- ovs_mutex_unlock(&conn_in->lock);
- conn_lookup_gc(ct, &conn_in->key_node[CT_DIR_FWD].key, now, &conn, NULL);
- ovs_mutex_lock(&conn_in->lock);
+ conn_lookup_gc(ct, &conn_in->key_node[CT_DIR_FWD].key, now, &conn, NULL);
if (conn && seq_skew) {
conn->seq_skew = seq_skew;
conn->seq_skew_dir = seq_skew_dir;
@@ -1661,9 +1658,7 @@ sweep_bucket(struct conntrack *ct, struct ct_bucket *bucket,
}
conn = CONTAINER_OF(keyn, struct conn, key_node[keyn->key.dir]);
- ovs_mutex_lock(&conn->lock);
- expiration = conn->expiration;
- ovs_mutex_unlock(&conn->lock);
+ expiration = conn_expiration(conn);
if (now >= expiration) {
conn_clean(ct, conn);
@@ -2671,12 +2666,20 @@ conn_update(struct conntrack *ct, struct conn *conn, struct dp_packet *pkt,
return update_res;
}
+static long long int
+conn_expiration(const struct conn *conn)
+{
+ long long int expiration;
+
+ atomic_read_relaxed(&CONST_CAST(struct conn *, conn)->expiration,
+ &expiration);
+ return expiration;
+}
+
static bool
conn_expired(struct conn *conn, long long now)
{
- ovs_mutex_lock(&conn->lock);
- bool expired = now >= conn->expiration ? true : false;
- ovs_mutex_unlock(&conn->lock);
+ bool expired = now >= conn_expiration(conn) ? true : false;
return expired;
}
@@ -2808,7 +2811,7 @@ conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
entry->mark = conn->mark;
memcpy(&entry->labels, &conn->label, sizeof entry->labels);
- long long expiration = conn->expiration - now;
+ long long expiration = conn_expiration(conn) - now;
struct ct_l4_proto *class = l4_protos[key->nw_proto];
if (class->conn_get_protoinfo) {