]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stick-table: always use atomic ops to requeue the table's task
authorWilly Tarreau <w@1wt.eu>
Wed, 12 Oct 2022 10:00:50 +0000 (10:00 +0000)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Oct 2022 12:19:05 +0000 (14:19 +0200)
We're generalizing the change performed in previous commit "MEDIUM:
stick-table: requeue the expiration task out of the exclusive lock"
to stktable_requeue_exp() so that it can also be used by callers of
__stktable_store(). At the moment there's still no visible change
since it's still called under the write lock. However, the previous
code in stitable_touch_with_exp() was updated to use this function.

include/haproxy/stick_table.h
src/stick_table.c

index c5cd3c8fe25149b6b8d93ee1b2126b6e9999865b..e78bbd646cf4a0a57f435ad606b3be2aeb80c4c5 100644 (file)
@@ -50,6 +50,7 @@ int parse_stick_table(const char *file, int linenum, char **args,
                       struct stktable *t, char *id, char *nid, struct peers *peers);
 struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *key);
 struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts);
+void stktable_requeue_exp(struct stktable *t, const struct stksess *ts);
 void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int decrefcount, int expire, int decrefcnt);
 void stktable_touch_remote(struct stktable *t, struct stksess *ts, int decrefcnt);
 void stktable_touch_local(struct stktable *t, struct stksess *ts, int decrefccount);
index facd5fa786a31905e00597a284d1b02d57f7843c..57c1b177571c1870133eb86c8ce46907de83383e 100644 (file)
@@ -378,32 +378,11 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local,
 {
        struct eb32_node * eb;
        int locked = 0;
-       int old_exp, new_exp;
 
        if (expire != HA_ATOMIC_LOAD(&ts->expire)) {
                /* we'll need to set the expiration and to wake up the expiration timer .*/
                HA_ATOMIC_STORE(&ts->expire, expire);
-               if (t->expire) {
-                       /* set both t->exp_next and the task's expire to the newest
-                        * expiration date.
-                        */
-                       old_exp = HA_ATOMIC_LOAD(&t->exp_next);
-                       do {
-                               new_exp = tick_first(expire, old_exp);
-                       } while (new_exp != old_exp &&
-                                !HA_ATOMIC_CAS(&t->exp_next, &old_exp, new_exp) &&
-                                __ha_cpu_relax());
-
-                       old_exp = HA_ATOMIC_LOAD(&t->exp_task->expire);
-                       do {
-                               new_exp = HA_ATOMIC_LOAD(&t->exp_next);
-                       } while (new_exp != old_exp &&
-                                !HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp) &&
-                                __ha_cpu_relax());
-
-                       task_queue(t->exp_task);
-                       /* keep the lock */
-               }
+               stktable_requeue_exp(t, ts);
        }
 
        /* If sync is enabled */
@@ -516,11 +495,31 @@ struct stksess *__stktable_store(struct stktable *t, struct stksess *ts)
 /* requeues the table's expiration task to take the recently added <ts> into
  * account. This is performed atomically and doesn't require any lock.
  */
-static void stktable_requeue_exp(struct stktable *t, const struct stksess *ts)
+void stktable_requeue_exp(struct stktable *t, const struct stksess *ts)
 {
+       int old_exp, new_exp;
+       int expire = ts->expire;
+
        if (!t->expire)
                return;
-       t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
+
+       /* set both t->exp_next and the task's expire to the newest
+        * expiration date.
+        */
+       old_exp = HA_ATOMIC_LOAD(&t->exp_next);
+       do {
+               new_exp = tick_first(expire, old_exp);
+       } while (new_exp != old_exp &&
+                !HA_ATOMIC_CAS(&t->exp_next, &old_exp, new_exp) &&
+                __ha_cpu_relax());
+
+       old_exp = HA_ATOMIC_LOAD(&t->exp_task->expire);
+       do {
+               new_exp = HA_ATOMIC_LOAD(&t->exp_next);
+       } while (new_exp != old_exp &&
+                !HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp) &&
+                __ha_cpu_relax());
+
        task_queue(t->exp_task);
 }