Blame SOURCES/0097-Ticket-49768-Under-network-intensive-load-persistent.patch

92192e
From 2136ba8dd18e72bfbe037517c10187bfe695628f Mon Sep 17 00:00:00 2001
92192e
From: Thierry Bordaz <tbordaz@redhat.com>
92192e
Date: Thu, 24 May 2018 15:36:34 +0200
92192e
Subject: [PATCH] Ticket 49768 - Under network intensive load persistent search
92192e
 can erronously decrease connection refcnt
92192e
92192e
Bug Description:
92192e
	If a connection enters in turbo mode (because of high traffic) or
92192e
	a worker reads several requests in the read buffer (more_data), the thread
92192e
	keeps processing connection.
92192e
	In that condition it should not decrease the refcnt.
92192e
	In case the operation is a persistent search, it decreases systematically
92192e
	the refcnt.
92192e
	So refcnt can become lower than the actual number of threads active on the connection.
92192e
92192e
	Most of the time it can create messages like
92192e
		Attempt to release connection that is not acquired
92192e
	In some rare case, if the a connection is out of the active list but a remaining thread
92192e
	tries to remove it again it can lead to a crash
92192e
92192e
Fix Description:
92192e
	The fix consist, when processing a PS, to decrease the refcnt at the condition
92192e
	the connection is not in turbo mode or in more_data.
92192e
92192e
https://pagure.io/389-ds-base/issue/49768
92192e
92192e
Reviewed by: Mark Reynolds
92192e
92192e
Platforms tested: F26
92192e
92192e
Flag Day: no
92192e
92192e
Doc impact: no
92192e
---
92192e
 ldap/servers/slapd/connection.c | 14 +++++++++++---
92192e
 1 file changed, 11 insertions(+), 3 deletions(-)
92192e
92192e
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
92192e
index c54e7c26c..1dbb49f06 100644
92192e
--- a/ldap/servers/slapd/connection.c
92192e
+++ b/ldap/servers/slapd/connection.c
92192e
@@ -1811,9 +1811,17 @@ connection_threadmain()
92192e
         slapi_counter_increment(ops_completed);
92192e
         /* If this op isn't a persistent search, remove it */
92192e
         if (op->o_flags & OP_FLAG_PS) {
92192e
-            PR_EnterMonitor(conn->c_mutex);
92192e
-            connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */
92192e
-            PR_ExitMonitor(conn->c_mutex);
92192e
+            /* Release the connection (i.e. decrease refcnt) at the condition
92192e
+             * this thread will not loop on it.
92192e
+             * If we are in turbo mode (dedicated to that connection) or
92192e
+             * more_data (continue reading buffered req) this thread
92192e
+             * continues to hold the connection
92192e
+             */
92192e
+            if (!thread_turbo_flag && !more_data) {
92192e
+                PR_EnterMonitor(conn->c_mutex);
92192e
+                connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */
92192e
+                PR_ExitMonitor(conn->c_mutex);
92192e
+            }
92192e
             /* ps_add makes a shallow copy of the pb - so we
92192e
                  * can't free it or init it here - just set operation to NULL.
92192e
                  * ps_send_results will call connection_remove_operation_ext to free it
92192e
-- 
92192e
2.17.1
92192e