[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