MEDIUM: shctx: Descend shctx_lock calls into the shctx_row_reserve_hot
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 16 Nov 2023 16:38:23 +0000 (17:38 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 16 Nov 2023 18:35:10 +0000 (19:35 +0100)
Descend the shctx_lock calls into the shctx_row_reserve_hot so that the
cases when we don't need to lock anything (enough space in the current
row or not enough space in the 'avail' list) do not take the lock at
all.
In sh_ssl_sess_new_cb the lock had to be descended into
sh_ssl_sess_store in order not to cover the shctx_row_reserve_hot call
anymore.

src/cache.c
src/shctx.c
src/ssl_sock.c

index caa71e8..03651c8 100644 (file)
@@ -770,13 +770,10 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms
 
   end:
 
-       shctx_wrlock(shctx);
        fb = shctx_row_reserve_hot(shctx, st->first_block, trash.data);
        if (!fb) {
-               shctx_wrunlock(shctx);
                goto no_cache;
        }
-       shctx_wrunlock(shctx);
 
        ret = shctx_row_data_append(shctx, st->first_block,
                                    (unsigned char *)b_head(&trash), b_data(&trash));
@@ -1225,9 +1222,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
        }
        cache_wrunlock(cache);
 
-       shctx_wrlock(shctx);
        first = shctx_row_reserve_hot(shctx, NULL, sizeof(struct cache_entry));
-       shctx_wrunlock(shctx);
        if (!first) {
                goto out;
        }
@@ -1327,12 +1322,9 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px,
                if (set_secondary_key_encoding(htx, object->secondary_key))
                    goto out;
 
-       shctx_wrlock(shctx);
        if (!shctx_row_reserve_hot(shctx, first, trash.data)) {
-               shctx_wrunlock(shctx);
                goto out;
        }
-       shctx_wrunlock(shctx);
 
        /* cache the headers in a http action because it allows to chose what
         * to cache, for example you might want to cache a response before
index a9ea4c3..daf7866 100644 (file)
@@ -35,10 +35,6 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
 
        BUG_ON(data_len < 0);
 
-       /* not enough usable blocks */
-       if (data_len > shctx->nbav * shctx->block_size)
-               goto out;
-
        /* Check the object size limit. */
        if (shctx->max_obj_size > 0) {
                if ((first && first->len + data_len > shctx->max_obj_size) ||
@@ -66,8 +62,19 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
                }
        }
 
+       shctx_wrlock(shctx);
+
+       /* not enough usable blocks */
+       if (data_len > shctx->nbav * shctx->block_size) {
+               shctx_wrunlock(shctx);
+               goto out;
+       }
+
+
        if (data_len <= 0 || LIST_ISEMPTY(&shctx->avail)) {
-               return NULL;
+               ret = NULL;
+               shctx_wrunlock(shctx);
+               goto out;
        }
 
        list_for_each_entry_safe(block, sblock, &shctx->avail, list) {
@@ -101,6 +108,8 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
                }
        }
 
+       shctx_wrunlock(shctx);
+
 out:
        return ret;
 }
index bcbcb84..3a8f248 100644 (file)
@@ -4239,6 +4239,8 @@ static int sh_ssl_sess_store(unsigned char *s_id, unsigned char *data, int data_
                return 0;
        }
 
+       shctx_wrlock(ssl_shctx);
+
        /* STORE the key in the first elem */
        sh_ssl_sess = (struct sh_ssl_sess_hdr *)first->data;
        memcpy(sh_ssl_sess->key_data, s_id, SSL_MAX_SSL_SESSION_ID_LENGTH);
@@ -4267,6 +4269,8 @@ static int sh_ssl_sess_store(unsigned char *s_id, unsigned char *data, int data_
 
        shctx_row_reattach(ssl_shctx, first);
 
+       shctx_wrunlock(ssl_shctx);
+
        return 1;
 }
 
@@ -4408,10 +4412,8 @@ int sh_ssl_sess_new_cb(SSL *ssl, SSL_SESSION *sess)
        i2d_SSL_SESSION(sess, &p);
 
 
-       shctx_wrlock(ssl_shctx);
        /* store to cache */
        sh_ssl_sess_store(encid, encsess, data_len);
-       shctx_wrunlock(ssl_shctx);
 err:
        /* reset original length values */
        SSL_SESSION_set1_id(sess, encid, sid_length);