aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CommonLibs/osmo_signal.h7
-rw-r--r--CommonLibs/trx_rate_ctr.cpp53
-rw-r--r--CommonLibs/trx_rate_ctr.h1
-rw-r--r--CommonLibs/trx_vty.c5
-rw-r--r--Transceiver52M/Transceiver.cpp11
-rw-r--r--Transceiver52M/Transceiver.h3
6 files changed, 73 insertions, 7 deletions
diff --git a/CommonLibs/osmo_signal.h b/CommonLibs/osmo_signal.h
index ceb7d6f..de17b1d 100644
--- a/CommonLibs/osmo_signal.h
+++ b/CommonLibs/osmo_signal.h
@@ -43,6 +43,7 @@ enum SS_DEVICE {
(struct device_counters). Must be sent with PTHREAD_CANCEL_DISABLE
to avoid deadlocks in case osmo-trx process is asked to exit. */
S_DEVICE_COUNTER_CHANGE,
+ S_TRX_COUNTER_CHANGE, /* same, but for Transceiver class */
};
/* signal cb for signal <SS_DEVICE,S_DEVICE_COUNTER_CHANGE> */
@@ -55,3 +56,9 @@ struct device_counters {
unsigned int tx_dropped_events;
unsigned int tx_dropped_samples;
};
+
+/* signal cb for signal <SS_DEVICE,S_TRX_COUNTER_CHANGE> */
+struct trx_counters {
+ size_t chan;
+ unsigned int tx_stale_bursts; /* Amount of Tx bursts dropped to to arriving too late from TRXD */
+};
diff --git a/CommonLibs/trx_rate_ctr.cpp b/CommonLibs/trx_rate_ctr.cpp
index e941cf0..76aff7d 100644
--- a/CommonLibs/trx_rate_ctr.cpp
+++ b/CommonLibs/trx_rate_ctr.cpp
@@ -75,9 +75,12 @@ static void *trx_rate_ctr_ctx;
static struct rate_ctr_group** rate_ctrs;
static struct device_counters* dev_ctrs_pending;
+static struct trx_counters* trx_ctrs_pending;
static size_t chan_len;
static struct osmo_fd dev_rate_ctr_timerfd;
+static struct osmo_fd trx_rate_ctr_timerfd;
static Mutex dev_rate_ctr_mutex;
+static Mutex trx_rate_ctr_mutex;
struct osmo_timer_list threshold_timer;
static LLIST_HEAD(threshold_list);
@@ -99,6 +102,7 @@ const struct value_string trx_chan_ctr_names[] = {
{ TRX_CTR_DEV_RX_DROP_SMPL, "rx_drop_samples" },
{ TRX_CTR_DEV_TX_DROP_EV, "tx_drop_events" },
{ TRX_CTR_DEV_TX_DROP_SMPL, "tx_drop_samples" },
+ { TRX_CTR_TRX_TX_STALE_BURSTS, "tx_stale_bursts" },
{ 0, NULL }
};
@@ -108,7 +112,8 @@ static const struct rate_ctr_desc trx_chan_ctr_desc[] = {
[TRX_CTR_DEV_RX_DROP_EV] = { "device:rx_drop_events", "Number of times Rx samples were dropped by HW" },
[TRX_CTR_DEV_RX_DROP_SMPL] = { "device:rx_drop_samples", "Number of Rx samples dropped by HW" },
[TRX_CTR_DEV_TX_DROP_EV] = { "device:tx_drop_events", "Number of times Tx samples were dropped by HW" },
- [TRX_CTR_DEV_TX_DROP_SMPL] = { "device:tx_drop_samples", "Number of Tx samples dropped by HW" }
+ [TRX_CTR_DEV_TX_DROP_SMPL] = { "device:tx_drop_samples", "Number of Tx samples dropped by HW" },
+ [TRX_CTR_TRX_TX_STALE_BURSTS] = { "trx:tx_stale_bursts", "Number of Tx burts dropped by TRX due to arriving too late" },
};
static const struct rate_ctr_group_desc trx_chan_ctr_group_desc = {
@@ -150,11 +155,32 @@ static int dev_rate_ctr_timerfd_cb(struct osmo_fd *ofd, unsigned int what) {
return 0;
}
+static int trx_rate_ctr_timerfd_cb(struct osmo_fd *ofd, unsigned int what) {
+ size_t chan;
+ struct rate_ctr *ctr;
+ LOGC(DMAIN, NOTICE) << "Main thread is updating Transceiver counters";
+ dev_rate_ctr_mutex.lock();
+ for (chan = 0; chan < chan_len; chan++) {
+ if (trx_ctrs_pending[chan].chan == PENDING_CHAN_NONE)
+ continue;
+ LOGCHAN(chan, DMAIN, INFO) << "rate_ctr update";
+ ctr = &rate_ctrs[chan]->ctr[TRX_CTR_TRX_TX_STALE_BURSTS];
+ rate_ctr_add(ctr, trx_ctrs_pending[chan].tx_stale_bursts - ctr->current);
+ /* Mark as done */
+ trx_ctrs_pending[chan].chan = PENDING_CHAN_NONE;
+ }
+ if (osmo_timerfd_disable(&trx_rate_ctr_timerfd) < 0)
+ LOGC(DMAIN, ERROR) << "Failed to disable timerfd";
+ trx_rate_ctr_mutex.unlock();
+ return 0;
+}
+
/* Callback function to be called every time we receive a signal from DEVICE */
static int device_sig_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
- struct device_counters *ctr;
+ struct device_counters *dev_ctr;
+ struct trx_counters *trx_ctr;
/* Delay sched around 20 ms, in case we receive several calls from several
* channels batched */
struct timespec next_sched = {.tv_sec = 0, .tv_nsec = 20*1000*1000};
@@ -163,15 +189,25 @@ static int device_sig_cb(unsigned int subsys, unsigned int signal,
switch (signal) {
case S_DEVICE_COUNTER_CHANGE:
- ctr = (struct device_counters *)signal_data;
- LOGCHAN(ctr->chan, DMAIN, NOTICE) << "Received counter change from radioDevice";
+ dev_ctr = (struct device_counters *)signal_data;
+ LOGCHAN(dev_ctr->chan, DMAIN, NOTICE) << "Received counter change from radioDevice";
dev_rate_ctr_mutex.lock();
- dev_ctrs_pending[ctr->chan] = *ctr;
+ dev_ctrs_pending[dev_ctr->chan] = *dev_ctr;
if (osmo_timerfd_schedule(&dev_rate_ctr_timerfd, &next_sched, &intv_sched) < 0) {
LOGC(DMAIN, ERROR) << "Failed to schedule timerfd: " << errno << " = "<< strerror(errno);
}
dev_rate_ctr_mutex.unlock();
break;
+ case S_TRX_COUNTER_CHANGE:
+ trx_ctr = (struct trx_counters *)signal_data;
+ LOGCHAN(trx_ctr->chan, DMAIN, NOTICE) << "Received counter change from Transceiver";
+ trx_rate_ctr_mutex.lock();
+ trx_ctrs_pending[trx_ctr->chan] = *trx_ctr;
+ if (osmo_timerfd_schedule(&trx_rate_ctr_timerfd, &next_sched, &intv_sched) < 0) {
+ LOGC(DMAIN, ERROR) << "Failed to schedule timerfd: " << errno << " = "<< strerror(errno);
+ }
+ trx_rate_ctr_mutex.unlock();
+ break;
default:
break;
}
@@ -273,10 +309,12 @@ void trx_rate_ctr_init(void *ctx, struct trx_ctx* trx_ctx)
trx_rate_ctr_ctx = ctx;
chan_len = trx_ctx->cfg.num_chans;
dev_ctrs_pending = (struct device_counters*) talloc_zero_size(ctx, chan_len * sizeof(struct device_counters));
+ trx_ctrs_pending = (struct trx_counters*) talloc_zero_size(ctx, chan_len * sizeof(struct trx_counters));
rate_ctrs = (struct rate_ctr_group**) talloc_zero_size(ctx, chan_len * sizeof(struct rate_ctr_group*));
for (i = 0; i < chan_len; i++) {
dev_ctrs_pending[i].chan = PENDING_CHAN_NONE;
+ trx_ctrs_pending[i].chan = PENDING_CHAN_NONE;
rate_ctrs[i] = rate_ctr_group_alloc(ctx, &trx_chan_ctr_group_desc, i);
if (!rate_ctrs[i]) {
LOGCHAN(i, DMAIN, ERROR) << "Failed to allocate rate ctr";
@@ -288,6 +326,11 @@ void trx_rate_ctr_init(void *ctx, struct trx_ctx* trx_ctx)
LOGC(DMAIN, ERROR) << "Failed to setup timerfd";
exit(1);
}
+ trx_rate_ctr_timerfd.fd = -1;
+ if (osmo_timerfd_setup(&trx_rate_ctr_timerfd, trx_rate_ctr_timerfd_cb, NULL) < 0) {
+ LOGC(DMAIN, ERROR) << "Failed to setup timerfd";
+ exit(1);
+ }
osmo_signal_register_handler(SS_DEVICE, device_sig_cb, NULL);
/* Now set up threshold checks */
diff --git a/CommonLibs/trx_rate_ctr.h b/CommonLibs/trx_rate_ctr.h
index e122f99..588ac2f 100644
--- a/CommonLibs/trx_rate_ctr.h
+++ b/CommonLibs/trx_rate_ctr.h
@@ -10,6 +10,7 @@ enum TrxCtr {
TRX_CTR_DEV_RX_DROP_SMPL,
TRX_CTR_DEV_TX_DROP_EV,
TRX_CTR_DEV_TX_DROP_SMPL,
+ TRX_CTR_TRX_TX_STALE_BURSTS,
};
struct ctr_threshold {
diff --git a/CommonLibs/trx_vty.c b/CommonLibs/trx_vty.c
index 3f875f5..f085d09 100644
--- a/CommonLibs/trx_vty.c
+++ b/CommonLibs/trx_vty.c
@@ -390,7 +390,7 @@ static int vty_intv_name_2_id(const char* str) {
return -1;
}
-#define THRESHOLD_ARGS "(rx_overruns|tx_underruns|rx_drop_events|rx_drop_samples|tx_drop_events|tx_drop_samples)"
+#define THRESHOLD_ARGS "(rx_overruns|tx_underruns|rx_drop_events|rx_drop_samples|tx_drop_events|tx_drop_samples|tx_stale_bursts)"
#define THRESHOLD_STR_VAL(s) "Set threshold value for rate_ctr device:" OSMO_STRINGIFY_VAL(s) "\n"
#define THRESHOLD_STRS \
THRESHOLD_STR_VAL(rx_overruns) \
@@ -398,7 +398,8 @@ static int vty_intv_name_2_id(const char* str) {
THRESHOLD_STR_VAL(rx_drop_events) \
THRESHOLD_STR_VAL(rx_drop_samples) \
THRESHOLD_STR_VAL(tx_drop_events) \
- THRESHOLD_STR_VAL(tx_drop_samples)
+ THRESHOLD_STR_VAL(tx_drop_samples) \
+ THRESHOLD_STR_VAL(tx_stale_bursts)
#define INTV_ARGS "(per-second|per-minute|per-hour|per-day)"
#define INTV_STR_VAL(s) "Threshold value sampled " OSMO_STRINGIFY_VAL(s) "\n"
#define INTV_STRS \
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 7a81b7b..941b761 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -420,18 +420,29 @@ void Transceiver::pushRadioVector(GSM::Time &nowTime)
std::vector<signalVector *> bursts(mChans);
std::vector<bool> zeros(mChans);
std::vector<bool> filler(mChans, true);
+ bool stale_bursts_changed;
for (size_t i = 0; i < mChans; i ++) {
state = &mStates[i];
+ stale_bursts_changed = false;
while ((burst = mTxPriorityQueues[i].getStaleBurst(nowTime))) {
LOGCHAN(i, DTRXDDL, NOTICE) << "dumping STALE burst in TRX->SDR interface ("
<< burst->getTime() <<" vs " << nowTime << "), retrans=" << state->mRetrans;
+ state->ctrs.tx_stale_bursts++;
+ stale_bursts_changed = true;
if (state->mRetrans)
updateFillerTable(i, burst);
delete burst;
}
+ if (stale_bursts_changed) {
+ thread_enable_cancel(false);
+ state->ctrs.chan = i;
+ osmo_signal_dispatch(SS_DEVICE, S_TRX_COUNTER_CHANGE, &state->ctrs);
+ thread_enable_cancel(true);
+ }
+
TN = nowTime.TN();
modFN = nowTime.FN() % state->fillerModulus[TN];
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 6e0d157..7ce5fa2 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -83,6 +83,9 @@ struct TransceiverState {
/* Shadowed downlink attenuation */
int mPower;
+
+ /* counters */
+ struct trx_counters ctrs;
};
/** The Transceiver class, responsible for physical layer of basestation */