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 <[email protected]> --- 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 _______________________________________________ Dev mailing list [email protected] https://lists.strongswan.org/mailman/listinfo/dev
