[strongSwan-dev] [PATCH] charon: improve scalability of half_open ike sa counting

Christophe Gouault christophe.gouault at 6wind.com
Tue Apr 8 17:09:10 CEST 2014


Currently, to count the total number of half_open ike SAs, get_half_open_count
sums up the count of each segment in the SA hash table (acquiring a lock for
each segment). This procedure does not scale when the number of segments
increases. This count is performed at each new negotiation.

Instead, let us maintain a global atomic counter.

This optimization enables to use big numbers for charon.ikesa_table_size and
charon.ikesa_table_segments.

perf top before optimization:

36.10%  libcrypto.so.1.0.0             [.] 0xbc93c
20.47%  libpthread-2.13.so             [.] pthread_rwlock_unlock
16.27%  libpthread-2.13.so             [.] pthread_rwlock_rdlock
 2.61%  libcharon.so.0.0.0             [.] get_half_open_count

perf top after optimization:

60.97%  libcrypto.so.1.0.0        [.] 0xbc8ba
 5.24%  libpthread-2.13.so        [.] pthread_rwlock_rdlock

Signed-off-by: Christophe Gouault <christophe.gouault at 6wind.com>
---
 src/libcharon/sa/ike_sa_manager.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index f2f81cf..cc21b78 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -349,6 +349,11 @@ struct private_ike_sa_manager_t {
 	table_item_t **half_open_table;
 
 	/**
+	 * The total number of "half-open" SAs.
+	 */
+	refcount_t half_open_count;
+
+	/**
 	  * Segments of the "half-open" hash table.
 	 */
 	shareable_segment_t *half_open_segments;
@@ -764,6 +769,7 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry)
 		this->half_open_table[row] = item;
 	}
 	this->half_open_segments[segment].count++;
+	ref_get(&this->half_open_count);
 	lock->unlock(lock);
 }
 
@@ -803,6 +809,7 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
 				free(item);
 			}
 			this->half_open_segments[segment].count--;
+			ref_put(&this->half_open_count);
 			break;
 		}
 		prev = item;
@@ -1962,13 +1969,7 @@ METHOD(ike_sa_manager_t, get_half_open_count, u_int,
 	}
 	else
 	{
-		for (segment = 0; segment < this->segment_count; segment++)
-		{
-			lock = this->half_open_segments[segment].lock;
-			lock->read_lock(lock);
-			count += this->half_open_segments[segment].count;
-			lock->unlock(lock);
-		}
+		count = this->half_open_count;
 	}
 	return count;
 }
@@ -2181,6 +2182,8 @@ ike_sa_manager_t *ike_sa_manager_create()
 		this->half_open_segments[i].count = 0;
 	}
 
+	this->half_open_count = 0;
+
 	/* also for the hash table used for duplicate tests */
 	this->connected_peers_table = calloc(this->table_size, sizeof(table_item_t*));
 	this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
-- 
1.7.10.4



More information about the Dev mailing list