ike-sa-manager: Improve scalability of IKE_SA count checking

Much like in commit a68454b, we now use a global atomic counter to keep
track of the number of IKE_SAs currently registered. This should improve
scalability for a large number of segments even more.

Signed-off-by: Thomas Egerer <[email protected]>
This commit is contained in:
Thomas Egerer
2017-05-19 15:28:46 +02:00
committed by Tobias Brunner
parent 59e6e93323
commit 746e88406c
+10 -19
View File
@@ -276,9 +276,6 @@ typedef struct segment_t segment_t;
struct segment_t { struct segment_t {
/** mutex to access a segment exclusively */ /** mutex to access a segment exclusively */
mutex_t *mutex; mutex_t *mutex;
/** the number of entries in this segment */
u_int count;
}; };
typedef struct shareable_segment_t shareable_segment_t; typedef struct shareable_segment_t shareable_segment_t;
@@ -370,6 +367,11 @@ struct private_ike_sa_manager_t {
*/ */
refcount_t half_open_count_responder; refcount_t half_open_count_responder;
/**
* Total number of IKE_SAs registered with IKE_SA manager.
*/
refcount_t total_sa_count;
/** /**
* Hash table with connected_peers_t objects. * Hash table with connected_peers_t objects.
*/ */
@@ -601,7 +603,7 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry)
item->next = current; item->next = current;
} }
this->ike_sa_table[row] = item; this->ike_sa_table[row] = item;
this->segments[segment].count++; ref_get(&this->total_sa_count);
return segment; return segment;
} }
@@ -612,10 +614,9 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry)
static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry)
{ {
table_item_t *item, *prev = NULL; table_item_t *item, *prev = NULL;
u_int row, segment; u_int row;
row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask;
segment = row & this->segment_mask;
item = this->ike_sa_table[row]; item = this->ike_sa_table[row];
while (item) while (item)
{ {
@@ -629,7 +630,7 @@ static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry)
{ {
this->ike_sa_table[row] = item->next; this->ike_sa_table[row] = item->next;
} }
this->segments[segment].count--; ignore_result(ref_put(&this->total_sa_count));
free(item); free(item);
break; break;
} }
@@ -648,7 +649,7 @@ static void remove_entry_at(private_enumerator_t *this)
{ {
table_item_t *current = this->current; table_item_t *current = this->current;
this->manager->segments[this->segment].count--; ignore_result(ref_put(&this->manager->total_sa_count));
this->current = this->prev; this->current = this->prev;
if (this->prev) if (this->prev)
@@ -2034,17 +2035,7 @@ METHOD(ike_sa_manager_t, has_contact, bool,
METHOD(ike_sa_manager_t, get_count, u_int, METHOD(ike_sa_manager_t, get_count, u_int,
private_ike_sa_manager_t *this) private_ike_sa_manager_t *this)
{ {
u_int segment, count = 0; return (u_int)ref_cur(&this->total_sa_count);
mutex_t *mutex;
for (segment = 0; segment < this->segment_count; segment++)
{
mutex = this->segments[segment & this->segment_mask].mutex;
mutex->lock(mutex);
count += this->segments[segment].count;
mutex->unlock(mutex);
}
return count;
} }
METHOD(ike_sa_manager_t, get_half_open_count, u_int, METHOD(ike_sa_manager_t, get_half_open_count, u_int,