BUG/MEDIUM: pattern: don't trim pools under lock in pat_ref_purge_range()

There's a subtle issue that results from pat_ref_purge_range() trying
to release memory. Since commit 0d93a8186 ("MINOR: pools: work around
possibly slow malloc_trim() during gc") that was backported to 2.3,
trim_all_pools() now protects itself against concurrent malloc() and
free() by isolating itself. The problem is that pat_ref_purge_range()
must be called under a lock, which is precisely what's done in
cli_io_handler_clear_map(). Thus during a clearing of a map, if
another thread tries to access or update an entry in the same map, it
will wait for the ref->lock to be released, and trim_all_pools() will
wait for all threads to be harmless, thus causing a deadlock. Note
that disabling memory trimming cannot work around the problem here
because it's tested only under isolation.

The solution here consists in moving the call to trim_all_pools() to
the caller, out of the lock.

This must be backported as far as 2.4.

(cherry picked from commit 58185669d8a0891948caaa7b357d78775b0cecb3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 88b1ec97ec33a760538c0bd6c9f3fecbef46f44e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 4233e2b6fec47f0238e84b45fe90747a4463d4ae)
[cf: trim_all_pools() is not used here but malloc_trim(). So the malloc_trim()
     is moved instead]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 7ed6888a5a82486f1d71c49d19d231fad837eafe)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/map.c b/src/map.c
index f482b77..41afbe8 100644
--- a/src/map.c
+++ b/src/map.c
@@ -997,6 +997,12 @@
 		si_rx_endp_more(si);
 		return 0;
 	}
+
+#if defined(HA_HAVE_MALLOC_TRIM)
+	if (finished) {
+		malloc_trim(0);
+	}
+#endif
 	return 1;
 }
 
diff --git a/src/pattern.c b/src/pattern.c
index 417841b..9e4a4ac 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -2072,12 +2072,6 @@
 	list_for_each_entry(expr, &ref->pat, list)
 		HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
 
-#if defined(HA_HAVE_MALLOC_TRIM)
-	if (done) {
-		malloc_trim(0);
-	}
-#endif
-
 	return done;
 }