Skip to content

Commit ac5ea51

Browse files
Pavel Harbanaucodebot
authored andcommitted
ofh: change logging of lates in the transmitter queue
1 parent 66c2388 commit ac5ea51

10 files changed

+126
-76
lines changed

include/srsran/ofh/ethernet/ethernet_frame_pool.h

Lines changed: 82 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ class frame_buffer_array
108108
};
109109

110110
public:
111+
struct used_buffer {
112+
frame_buffer* buffer;
113+
ofh::slot_symbol_point timestamp;
114+
};
115+
111116
// Constructor receives number of buffers stored/read at a time, reserves storage for all eAxCs.
112117
frame_buffer_array(unsigned nof_buffers_to_return, unsigned buffer_size, unsigned nof_antennas) :
113118
increment_quant(nof_buffers_to_return),
@@ -140,14 +145,14 @@ class frame_buffer_array
140145

141146
// Stores actually used buffers in a list of buffers ready for sending.
142147
// Unused buffers state is changed to 'free'.
143-
void push_buffers(span<frame_buffer> prepared_buffers)
148+
void push_buffers(span<frame_buffer> prepared_buffers, ofh::slot_symbol_point symbol_point)
144149
{
145150
for (auto& buffer : prepared_buffers) {
146151
if (buffer.empty()) {
147152
buffer.status = frame_buffer::frame_buffer_status::free;
148153
} else {
149154
buffer.status = frame_buffer::frame_buffer_status::used;
150-
used_buffers.push_back(&buffer);
155+
used_buffers.push_back({&buffer, symbol_point});
151156
}
152157
}
153158
}
@@ -176,14 +181,16 @@ class frame_buffer_array
176181
span<const frame_buffer*> find_buffers_ready_for_sending()
177182
{
178183
aux_array.clear();
179-
for (auto& buffer : used_buffers) {
180-
buffer->status = frame_buffer::frame_buffer_status::marked_to_send;
181-
aux_array.push_back(buffer);
184+
for (auto& used_buf : used_buffers) {
185+
used_buf.buffer->status = frame_buffer::frame_buffer_status::marked_to_send;
186+
aux_array.push_back(used_buf.buffer);
182187
}
183188
used_buffers.clear();
184189
return aux_array;
185190
}
186191

192+
span<const used_buffer> get_prepared_buffers() const { return used_buffers; }
193+
187194
private:
188195
// Number of buffers accessed at a time.
189196
unsigned increment_quant;
@@ -192,7 +199,7 @@ class frame_buffer_array
192199
// Data buffers.
193200
storage_array_type buffers_array;
194201
// Used buffers are added to this list.
195-
static_vector<frame_buffer*, 128> used_buffers;
202+
static_vector<used_buffer, 128> used_buffers;
196203
// Auxiliary array used as a list of ready-to-send buffers returned to a reader.
197204
std::vector<const frame_buffer*> aux_array;
198205
// Keeps track of the current write position.
@@ -202,8 +209,11 @@ class frame_buffer_array
202209
/// Pool of Ethernet frames pre-allocated for each slot symbol.
203210
class eth_frame_pool
204211
{
212+
/// Number of slots the pool can accommodate.
213+
static constexpr size_t NUM_SLOTS = 20L;
214+
205215
/// Maximum number of entries contained by the pool, one entry per OFDM symbol, sized to accommodate 20 slots.
206-
static constexpr size_t NUM_ENTRIES = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP * 20L;
216+
static constexpr size_t NUM_ENTRIES = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP * NUM_SLOTS;
207217

208218
/// Number of symbols in an interval for which an auxiliary vector is pre-allocated to store buffer pointers.
209219
static constexpr size_t NUM_INTERVAL_SYMBOL = 14;
@@ -259,10 +269,10 @@ class eth_frame_pool
259269
}
260270

261271
/// Push span of ready buffers to the array associated with the given OFH type.
262-
void push_buffers(const ofh_pool_message_type& context, span<frame_buffer> prepared_buffers)
272+
void push_buffers(const frame_pool_context& context, span<frame_buffer> prepared_buffers)
263273
{
264-
frame_buffer_array& entry_buf = get_ofh_type_buffers(context.type, context.direction);
265-
entry_buf.push_buffers(prepared_buffers);
274+
frame_buffer_array& entry_buf = get_ofh_type_buffers(context.type.type, context.type.direction);
275+
entry_buf.push_buffers(prepared_buffers, context.symbol_point);
266276
}
267277

268278
void clear_buffers(const ofh_pool_message_type& context)
@@ -277,6 +287,12 @@ class eth_frame_pool
277287
entry_buf.reset_buffers();
278288
}
279289

290+
span<const frame_buffer_array::used_buffer> get_prepared_buffers(const ofh_pool_message_type& context) const
291+
{
292+
const frame_buffer_array& entry_buf = get_ofh_type_buffers(context.type, context.direction);
293+
return entry_buf.get_prepared_buffers();
294+
}
295+
280296
/// Returns a view over a next stored frame buffer for a given OFH type.
281297
span<const frame_buffer*> read_buffers(const ofh_pool_message_type& context)
282298
{
@@ -320,7 +336,7 @@ class eth_frame_pool
320336
pool_entry& p_entry = get_pool_entry(context.symbol_point.get_slot(), context.symbol_point.get_symbol_index());
321337
// Lock and update the pool entry.
322338
std::lock_guard<std::mutex> lock(mutex);
323-
p_entry.push_buffers(context.type, prepared_buffers);
339+
p_entry.push_buffers(context, prepared_buffers);
324340
}
325341

326342
/// Returns data buffers from the pool to a reader thread given a specific symbol context.
@@ -385,29 +401,76 @@ class eth_frame_pool
385401
}
386402
}
387403

388-
/// Clear stored buffers associated with the given slot.
389-
void clear_slot(slot_point slot_point)
404+
/// Clears stored buffers associated with the given slot and logs the messages that could not be sent.
405+
void clear_downlink_slot(slot_point slot_point, srslog::basic_logger& logger)
390406
{
391407
// Lock before changing the pool entries.
392408
std::lock_guard<std::mutex> lock(mutex);
393409

394410
pool_entry& cp_entry = get_pool_entry(slot_point, 0);
395411
// Clear buffers with DL Control-Plane messages.
396412
ofh_pool_message_type msg_type{ofh::message_type::control_plane, ofh::data_direction::downlink};
397-
cp_entry.reset_buffers(msg_type);
398-
// Clear buffers with UL Control-Plane messages.
399-
msg_type.direction = ofh::data_direction::uplink;
400-
cp_entry.reset_buffers(msg_type);
413+
414+
auto dl_cp_buffers = cp_entry.get_prepared_buffers(msg_type);
415+
for (const auto& used_buf : dl_cp_buffers) {
416+
if (used_buf.timestamp.get_slot() == slot_point) {
417+
continue;
418+
}
419+
logger.warning("Detected '{}' late downlink C-Plane messages in the transmitter queue for slot '{}'",
420+
dl_cp_buffers.size(),
421+
used_buf.timestamp.get_slot());
422+
cp_entry.reset_buffers(msg_type);
423+
break;
424+
}
401425

402426
// Clear buffers with User-Plane messages.
403427
msg_type.type = ofh::message_type::user_plane;
404428
msg_type.direction = ofh::data_direction::downlink;
405-
for (unsigned symbol = 0; symbol != 14; ++symbol) {
429+
for (unsigned symbol = 0; symbol != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP; ++symbol) {
406430
pool_entry& up_entry = get_pool_entry(slot_point, symbol);
407-
up_entry.reset_buffers(msg_type);
431+
432+
auto dl_up_buffers = up_entry.get_prepared_buffers(msg_type);
433+
for (const auto& used_buf : dl_up_buffers) {
434+
if (used_buf.timestamp.get_slot() == slot_point) {
435+
continue;
436+
}
437+
logger.warning(
438+
"Detected '{}' late downlink U-Plane messages in the transmitter queue for slot '{}', symbol '{}'",
439+
dl_up_buffers.size(),
440+
used_buf.timestamp.get_slot(),
441+
used_buf.timestamp.get_symbol_index());
442+
up_entry.reset_buffers(msg_type);
443+
break;
444+
}
408445
}
409446
}
410447

448+
/// Clears stored uplink C-Plane buffers associated with the given slot and logs the messages that could not be sent.
449+
void clear_uplink_slot(slot_point slot_point, srslog::basic_logger& logger)
450+
{
451+
// Lock before changing the pool entries.
452+
std::lock_guard<std::mutex> lock(mutex);
453+
454+
pool_entry& cp_entry = get_pool_entry(slot_point, 0);
455+
// Clear buffers with UL Control-Plane messages.
456+
ofh_pool_message_type msg_type{ofh::message_type::control_plane, ofh::data_direction::uplink};
457+
458+
auto ul_cp_buffers = cp_entry.get_prepared_buffers(msg_type);
459+
for (const auto& used_buf : ul_cp_buffers) {
460+
if (used_buf.timestamp.get_slot() == slot_point) {
461+
continue;
462+
}
463+
logger.warning("Detected '{}' late uplink C-Plane messages in the transmitter queue for slot '{}'",
464+
ul_cp_buffers.size(),
465+
used_buf.timestamp.get_slot());
466+
cp_entry.reset_buffers(msg_type);
467+
break;
468+
}
469+
}
470+
471+
/// Returns number of slots the pool can accommodate.
472+
size_t pool_size_in_slots() const { return NUM_SLOTS; }
473+
411474
private:
412475
/// Buffer pool.
413476
std::vector<pool_entry> pool;

lib/ofh/transmitter/ofh_downlink_handler_broadcast_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void downlink_handler_broadcast_impl::handle_dl_data(const resource_grid_context
5959
const resource_grid_reader& grid)
6060
{
6161
// Clear any stale buffers associated with the context slot.
62-
frame_pool.clear_slot(context.slot);
62+
frame_pool.clear_downlink_slot(context.slot, logger);
6363

6464
if (window_checker.is_late(context.slot)) {
6565
err_notifier.get().on_late_downlink_message({context.slot, sector_id});

lib/ofh/transmitter/ofh_downlink_handler_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void downlink_handler_impl::handle_dl_data(const resource_grid_context& context,
6262
grid.get_nof_ports());
6363

6464
// Clear any stale buffers associated with the context slot.
65-
frame_pool.clear_slot(context.slot);
65+
frame_pool.clear_downlink_slot(context.slot, logger);
6666

6767
if (window_checker.is_late(context.slot)) {
6868
err_notifier.get().on_late_downlink_message({context.slot, sector_id});

lib/ofh/transmitter/ofh_message_transmitter_impl.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,33 +76,4 @@ void message_transmitter_impl::on_new_symbol(slot_symbol_point symbol_point)
7676
interval.start = symbol_point + timing_params.sym_up_dl_end;
7777
interval.end = symbol_point + timing_params.sym_up_dl_start;
7878
transmit_enqueued_messages(interval);
79-
80-
// Log the late messages when the transmission window closes.
81-
log_late_messages_on_tx_window_close(symbol_point);
82-
}
83-
84-
void message_transmitter_impl::log_late_messages_on_tx_window_close(slot_symbol_point symbol_point)
85-
{
86-
log_late_messages(symbol_point + timing_params.sym_cp_dl_end, message_type::control_plane, data_direction::downlink);
87-
log_late_messages(symbol_point + timing_params.sym_cp_ul_end, message_type::control_plane, data_direction::uplink);
88-
log_late_messages(symbol_point + timing_params.sym_up_dl_end, message_type::user_plane, data_direction::downlink);
89-
}
90-
91-
void message_transmitter_impl::log_late_messages(slot_symbol_point late_point,
92-
message_type type,
93-
data_direction direction)
94-
{
95-
const ether::frame_pool_context context{{type, direction}, late_point};
96-
auto frame_buffers = pool.read_frame_buffers(context);
97-
98-
if (!frame_buffers.empty()) {
99-
logger.warning("Detected '{}' late Ethernet frames in the transmitter queue for slot '{}', symbol '{}', type '{}', "
100-
"direction '{}'",
101-
frame_buffers.size(),
102-
late_point.get_slot(),
103-
late_point.get_symbol_index(),
104-
(type == message_type::control_plane) ? "control" : "user",
105-
(direction == data_direction::downlink) ? "downlink" : "uplink");
106-
pool.clear_sent_frame_buffers(context);
107-
}
10879
}

lib/ofh/transmitter/ofh_message_transmitter_impl.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,6 @@ class message_transmitter_impl : public ota_symbol_boundary_notifier
7979
private:
8080
/// Transmits enqueued messages for the given interval of slot symbol points.
8181
void transmit_enqueued_messages(const ether::frame_pool_interval& interval);
82-
83-
/// Logs the messages that could not be sent due the transmission window closed.
84-
void log_late_messages_on_tx_window_close(slot_symbol_point symbol_point);
85-
86-
/// Logs the late messages for the given late slot symbol point, message type and direction.
87-
void log_late_messages(slot_symbol_point late_point, message_type type, data_direction direction);
8882
};
8983

9084
} // namespace ofh

lib/ofh/transmitter/ofh_transmitter_factories.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,11 @@ create_uplink_request_handler(const transmitter_config&
161161
config.cp = tx_config.cp;
162162

163163
uplink_request_handler_impl_dependencies dependencies;
164-
dependencies.logger = &logger;
165-
dependencies.ul_slot_repo = ul_slot_context_repo;
166-
dependencies.ul_prach_repo = prach_context_repo;
167-
dependencies.data_flow = create_data_flow_cplane_sched(tx_config, logger, frame_pool, ul_cp_context_repo);
164+
dependencies.logger = &logger;
165+
dependencies.ul_slot_repo = ul_slot_context_repo;
166+
dependencies.ul_prach_repo = prach_context_repo;
167+
dependencies.frame_pool_ptr = frame_pool;
168+
dependencies.data_flow = create_data_flow_cplane_sched(tx_config, logger, frame_pool, ul_cp_context_repo);
168169

169170
return std::make_unique<uplink_request_handler_impl>(config, std::move(dependencies));
170171
}

lib/ofh/transmitter/ofh_uplink_request_handler_impl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,22 @@ uplink_request_handler_impl::uplink_request_handler_impl(const uplink_request_ha
4848
ul_prach_repo_ptr(dependencies.ul_prach_repo),
4949
ul_slot_repo(*ul_slot_repo_ptr),
5050
ul_prach_repo(*ul_prach_repo_ptr),
51-
data_flow(std::move(dependencies.data_flow))
51+
data_flow(std::move(dependencies.data_flow)),
52+
frame_pool_ptr(dependencies.frame_pool_ptr),
53+
frame_pool(*frame_pool_ptr)
5254
{
5355
srsran_assert(ul_slot_repo_ptr, "Invalid uplink repository");
5456
srsran_assert(ul_prach_repo_ptr, "Invalid PRACH repository");
5557
srsran_assert(data_flow, "Invalid data flow");
58+
srsran_assert(frame_pool_ptr, "Invalid frame pool");
5659
}
5760

5861
void uplink_request_handler_impl::handle_prach_occasion(const prach_buffer_context& context, prach_buffer& buffer)
5962
{
6063
logger.debug("Registering PRACH context entry for slot '{}' and sector#{}", context.slot, context.sector);
6164

65+
frame_pool.clear_uplink_slot(context.slot, logger);
66+
6267
// Sampling rate defining the \f$T_s = 1/(\Delta f_{ref} \times N_{f,ref})\f$ parameter, see 3GPP TS38.211,
6368
// clause 4.1.
6469
// Open Fronthaul parameters timeOffset and cpLength are expressed in multiple of \f$T_s\f$ units.
@@ -136,6 +141,8 @@ void uplink_request_handler_impl::handle_new_uplink_slot(const resource_grid_con
136141
{
137142
logger.debug("Registering UL context entry for slot '{}' and sector#{}", context.slot, context.sector);
138143

144+
frame_pool.clear_uplink_slot(context.slot, logger);
145+
139146
// Store the context in the repository.
140147
ul_slot_repo.add(context, grid);
141148

lib/ofh/transmitter/ofh_uplink_request_handler_impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "../support/uplink_context_repository.h"
1515
#include "ofh_data_flow_cplane_scheduling_commands.h"
1616
#include "srsran/adt/optional.h"
17+
#include "srsran/ofh/ethernet/ethernet_frame_pool.h"
1718
#include "srsran/ofh/transmitter/ofh_uplink_request_handler.h"
1819
#include "srsran/ran/tdd/tdd_ul_dl_config.h"
1920

@@ -42,6 +43,8 @@ struct uplink_request_handler_impl_dependencies {
4243
std::shared_ptr<uplink_context_repository> ul_slot_repo;
4344
/// Uplink PRACH context repository.
4445
std::shared_ptr<prach_context_repository> ul_prach_repo;
46+
/// Ethernet frame pool.
47+
std::shared_ptr<ether::eth_frame_pool> frame_pool_ptr;
4548
/// Data flow for Control-Plane scheduling commands.
4649
std::unique_ptr<data_flow_cplane_scheduling_commands> data_flow;
4750
};
@@ -71,6 +74,8 @@ class uplink_request_handler_impl : public uplink_request_handler
7174
uplink_context_repository& ul_slot_repo;
7275
prach_context_repository& ul_prach_repo;
7376
std::unique_ptr<data_flow_cplane_scheduling_commands> data_flow;
77+
std::shared_ptr<ether::eth_frame_pool> frame_pool_ptr;
78+
ether::eth_frame_pool& frame_pool;
7479
};
7580

7681
} // namespace ofh

tests/unittests/ofh/ethernet/ethernet_frame_pool_test.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,11 @@ TEST_P(EthFramePoolFixture, pool_should_have_enough_space)
457457

458458
TEST_P(EthFramePoolFixture, clearing_full_pool_should_allow_adding_more_data)
459459
{
460+
srslog::basic_logger& logger = srslog::fetch_basic_logger("OFH_TEST", false);
461+
logger.set_level(srslog::basic_levels::debug);
462+
463+
size_t pool_size_slots = pool.pool_size_in_slots();
464+
460465
slot_point slot(to_numerology_value(scs), 0);
461466
for (unsigned slot_count = 0; slot_count < TEST_NUM_SLOTS; ++slot_count) {
462467
for (unsigned symbol = 0; symbol < nof_symbols; ++symbol) {
@@ -478,8 +483,9 @@ TEST_P(EthFramePoolFixture, clearing_full_pool_should_allow_adding_more_data)
478483
}
479484
pool.push_frame_buffers(ctx, frame_buffers);
480485
}
481-
// Clear full slot in the pool and try to get buffers again.
482-
pool.clear_slot(slot);
486+
// Increase slot by pool size, clear stale buffers in the pool and try to get buffers again.
487+
auto wrapped_slot = slot + pool_size_slots;
488+
pool.clear_downlink_slot(wrapped_slot, logger);
483489
for (unsigned i = 0; i != nof_requested_buffers; ++i) {
484490
span<frame_buffer> frame_buffers = pool.get_frame_buffers(ctx);
485491
ASSERT_TRUE(!frame_buffers.empty()) << "Non-empty span of buffers expected";
@@ -506,7 +512,7 @@ TEST_P(EthFramePoolFixture, clearing_full_pool_should_allow_adding_more_data)
506512
pool.push_frame_buffers(ctx, frame_buffers);
507513
}
508514
// Clear full slot in the pool and try to get buffers again.
509-
pool.clear_slot(slot);
515+
pool.clear_uplink_slot(wrapped_slot, logger);
510516
for (unsigned i = 0; i != nof_requested_buffers; ++i) {
511517
span<frame_buffer> frame_buffers = pool.get_frame_buffers(ctx);
512518
ASSERT_TRUE(!frame_buffers.empty()) << "Non-empty span of buffers expected";

0 commit comments

Comments
 (0)