@@ -144,7 +144,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;
@@ -240,7 +240,7 @@ static void
conn_schedule_expiration(struct conn *conn, enum ct_timeout tm, long long now,
uint32_t tp_value)
{
- conn->expiration = now + tp_value * 1000;
+ atomic_store_relaxed(&conn->expiration, now + tp_value * 1000);
conn->exp.tm = tm;
ignore(atomic_flag_test_and_set(&conn->exp.reschedule));
}
@@ -99,6 +99,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 *);
static bool conn_expired(struct conn *, long long now);
static void set_mark(struct dp_packet *, struct conn *,
uint32_t val, uint32_t mask);
@@ -1018,13 +1019,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(ct, &conn_in->key, now, &conn, NULL);
- ovs_mutex_lock(&conn_in->lock);
+ conn_lookup(ct, &conn_in->key, now, &conn, NULL);
if (conn && seq_skew) {
conn->seq_skew = seq_skew;
conn->seq_skew_dir = seq_skew_dir;
@@ -1596,9 +1594,7 @@ ct_sweep(struct conntrack *ct, long long now, size_t limit)
continue;
}
- ovs_mutex_lock(&conn->lock);
- expiration = conn->expiration;
- ovs_mutex_unlock(&conn->lock);
+ expiration = conn_expiration(conn);
if (conn == end_of_queue) {
/* If we already re-enqueued this conn during this sweep,
@@ -2483,14 +2479,21 @@ 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)
{
if (conn->conn_type == CT_CONN_TYPE_DEFAULT) {
- ovs_mutex_lock(&conn->lock);
- bool expired = now >= conn->expiration ? true : false;
- ovs_mutex_unlock(&conn->lock);
- return expired;
+ return now >= conn_expiration(conn);
}
return false;
}
@@ -2633,7 +2636,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[conn->key.nw_proto];
if (class->conn_get_protoinfo) {