Skip to content

Commit

Permalink
[load_balancer] Improve probing by sending the probs outside locking
Browse files Browse the repository at this point in the history
Collect the data under locking, move the OPTIONs probing outside the locking, to be sure that any potential blocking on SIP level sending is not leading to lock starvation.
Simialar to 4c7a7a8 (drouting)
Related to #2438
  • Loading branch information
bogdan-iancu committed Sep 16, 2022
1 parent 8139e27 commit 994e55c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 8 deletions.
54 changes: 50 additions & 4 deletions modules/load_balancer/lb_prober.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ extern struct tm_binds lb_tmb;
void set_dst_state_from_rplcode( int id, int code);


typedef struct lb_param_prob_callback {
unsigned int id;
}lb_param_prob_callback_t;


static void lb_probing_callback( struct cell *t, int type,
struct tmcb_params *ps )
Expand All @@ -45,7 +49,7 @@ static void lb_probing_callback( struct cell *t, int type,
LM_CRIT("BUG - reply to a LB probe with no ID (code=%d)\n", ps->code);
return;
}
id = (int)(long)(*ps->param);
id = ((lb_param_prob_callback_t*)*ps->param)->id;

set_dst_state_from_rplcode( id, ps->code);

Expand All @@ -56,11 +60,25 @@ static void lb_probing_callback( struct cell *t, int type,

void lb_do_probing(struct lb_data *data)
{
struct gw_prob_pack {
/* IMPORTANT, this member must be the first, as we use its pointer
* to free the whole structure here */
lb_param_prob_callback_t params;

str uri;

struct gw_prob_pack *next;
};
struct lb_dst *dst;
struct gw_prob_pack *pack, *pack_last, *pack_head;

if ( !lb_cluster_shtag_is_active() )
return;

pack_last = pack_head = NULL;

lock_start_read( ref_lock );

/* go through all destinations */
for( dst = data->dsts ; dst ; dst=dst->next ) {
/* dst requires probing ? */
Expand All @@ -73,13 +91,41 @@ void lb_do_probing(struct lb_data *data)
)
continue;

if (lb_tmb.t_request( &lb_probe_method, &dst->uri, &dst->uri,
/* build its pack, so we can build and send the prob later */
pack = shm_malloc(sizeof(struct gw_prob_pack)+dst->uri.len);
if( pack==0 ) {
LM_ERR("no more shm memory!\n");
/* send whatever probs we have so far */
break;
}

pack->uri.s = (char*)(pack+1);
memcpy(pack->uri.s, dst->uri.s, dst->uri.len);
pack->uri.len = dst->uri.len;

pack->params.id = dst->id;

if (pack_head==NULL) {
pack_head = pack_last = pack;
} else {
pack_last->next = pack;
pack_last = pack;
}

}

lock_stop_read( ref_lock );

/* now send all the probs, outside the lock */
for( pack = pack_head ; pack ; pack=pack->next ) {

if (lb_tmb.t_request( &lb_probe_method, &pack->uri, &pack->uri,
&lb_probe_from, NULL, NULL, NULL, lb_probing_callback,
(void*)(long)dst->id, NULL) < 0) {
(void*)(long)pack, osips_shm_free) < 0) {
LM_ERR("probing failed\n");
shm_free(pack);
}


}

}
5 changes: 1 addition & 4 deletions modules/load_balancer/load_balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,14 +771,11 @@ void set_dst_state_from_rplcode( int id, int code)

static void lb_prob_handler(unsigned int ticks, void* param)
{
lock_start_read( ref_lock );

/* do probing */
lb_do_probing(*curr_data);

lock_stop_read( ref_lock );
}


static void lb_update_max_loads(unsigned int ticks, void *param)
{
struct lb_dst *dst;
Expand Down

0 comments on commit 994e55c

Please sign in to comment.