andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone

Blame SOURCES/0046-Issue-4551-Paged-search-impacts-performance-5838.patch

e92659
From e7ef85ce90412ab2a7256a27bdd55fa94beb2921 Mon Sep 17 00:00:00 2001
e92659
From: progier389 <progier@redhat.com>
e92659
Date: Tue, 18 Jul 2023 11:17:07 +0200
e92659
Subject: [PATCH 1/2] Issue 4551 - Paged search impacts performance (#5838)
e92659
e92659
Problem:
e92659
Having a script looping doing a search with paged result impact greatly the performance of other clients
e92659
(for example ldclt bind+search rate decreased by 80% in the test case)
e92659
e92659
Cause:
e92659
Page result field in connection were protected by the connection mutex that is also used by the listener thread, in some cases this cause contention that delays the handling of new operations
e92659
e92659
Solution:
e92659
Do not rely on the connection mutex to protect the page result context but on a dedicated array of locks.
e92659
e92659
(cherry picked from commit 3c510e0a26e321949b552b5e8c887634d9d7e63e)
e92659
---
e92659
 ldap/servers/slapd/daemon.c       |   4 +-
e92659
 ldap/servers/slapd/main.c         |   2 +
e92659
 ldap/servers/slapd/opshared.c     |  26 +++---
e92659
 ldap/servers/slapd/pagedresults.c | 137 ++++++++++++++++++------------
e92659
 ldap/servers/slapd/proto-slap.h   |   3 +
e92659
 5 files changed, 105 insertions(+), 67 deletions(-)
e92659
e92659
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
e92659
index 5d8767df6..71c2bf911 100644
e92659
--- a/ldap/servers/slapd/daemon.c
e92659
+++ b/ldap/servers/slapd/daemon.c
e92659
@@ -1275,7 +1275,9 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "slapd_daemon",
e92659
                   "slapd shutting down - waiting for backends to close down\n");
e92659
 
e92659
-    eq_stop();
e92659
+    pageresult_lock_cleanup();
e92659
+    eq_stop(); /* deprecated */
e92659
+
e92659
     if (!in_referral_mode) {
e92659
         task_shutdown();
e92659
         uniqueIDGenCleanup();
e92659
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
e92659
index 5ca52ce74..d3ff99408 100644
e92659
--- a/ldap/servers/slapd/main.c
e92659
+++ b/ldap/servers/slapd/main.c
e92659
@@ -1094,6 +1094,7 @@ main(int argc, char **argv)
e92659
         }
e92659
 
e92659
         ps_init_psearch_system(); /* must come before plugin_startall() */
e92659
+        pageresult_lock_init();
e92659
 
e92659
 
e92659
         /* initialize UniqueID generator - must be done once backends are started
e92659
@@ -2311,6 +2312,7 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg)
e92659
 
e92659
             eq_init();                /* must be done before plugins started */
e92659
             ps_init_psearch_system(); /* must come before plugin_startall() */
e92659
+            pageresult_lock_init();
e92659
             plugin_startall(argc, argv, plugin_list);
e92659
             eq_start(); /* must be done after plugins started */
e92659
             charray_free(plugin_list);
e92659
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
e92659
index a1630e134..ec316dfb9 100644
e92659
--- a/ldap/servers/slapd/opshared.c
e92659
+++ b/ldap/servers/slapd/opshared.c
e92659
@@ -266,6 +266,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
     int pr_idx = -1;
e92659
     Slapi_DN *orig_sdn = NULL;
e92659
     int free_sdn = 0;
e92659
+    pthread_mutex_t *pagedresults_mutex = NULL;
e92659
 
e92659
     be_list[0] = NULL;
e92659
     referral_list[0] = NULL;
e92659
@@ -549,6 +550,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
             int32_t tlimit;
e92659
             slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &tlimit);
e92659
             pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx);
e92659
+            pagedresults_mutex = pageresult_lock_get_addr(pb_conn);
e92659
         }
e92659
 
e92659
         /*
e92659
@@ -665,10 +667,10 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
             /* PAGED RESULTS and already have the search results from the prev op */
e92659
             pagedresults_lock(pb_conn, pr_idx);
e92659
             /*
e92659
-       * In async paged result case, the search result might be released
e92659
-       * by other theads.  We need to double check it in the locked region.
e92659
-       */
e92659
-            PR_EnterMonitor(pb_conn->c_mutex);
e92659
+             * In async paged result case, the search result might be released
e92659
+             * by other theads.  We need to double check it in the locked region.
e92659
+             */
e92659
+            pthread_mutex_lock(pagedresults_mutex);
e92659
             pr_search_result = pagedresults_get_search_result(pb_conn, operation, 1 /*locked*/, pr_idx);
e92659
             if (pr_search_result) {
e92659
                 if (pagedresults_is_abandoned_or_notavailable(pb_conn, 1 /*locked*/, pr_idx)) {
e92659
@@ -676,7 +678,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
                     /* Previous operation was abandoned and the simplepaged object is not in use. */
e92659
                     send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
e92659
                     rc = LDAP_SUCCESS;
e92659
-                    PR_ExitMonitor(pb_conn->c_mutex);
e92659
+                    pthread_mutex_unlock(pagedresults_mutex);
e92659
                     goto free_and_return;
e92659
                 } else {
e92659
                     slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, pr_search_result);
e92659
@@ -690,7 +692,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
                 pr_stat = PAGEDRESULTS_SEARCH_END;
e92659
                 rc = LDAP_SUCCESS;
e92659
             }
e92659
-            PR_ExitMonitor(pb_conn->c_mutex);
e92659
+            pthread_mutex_unlock(pagedresults_mutex);
e92659
             pagedresults_unlock(pb_conn, pr_idx);
e92659
 
e92659
             if ((PAGEDRESULTS_SEARCH_END == pr_stat) || (0 == pnentries)) {
e92659
@@ -811,10 +813,10 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
                 /* PAGED RESULTS */
e92659
                 if (op_is_pagedresults(operation)) {
e92659
                     /* cleanup the slot */
e92659
-                    PR_EnterMonitor(pb_conn->c_mutex);
e92659
+                    pthread_mutex_lock(pagedresults_mutex);
e92659
                     pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx);
e92659
                     rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, 1);
e92659
-                    PR_ExitMonitor(pb_conn->c_mutex);
e92659
+                    pthread_mutex_unlock(pagedresults_mutex);
e92659
                 }
e92659
                 if (1 == flag_no_such_object) {
e92659
                     break;
e92659
@@ -855,11 +857,11 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
                     slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
e92659
                     if ((PAGEDRESULTS_SEARCH_END == pr_stat) || (0 == pnentries)) {
e92659
                         /* no more entries, but at least another backend */
e92659
-                        PR_EnterMonitor(pb_conn->c_mutex);
e92659
+                        pthread_mutex_lock(pagedresults_mutex);
e92659
                         pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx);
e92659
                         be->be_search_results_release(&sr);
e92659
                         rc = pagedresults_set_current_be(pb_conn, next_be, pr_idx, 1);
e92659
-                        PR_ExitMonitor(pb_conn->c_mutex);
e92659
+                        pthread_mutex_unlock(pagedresults_mutex);
e92659
                         pr_stat = PAGEDRESULTS_SEARCH_END; /* make sure stat is SEARCH_END */
e92659
                         if (NULL == next_be) {
e92659
                             /* no more entries && no more backends */
e92659
@@ -887,9 +889,9 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
e92659
                     next_be = NULL; /* to break the loop */
e92659
                     if (operation->o_status & SLAPI_OP_STATUS_ABANDONED) {
e92659
                         /* It turned out this search was abandoned. */
e92659
-                        PR_EnterMonitor(pb_conn->c_mutex);
e92659
+                        pthread_mutex_lock(pagedresults_mutex);
e92659
                         pagedresults_free_one_msgid_nolock(pb_conn, operation->o_msgid);
e92659
-                        PR_ExitMonitor(pb_conn->c_mutex);
e92659
+                        pthread_mutex_unlock(pagedresults_mutex);
e92659
                         /* paged-results-request was abandoned; making an empty cookie. */
e92659
                         pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
e92659
                         send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
e92659
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
e92659
index 8cefe164e..8c043f6af 100644
e92659
--- a/ldap/servers/slapd/pagedresults.c
e92659
+++ b/ldap/servers/slapd/pagedresults.c
e92659
@@ -12,6 +12,34 @@
e92659
 
e92659
 #include "slap.h"
e92659
 
e92659
+#define LOCK_HASH_SIZE 997 /* Should be a prime number */
e92659
+
e92659
+static pthread_mutex_t *lock_hash = NULL;
e92659
+
e92659
+void
e92659
+pageresult_lock_init()
e92659
+{
e92659
+    lock_hash = (pthread_mutex_t *)slapi_ch_calloc(LOCK_HASH_SIZE, sizeof(pthread_mutex_t));
e92659
+    for (size_t i=0; i
e92659
+        pthread_mutex_init(&lock_hash[i], NULL);
e92659
+    }
e92659
+}
e92659
+
e92659
+void
e92659
+pageresult_lock_cleanup()
e92659
+{
e92659
+    for (size_t i=0; i
e92659
+        pthread_mutex_destroy(&lock_hash[i]);
e92659
+    }
e92659
+    slapi_ch_free((void**)&lock_hash);
e92659
+}
e92659
+
e92659
+pthread_mutex_t *
e92659
+pageresult_lock_get_addr(Connection *conn)
e92659
+{
e92659
+    return &lock_hash[(((size_t)conn)/sizeof (Connection))%LOCK_HASH_SIZE];
e92659
+}
e92659
+
e92659
 /* helper function to clean up one prp slot */
e92659
 static void
e92659
 _pr_cleanup_one_slot(PagedResults *prp)
e92659
@@ -98,7 +126,7 @@ pagedresults_parse_control_value(Slapi_PBlock *pb,
e92659
         return LDAP_UNWILLING_TO_PERFORM;
e92659
     }
e92659
 
e92659
-    PR_EnterMonitor(conn->c_mutex);
e92659
+    pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     /* the ber encoding is no longer needed */
e92659
     ber_free(ber, 1);
e92659
     if (cookie.bv_len <= 0) {
e92659
@@ -206,7 +234,7 @@ bail:
e92659
             }
e92659
         }
e92659
     }
e92659
-    PR_ExitMonitor(conn->c_mutex);
e92659
+    pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
 
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_parse_control_value",
e92659
                   "<= idx %d\n", *index);
e92659
@@ -300,7 +328,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one",
e92659
                   "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (conn->c_pagedresults.prl_count <= 0) {
e92659
             slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one",
e92659
                           "conn=%" PRIu64 " paged requests list count is %d\n",
e92659
@@ -311,7 +339,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
e92659
             conn->c_pagedresults.prl_count--;
e92659
             rc = 0;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
 
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", "<= %d\n", rc);
e92659
@@ -319,7 +347,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
e92659
 }
e92659
 
e92659
 /*
e92659
- * Used for abandoning - conn->c_mutex is already locked in do_abandone.
e92659
+ * Used for abandoning - pageresult_lock_get_addr(conn) is already locked in do_abandone.
e92659
  */
e92659
 int
e92659
 pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid)
e92659
@@ -363,11 +391,11 @@ pagedresults_get_current_be(Connection *conn, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_current_be", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             be = conn->c_pagedresults.prl_list[index].pr_current_be;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_current_be", "<= %p\n", be);
e92659
@@ -382,13 +410,13 @@ pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int
e92659
                   "pagedresults_set_current_be", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
         if (!nolock)
e92659
-            PR_EnterMonitor(conn->c_mutex);
e92659
+            pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_current_be = be;
e92659
         }
e92659
         rc = 0;
e92659
         if (!nolock)
e92659
-            PR_ExitMonitor(conn->c_mutex);
e92659
+            pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_current_be", "<= %d\n", rc);
e92659
@@ -407,13 +435,13 @@ pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int
e92659
                   locked ? "locked" : "not locked", index);
e92659
     if (conn && (index > -1)) {
e92659
         if (!locked) {
e92659
-            PR_EnterMonitor(conn->c_mutex);
e92659
+            pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         }
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             sr = conn->c_pagedresults.prl_list[index].pr_search_result_set;
e92659
         }
e92659
         if (!locked) {
e92659
-            PR_ExitMonitor(conn->c_mutex);
e92659
+            pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         }
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
@@ -433,7 +461,7 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int lo
e92659
                   index, sr);
e92659
     if (conn && (index > -1)) {
e92659
         if (!locked)
e92659
-            PR_EnterMonitor(conn->c_mutex);
e92659
+            pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             PagedResults *prp = conn->c_pagedresults.prl_list + index;
e92659
             if (!(prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) || !sr) {
e92659
@@ -443,7 +471,7 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int lo
e92659
             rc = 0;
e92659
         }
e92659
         if (!locked)
e92659
-            PR_ExitMonitor(conn->c_mutex);
e92659
+            pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_search_result", "=> %d\n", rc);
e92659
@@ -460,11 +488,11 @@ pagedresults_get_search_result_count(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_search_result_count", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             count = conn->c_pagedresults.prl_list[index].pr_search_result_count;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_search_result_count", "<= %d\n", count);
e92659
@@ -481,11 +509,11 @@ pagedresults_set_search_result_count(Connection *conn, Operation *op, int count,
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_search_result_count", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_search_result_count = count;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
@@ -506,11 +534,11 @@ pagedresults_get_search_result_set_size_estimate(Connection *conn,
e92659
                   "pagedresults_get_search_result_set_size_estimate",
e92659
                   "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             count = conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_search_result_set_size_estimate", "<= %d\n",
e92659
@@ -532,11 +560,11 @@ pagedresults_set_search_result_set_size_estimate(Connection *conn,
e92659
                   "pagedresults_set_search_result_set_size_estimate",
e92659
                   "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate = count;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
@@ -555,11 +583,11 @@ pagedresults_get_with_sort(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_with_sort", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             flags = conn->c_pagedresults.prl_list[index].pr_flags & CONN_FLAG_PAGEDRESULTS_WITH_SORT;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_with_sort", "<= %d\n", flags);
e92659
@@ -576,14 +604,14 @@ pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, int index
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_with_sort", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             if (flags & OP_FLAG_SERVER_SIDE_SORTING) {
e92659
                 conn->c_pagedresults.prl_list[index].pr_flags |=
e92659
                     CONN_FLAG_PAGEDRESULTS_WITH_SORT;
e92659
             }
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_set_with_sort", "<= %d\n", rc);
e92659
@@ -600,11 +628,11 @@ pagedresults_get_unindexed(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_unindexed", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             flags = conn->c_pagedresults.prl_list[index].pr_flags & CONN_FLAG_PAGEDRESULTS_UNINDEXED;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_unindexed", "<= %d\n", flags);
e92659
@@ -621,12 +649,12 @@ pagedresults_set_unindexed(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_unindexed", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_flags |=
e92659
                 CONN_FLAG_PAGEDRESULTS_UNINDEXED;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
@@ -644,11 +672,11 @@ pagedresults_get_sort_result_code(Connection *conn, Operation *op, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_sort_result_code", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             code = conn->c_pagedresults.prl_list[index].pr_sort_result_code;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_get_sort_result_code", "<= %d\n", code);
e92659
@@ -665,11 +693,11 @@ pagedresults_set_sort_result_code(Connection *conn, Operation *op, int code, int
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_sort_result_code", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_sort_result_code = code;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
@@ -687,11 +715,11 @@ pagedresults_set_timelimit(Connection *conn, Operation *op, time_t timelimit, in
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_timelimit", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             slapi_timespec_expire_at(timelimit, &(conn->c_pagedresults.prl_list[index].pr_timelimit_hr));
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
         rc = 0;
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_set_timelimit", "<= %d\n", rc);
e92659
@@ -746,7 +774,7 @@ pagedresults_cleanup(Connection *conn, int needlock)
e92659
     }
e92659
 
e92659
     if (needlock) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     for (i = 0; conn->c_pagedresults.prl_list &&
e92659
                 i < conn->c_pagedresults.prl_maxlen;
e92659
@@ -765,7 +793,7 @@ pagedresults_cleanup(Connection *conn, int needlock)
e92659
     }
e92659
     conn->c_pagedresults.prl_count = 0;
e92659
     if (needlock) {
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_cleanup", "<= %d\n", rc);
e92659
     return rc;
e92659
@@ -792,7 +820,7 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
e92659
     }
e92659
 
e92659
     if (needlock) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     for (i = 0; conn->c_pagedresults.prl_list &&
e92659
                 i < conn->c_pagedresults.prl_maxlen;
e92659
@@ -812,7 +840,7 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
e92659
     conn->c_pagedresults.prl_maxlen = 0;
e92659
     conn->c_pagedresults.prl_count = 0;
e92659
     if (needlock) {
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_cleanup_all", "<= %d\n", rc);
e92659
     return rc;
e92659
@@ -831,7 +859,7 @@ pagedresults_check_or_set_processing(Connection *conn, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_check_or_set_processing", "=>\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             ret = (conn->c_pagedresults.prl_list[index].pr_flags &
e92659
                    CONN_FLAG_PAGEDRESULTS_PROCESSING);
e92659
@@ -839,7 +867,7 @@ pagedresults_check_or_set_processing(Connection *conn, int index)
e92659
             conn->c_pagedresults.prl_list[index].pr_flags |=
e92659
                                               CONN_FLAG_PAGEDRESULTS_PROCESSING;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_check_or_set_processing", "<= %d\n", ret);
e92659
@@ -858,7 +886,7 @@ pagedresults_reset_processing(Connection *conn, int index)
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_reset_processing", "=> idx=%d\n", index);
e92659
     if (conn && (index > -1)) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             ret = (conn->c_pagedresults.prl_list[index].pr_flags &
e92659
                    CONN_FLAG_PAGEDRESULTS_PROCESSING);
e92659
@@ -866,7 +894,7 @@ pagedresults_reset_processing(Connection *conn, int index)
e92659
             conn->c_pagedresults.prl_list[index].pr_flags &=
e92659
                                              ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
e92659
         }
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_reset_processing", "<= %d\n", ret);
e92659
@@ -885,7 +913,7 @@ pagedresults_reset_processing(Connection *conn, int index)
e92659
  * Do not return timed out here.  But let the next request take care the
e92659
  * timedout slot(s).
e92659
  *
e92659
- * must be called within conn->c_mutex
e92659
+ * must be called within pageresult_lock_get_addr(conn)
e92659
  */
e92659
 int
e92659
 pagedresults_is_timedout_nolock(Connection *conn)
e92659
@@ -912,7 +940,7 @@ pagedresults_is_timedout_nolock(Connection *conn)
e92659
 
e92659
 /*
e92659
  * reset all timeout
e92659
- * must be called within conn->c_mutex
e92659
+ * must be called within pageresult_lock_get_addr(conn)
e92659
  */
e92659
 int
e92659
 pagedresults_reset_timedout_nolock(Connection *conn)
e92659
@@ -977,9 +1005,9 @@ pagedresults_lock(Connection *conn, int index)
e92659
     if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
e92659
         return;
e92659
     }
e92659
-    PR_EnterMonitor(conn->c_mutex);
e92659
+    pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     prp = conn->c_pagedresults.prl_list + index;
e92659
-    PR_ExitMonitor(conn->c_mutex);
e92659
+    pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     if (prp->pr_mutex) {
e92659
         PR_Lock(prp->pr_mutex);
e92659
     }
e92659
@@ -993,9 +1021,9 @@ pagedresults_unlock(Connection *conn, int index)
e92659
     if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
e92659
         return;
e92659
     }
e92659
-    PR_EnterMonitor(conn->c_mutex);
e92659
+    pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     prp = conn->c_pagedresults.prl_list + index;
e92659
-    PR_ExitMonitor(conn->c_mutex);
e92659
+    pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     if (prp->pr_mutex) {
e92659
         PR_Unlock(prp->pr_mutex);
e92659
     }
e92659
@@ -1010,11 +1038,11 @@ pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int inde
e92659
         return 1; /* not abandoned, but do not want to proceed paged results op. */
e92659
     }
e92659
     if (!locked) {
e92659
-        PR_EnterMonitor(conn->c_mutex);
e92659
+        pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     prp = conn->c_pagedresults.prl_list + index;
e92659
     if (!locked) {
e92659
-        PR_ExitMonitor(conn->c_mutex);
e92659
+        pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
     }
e92659
     return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED;
e92659
 }
e92659
@@ -1039,13 +1067,14 @@ pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked)
e92659
                   "pagedresults_set_search_result_pb", "=> idx=%d, sr=%p\n", index, sr);
e92659
     if (conn && (index > -1)) {
e92659
         if (!locked)
e92659
-            PR_EnterMonitor(conn->c_mutex);
e92659
+            pthread_mutex_lock(pageresult_lock_get_addr(conn));
e92659
         if (index < conn->c_pagedresults.prl_maxlen) {
e92659
             conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
e92659
             rc = 0;
e92659
         }
e92659
-        if (!locked)
e92659
-            PR_ExitMonitor(conn->c_mutex);
e92659
+        if (!locked) {
e92659
+            pthread_mutex_unlock(pageresult_lock_get_addr(conn));
e92659
+        }
e92659
     }
e92659
     slapi_log_err(SLAPI_LOG_TRACE,
e92659
                   "pagedresults_set_search_result_pb", "<= %d\n", rc);
e92659
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
e92659
index 50f1ff75a..b8f736107 100644
e92659
--- a/ldap/servers/slapd/proto-slap.h
e92659
+++ b/ldap/servers/slapd/proto-slap.h
e92659
@@ -1489,6 +1489,9 @@ int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt, int s
e92659
 /*
e92659
  * pagedresults.c
e92659
  */
e92659
+void pageresult_lock_init();
e92659
+void pageresult_lock_cleanup();
e92659
+pthread_mutex_t *pageresult_lock_get_addr(Connection *conn);
e92659
 int pagedresults_parse_control_value(Slapi_PBlock *pb, struct berval *psbvp, ber_int_t *pagesize, int *index, Slapi_Backend *be);
e92659
 void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, ber_int_t estimate, int curr_search_count, int index);
e92659
 Slapi_Backend *pagedresults_get_current_be(Connection *conn, int index);
e92659
-- 
e92659
2.41.0
e92659