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

Reply via email to