aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc')
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c5
-rw-r--r--src/osmo-bsc/bsc_subscriber.c115
-rw-r--r--src/osmo-bsc/bsc_vty.c8
-rw-r--r--src/osmo-bsc/gsm_08_08.c11
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c5
-rw-r--r--src/osmo-bsc/paging.c5
6 files changed, 93 insertions, 56 deletions
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index 95bbb12bf..de73a2a8b 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -823,7 +823,8 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
OSMO_ASSERT(data);
mi_imsi = data;
if (!conn->bsub)
- conn->bsub = bsc_subscr_find_or_create_by_imsi(conn->network->bsc_subscribers, mi_imsi->imsi);
+ conn->bsub = bsc_subscr_find_or_create_by_imsi(conn->network->bsc_subscribers, mi_imsi->imsi,
+ BSUB_USE_CONN);
else {
/* we already have a bsc_subscr associated; maybe that subscriber has no IMSI yet? */
if (!conn->bsub->imsi[0])
@@ -855,7 +856,7 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
if (conn->bsub) {
LOGPFSML(fi, LOGL_DEBUG, "Putting bsc_subscr\n");
- bsc_subscr_put(conn->bsub);
+ bsc_subscr_put(conn->bsub, BSUB_USE_CONN);
conn->bsub = NULL;
}
diff --git a/src/osmo-bsc/bsc_subscriber.c b/src/osmo-bsc/bsc_subscriber.c
index 9ddfcaa43..79d0c8512 100644
--- a/src/osmo-bsc/bsc_subscriber.c
+++ b/src/osmo-bsc/bsc_subscriber.c
@@ -32,6 +32,38 @@
#include <osmocom/bsc/bsc_subscriber.h>
#include <osmocom/bsc/debug.h>
+static void bsc_subscr_free(struct bsc_subscr *bsub);
+
+static int bsub_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
+{
+ struct bsc_subscr *bsub = e->use_count->talloc_object;
+ int32_t total;
+ int level;
+
+ if (!e->use)
+ return -EINVAL;
+
+ total = osmo_use_count_total(&bsub->use_count);
+
+ if (total == 0
+ || (total == 1 && old_use_count == 0 && e->count == 1))
+ level = LOGL_INFO;
+ else
+ level = LOGL_DEBUG;
+
+ LOGPSRC(DREF, level, file, line, "BSC subscr %s: %s %s: now used by %s\n",
+ bsc_subscr_name(bsub),
+ (e->count - old_use_count) > 0? "+" : "-", e->use,
+ osmo_use_count_to_str_c(OTC_SELECT, &bsub->use_count));
+
+ if (e->count < 0)
+ return -ERANGE;
+
+ if (total == 0)
+ bsc_subscr_free(bsub);
+ return 0;
+}
+
static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
{
struct bsc_subscr *bsub;
@@ -40,13 +72,20 @@ static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
if (!bsub)
return NULL;
+ bsub->tmsi = GSM_RESERVED_TMSI;
+ bsub->use_count = (struct osmo_use_count){
+ .talloc_object = bsub,
+ .use_cb = bsub_use_cb,
+ };
+
llist_add_tail(&bsub->entry, list);
return bsub;
}
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
- const char *imsi)
+ const char *imsi,
+ const char *use_token)
{
struct bsc_subscr *bsub;
@@ -54,14 +93,17 @@ struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
return NULL;
llist_for_each_entry(bsub, list, entry) {
- if (!strcmp(bsub->imsi, imsi))
- return bsc_subscr_get(bsub);
+ if (!strcmp(bsub->imsi, imsi)) {
+ bsc_subscr_get(bsub, use_token);
+ return bsub;
+ }
}
return NULL;
}
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
- uint32_t tmsi)
+ uint32_t tmsi,
+ const char *use_token)
{
struct bsc_subscr *bsub;
@@ -69,21 +111,24 @@ struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
return NULL;
llist_for_each_entry(bsub, list, entry) {
- if (bsub->tmsi == tmsi)
- return bsc_subscr_get(bsub);
+ if (bsub->tmsi == tmsi) {
+ bsc_subscr_get(bsub, use_token);
+ return bsub;
+ }
}
return NULL;
}
-struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi)
+struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
+ const char *use_token)
{
if (!mi)
return NULL;
switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- return bsc_subscr_find_by_imsi(list, mi->imsi);
+ return bsc_subscr_find_by_imsi(list, mi->imsi, use_token);
case GSM_MI_TYPE_TMSI:
- return bsc_subscr_find_by_tmsi(list, mi->tmsi);
+ return bsc_subscr_find_by_tmsi(list, mi->tmsi, use_token);
default:
return NULL;
}
@@ -97,42 +142,47 @@ void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi)
}
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
- const char *imsi)
+ const char *imsi,
+ const char *use_token)
{
struct bsc_subscr *bsub;
- bsub = bsc_subscr_find_by_imsi(list, imsi);
+ bsub = bsc_subscr_find_by_imsi(list, imsi, use_token);
if (bsub)
return bsub;
bsub = bsc_subscr_alloc(list);
if (!bsub)
return NULL;
bsc_subscr_set_imsi(bsub, imsi);
- return bsc_subscr_get(bsub);
+ bsc_subscr_get(bsub, use_token);
+ return bsub;
}
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
- uint32_t tmsi)
+ uint32_t tmsi,
+ const char *use_token)
{
struct bsc_subscr *bsub;
- bsub = bsc_subscr_find_by_tmsi(list, tmsi);
+ bsub = bsc_subscr_find_by_tmsi(list, tmsi, use_token);
if (bsub)
return bsub;
bsub = bsc_subscr_alloc(list);
if (!bsub)
return NULL;
bsub->tmsi = tmsi;
- return bsc_subscr_get(bsub);
+ bsc_subscr_get(bsub, use_token);
+ return bsub;
}
-struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi)
+struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
+ const char *use_token)
{
if (!mi)
return NULL;
switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- return bsc_subscr_find_or_create_by_imsi(list, mi->imsi);
+ return bsc_subscr_find_or_create_by_imsi(list, mi->imsi, use_token);
case GSM_MI_TYPE_TMSI:
- return bsc_subscr_find_or_create_by_tmsi(list, mi->tmsi);
+ return bsc_subscr_find_or_create_by_tmsi(list, mi->tmsi, use_token);
default:
return NULL;
}
@@ -170,29 +220,7 @@ static void bsc_subscr_free(struct bsc_subscr *bsub)
talloc_free(bsub);
}
-struct bsc_subscr *_bsc_subscr_get(struct bsc_subscr *bsub,
- const char *file, int line)
-{
- OSMO_ASSERT(bsub->use_count < INT_MAX);
- bsub->use_count++;
- LOGPSRC(DREF, LOGL_DEBUG, file, line,
- "BSC subscr %s usage increases to: %d\n",
- bsc_subscr_name(bsub), bsub->use_count);
- return bsub;
-}
-
-struct bsc_subscr *_bsc_subscr_put(struct bsc_subscr *bsub,
- const char *file, int line)
-{
- bsub->use_count--;
- LOGPSRC(DREF, bsub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR,
- file, line,
- "BSC subscr %s usage decreases to: %d\n",
- bsc_subscr_name(bsub), bsub->use_count);
- if (bsub->use_count <= 0)
- bsc_subscr_free(bsub);
- return NULL;
-}
+#define BSUB_USE_LOG_FILTER "log_filter"
void log_set_filter_bsc_subscr(struct log_target *target,
struct bsc_subscr *bsc_subscr)
@@ -201,13 +229,14 @@ void log_set_filter_bsc_subscr(struct log_target *target,
/* free the old data */
if (*fsub) {
- bsc_subscr_put(*fsub);
+ bsc_subscr_put(*fsub, BSUB_USE_LOG_FILTER);
*fsub = NULL;
}
if (bsc_subscr) {
target->filter_map |= (1 << LOG_FLT_BSC_SUBSCR);
- *fsub = bsc_subscr_get(bsc_subscr);
+ *fsub = bsc_subscr;
+ bsc_subscr_get(*fsub, BSUB_USE_LOG_FILTER);
} else
target->filter_map &= ~(1 << LOG_FLT_BSC_SUBSCR);
}
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 7be6aebd3..cd7d0e001 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1415,7 +1415,7 @@ static void bsc_subscr_dump_vty(struct vty *vty, struct bsc_subscr *bsub)
if (bsub->tmsi != GSM_RESERVED_TMSI)
vty_out(vty, " TMSI: 0x%08x%s", bsub->tmsi,
VTY_NEWLINE);
- vty_out(vty, " Use count: %d%s", bsub->use_count, VTY_NEWLINE);
+ vty_out(vty, " Use count: %s%s", osmo_use_count_to_str_c(OTC_SELECT, &bsub->use_count), VTY_NEWLINE);
}
static void meas_rep_dump_uni_vty(struct vty *vty,
@@ -6350,7 +6350,7 @@ DEFUN(logging_fltr_imsi,
if (!tgt)
return CMD_WARNING;
- bsc_subscr = bsc_subscr_find_or_create_by_imsi(bsc_gsmnet->bsc_subscribers, imsi);
+ bsc_subscr = bsc_subscr_find_or_create_by_imsi(bsc_gsmnet->bsc_subscribers, imsi, __func__);
if (!bsc_subscr) {
vty_out(vty, "%% failed to enable logging for subscriber with IMSI(%s)%s",
@@ -6360,14 +6360,14 @@ DEFUN(logging_fltr_imsi,
log_set_filter_bsc_subscr(tgt, bsc_subscr);
/* log_set_filter has grabbed its own reference */
- bsc_subscr_put(bsc_subscr);
+ bsc_subscr_put(bsc_subscr, __func__);
return CMD_SUCCESS;
}
static void dump_one_sub(struct vty *vty, struct bsc_subscr *bsub)
{
- vty_out(vty, " %15s %08x %d%s", bsub->imsi, bsub->tmsi, bsub->use_count,
+ vty_out(vty, " %15s %08x %s%s", bsub->imsi, bsub->tmsi, osmo_use_count_to_str_c(OTC_SELECT, &bsub->use_count),
VTY_NEWLINE);
}
diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c
index e5a27748f..01d9d0ee3 100644
--- a/src/osmo-bsc/gsm_08_08.c
+++ b/src/osmo-bsc/gsm_08_08.c
@@ -402,7 +402,7 @@ int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_chan
* See e.g. BSC_Tests.TC_chan_rel_rll_rel_ind: "dt := * f_est_dchan('23'O, 23, '00010203040506'O);"
*/
} else {
- bsub = bsc_subscr_find_or_create_by_mi(bsc_gsmnet->bsc_subscribers, &mi);
+ bsub = bsc_subscr_find_or_create_by_mi(bsc_gsmnet->bsc_subscribers, &mi, __func__);
}
/* allocate a new connection */
@@ -412,8 +412,13 @@ int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_chan
goto early_fail;
}
if (bsub) {
- /* pass bsub use count to conn */
- conn->bsub = bsub;
+ /* We got the conn either from new allocation, or by searching for it by bsub. So: */
+ OSMO_ASSERT((!conn->bsub) || (conn->bsub == bsub));
+ if (!conn->bsub) {
+ conn->bsub = bsub;
+ bsc_subscr_get(conn->bsub, BSUB_USE_CONN);
+ }
+ bsc_subscr_put(bsub, __func__);
}
gscon_change_primary_lchan(conn, lchan);
gscon_update_id(conn);
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 023929cb5..124f61353 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -347,7 +347,8 @@ int bsc_paging_start(struct bsc_paging_params *params)
rate_ctr_inc(&bsc_gsmnet->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED]);
if (!params->bsub) {
- params->bsub = bsc_subscr_find_or_create_by_imsi(bsc_gsmnet->bsc_subscribers, params->imsi.imsi);
+ params->bsub = bsc_subscr_find_or_create_by_imsi(bsc_gsmnet->bsc_subscribers, params->imsi.imsi,
+ BSUB_USE_PAGING_START);
if (!params->bsub) {
LOG_PAGING(params, DMSC, LOGL_ERROR, "Paging request failed: Could not allocate subscriber\n");
return -EINVAL;
@@ -394,7 +395,7 @@ int bsc_paging_start(struct bsc_paging_params *params)
break;
}
- bsc_subscr_put(params->bsub);
+ bsc_subscr_put(params->bsub, BSUB_USE_PAGING_START);
log_set_context(LOG_CTX_BSC_SUBSCR, NULL);
return 0;
}
diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c
index 54a5fd7cd..a4a5a1e68 100644
--- a/src/osmo-bsc/paging.c
+++ b/src/osmo-bsc/paging.c
@@ -67,7 +67,7 @@ static void paging_remove_request(struct gsm_bts_paging_state *paging_bts,
{
osmo_timer_del(&to_be_deleted->T3113);
llist_del(&to_be_deleted->entry);
- bsc_subscr_put(to_be_deleted->bsub);
+ bsc_subscr_put(to_be_deleted->bsub, BSUB_USE_PAGING_REQUEST);
talloc_free(to_be_deleted);
}
@@ -343,7 +343,8 @@ static int _paging_request(const struct bsc_paging_params *params, struct gsm_bt
req = talloc_zero(tall_paging_ctx, struct gsm_paging_request);
OSMO_ASSERT(req);
req->reason = params->reason;
- req->bsub = bsc_subscr_get(params->bsub);
+ req->bsub = params->bsub;
+ bsc_subscr_get(req->bsub, BSUB_USE_PAGING_REQUEST);
req->bts = bts;
req->chan_type = params->chan_needed;
req->msc = params->msc;