File 0579-Optimize-pkix_db-cert-selection.patch of Package erlang

From bc35b4f14f100bf95db685d704f06d076bfb8c31 Mon Sep 17 00:00:00 2001
From: John Altenmueller <jaltenmueller@whatsapp.com>
Date: Thu, 30 Nov 2023 16:32:19 -0800
Subject: [PATCH] Optimize pkix_db cert selection

During high load, we observe lock contention on this ETS table:

```
> lcnt:inspect(db_tab, [{print, [id, colls, ratio, duration]}]).

                      id  #collisions  collisions [%]  duration [%]
                     --- ------------ --------------- -------------
ssl_otp_cacertificate_db         7827         12.5136      616.1264
     ssl_otp_ca_file_ref           30          0.2561        0.0026
```

ets:select is more efficient than using ets:foldl and in practice
reduces the contention that we see here.

Separately I plan to also issue another PR to add read_concurrency to
the ETS table which has also helped reduce the incidence of this.
---
 lib/ssl/src/ssl_handshake.erl |  7 +------
 lib/ssl/src/ssl_pkix_db.erl   | 10 +++++++++-
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index d44ed05e85..05a084a9f2 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -2019,12 +2019,7 @@ supported_cert_type_or_empty(Algo, Type) ->
     end.
 
 certificate_authorities_from_db(CertDbHandle, CertDbRef) when is_reference(CertDbRef) ->
-    ConnectionCerts = fun({{Ref, _, _}, Cert}, Acc) when Ref  == CertDbRef ->
-			      [Cert | Acc];
-			 (_, Acc) ->
-			      Acc
-		      end,
-    ssl_pkix_db:foldl(ConnectionCerts, [], CertDbHandle);
+    ssl_pkix_db:select_certs_by_ref(CertDbRef, CertDbHandle);
 certificate_authorities_from_db(_CertDbHandle, {extracted, CertDbData}) ->
     %% Cache disabled, Ref contains data
     lists:foldl(fun({decoded, {_Key,Cert}}, Acc) -> [Cert | Acc] end,
diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl
index eac9e2a8b3..4932f923c3 100644
--- a/lib/ssl/src/ssl_pkix_db.erl
+++ b/lib/ssl/src/ssl_pkix_db.erl
@@ -36,7 +36,7 @@
 	 extract_trusted_certs/1,
 	 remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1,
 	 ref_count/3, lookup_trusted_cert/4, foldl/3, select_certentries_by_ref/2,
-	 decode_pem_file/1, lookup/2]).
+	 select_certs_by_ref/2, decode_pem_file/1, lookup/2]).
 
 %%====================================================================
 %% Internal application API
@@ -251,6 +251,14 @@ foldl(Fun, Acc0, Cache) ->
 select_certentries_by_ref(Ref, Cache) ->
     ets:select(Cache, [{{{Ref,'_', '_'}, '_'},[],['$_']}]).
 
+%%--------------------------------------------------------------------
+-spec select_certs_by_ref(reference(), db_handle()) -> term().
+%%
+%% Description: Select certs originating from same source
+%%--------------------------------------------------------------------
+select_certs_by_ref(Ref, Cache) ->
+    ets:select(Cache, [{{{Ref,'_','_'},'$1'},[],['$1']}]).
+
 %%--------------------------------------------------------------------
 -spec ref_count(term(), db_handle(), integer()) -> integer().
 %%
-- 
2.35.3

openSUSE Build Service is sponsored by