ike-sa-manager: Improve scalability of half-open IKE_SA checking

This patch is based on one by Christoph Gouault.

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
well when the number of segments increases, as the method is called for
each new negotiation.

Instead, lets maintain a global atomic counter.

This optimization allows the use of big values for charon.ikesa_table_size
and charon.ikesa_table_segments.
This commit is contained in:
Tobias Brunner 2014-04-11 16:23:39 +02:00
parent 0f603d425d
commit a68454bd68
1 changed files with 8 additions and 7 deletions

View File

@ -353,6 +353,11 @@ struct private_ike_sa_manager_t {
*/ */
shareable_segment_t *half_open_segments; shareable_segment_t *half_open_segments;
/**
* Total number of half-open IKE_SAs.
*/
refcount_t half_open_count;
/** /**
* Hash table with connected_peers_t objects. * Hash table with connected_peers_t objects.
*/ */
@ -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_table[row] = item;
} }
this->half_open_segments[segment].count++; this->half_open_segments[segment].count++;
ref_get(&this->half_open_count);
lock->unlock(lock); lock->unlock(lock);
} }
@ -803,6 +809,7 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
free(item); free(item);
} }
this->half_open_segments[segment].count--; this->half_open_segments[segment].count--;
ignore_result(ref_put(&this->half_open_count));
break; break;
} }
prev = item; prev = item;
@ -1962,13 +1969,7 @@ METHOD(ike_sa_manager_t, get_half_open_count, u_int,
} }
else else
{ {
for (segment = 0; segment < this->segment_count; segment++) count = (u_int)ref_cur(&this->half_open_count);
{
lock = this->half_open_segments[segment].lock;
lock->read_lock(lock);
count += this->half_open_segments[segment].count;
lock->unlock(lock);
}
} }
return count; return count;
} }