pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/31811 )
Change subject: bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id() ......................................................................
bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id()
Refactor the double loop to check a code path matching the sccp_instance once instead of doing so for every subscr_conn.
If for instance let's say we have 1000 concurrent calls in progress, which means we have 1000 subscr_conn, which means we at least do the extra check regarding SMLC vs MSC 1000 times (at least, xN times if N conn_id already used are already found). That overhead happens every time a new subscr_conn is created (which in a BSC with already 1000 concurrent calls can potentially happen quite frequently).
Change-Id: Ic32b1eeb201fc51110e1ee130110824845f81e82 --- M src/osmo-bsc/bsc_sccp.c 1 file changed, 50 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/11/31811/1
diff --git a/src/osmo-bsc/bsc_sccp.c b/src/osmo-bsc/bsc_sccp.c index 79a6617..fea3907 100644 --- a/src/osmo-bsc/bsc_sccp.c +++ b/src/osmo-bsc/bsc_sccp.c @@ -45,6 +45,32 @@ /* This looks really suboptimal, but in most cases the static next_id should indicate exactly the next unused * conn_id, and we only iterate all conns once to make super sure that it is not already in use. */
+ /* SCCP towards SMLC: */ + if (bsc_gsmnet->smlc->sccp == sccp) { + for (i = 0; i < 0x00FFFFFE; i++) { + struct gsm_subscriber_connection *conn; + uint32_t conn_id = next_id; + bool conn_id_already_used = false; + + next_id = (next_id + 1) & 0x00FFFFFF; + if (next_id == 0x00FFFFFF) + next_id = 0; + + llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { + if (conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE && + conn->lcs.lb.conn_id == conn_id) { + conn_id_already_used = true; + break; + } + } + + if (!conn_id_already_used) + return conn_id; + } + return 0xFFFFFFFF; + } + + /* SCCP towards MSC: */ for (i = 0; i < 0x00FFFFFE; i++) { struct gsm_subscriber_connection *conn; uint32_t conn_id = next_id; @@ -55,19 +81,10 @@ next_id = 0;
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { - if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp) { - if (conn_id == conn->sccp.conn_id) { - conn_id_already_used = true; - break; - } - } - - if (bsc_gsmnet->smlc->sccp == sccp - && conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE) { - if (conn_id == conn->lcs.lb.conn_id) { - conn_id_already_used = true; - break; - } + if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp && + conn->sccp.conn_id == conn_id) { + conn_id_already_used = true; + break; } }