Skip to content

Commit 5adbd36

Browse files
committed
dpdk-ring - read timestamp from hw metadata if available
1 parent 1b4361d commit 5adbd36

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

input/dpdk-ring.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,30 @@ void DpdkRingReader::init(const char* params)
141141
} else {
142142
is_reader_ready = true;
143143
}
144+
getDynfieldInfo();
144145
}
145146

146147
struct timeval DpdkRingReader::getTimestamp(rte_mbuf* mbuf)
147148
{
148149
struct timeval tv;
150+
if (m_nfbMetadataEnabled) {
151+
uint64_t nfb_dynflag_mask = (1ULL << m_nfbMetadataDynfieldInfo.dynflag_bit_index);
152+
153+
if (mbuf->ol_flags & nfb_dynflag_mask) {
154+
const uint16_t ct_hdr_offset = *RTE_MBUF_DYNFIELD(
155+
mbuf, m_nfbMetadataDynfieldInfo.dynfield_byte_index, uint16_t*
156+
);
157+
158+
struct NfbMetadata *ct_hdr = (struct NfbMetadata*)
159+
((uint8_t*)mbuf->buf_addr + ct_hdr_offset);
160+
161+
tv.tv_sec = ct_hdr->timestamp.timestamp_s;
162+
tv.tv_usec = ct_hdr->timestamp.timestamp_ns / 1000;
163+
return tv;
164+
}
165+
}
166+
167+
// fallback to software timestamp
149168
auto now = std::chrono::system_clock::now();
150169
auto now_t = std::chrono::system_clock::to_time_t(now);
151170

@@ -210,4 +229,31 @@ void DpdkRingReader::configure_telemetry_dirs(
210229
register_file(queues_dir, "input-stats", statsOps);
211230
}
212231

232+
void DpdkRingReader::getDynfieldInfo()
233+
{
234+
struct rte_mbuf_dynfield dynfield_params;
235+
struct rte_mbuf_dynflag dynflag_param;
236+
int ret;
237+
bool dynflag_found = false;
238+
bool dynfield_found = false;
239+
240+
rte_errno = 0;
241+
ret = rte_mbuf_dynflag_lookup("rte_net_nfb_dynflag_header_vld", &dynflag_param);
242+
if (ret >= 0) {
243+
m_nfbMetadataDynfieldInfo.dynflag_bit_index = ret;
244+
dynflag_found = true;
245+
}
246+
247+
rte_errno = 0;
248+
ret = rte_mbuf_dynfield_lookup("rte_net_nfb_dynfield_header_offset", &dynfield_params);
249+
if (ret >= 0) {
250+
m_nfbMetadataDynfieldInfo.dynfield_byte_index = ret;
251+
dynfield_found = true;
252+
}
253+
254+
if (dynflag_found && dynfield_found) {
255+
m_nfbMetadataEnabled = true;
256+
}
257+
}
258+
213259
} // namespace ipxp

input/dpdk-ring.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,24 @@ class DpdkRingReader : public InputPlugin {
134134
uint64_t receivedBytes;
135135
};
136136

137+
struct NfbMetadataDynfieldInfo {
138+
int dynflag_bit_index;
139+
int dynfield_byte_index;
140+
};
141+
142+
struct NfbTimestamp {
143+
uint32_t timestamp_ns;
144+
uint32_t timestamp_s;
145+
} __rte_packed;
146+
147+
struct NfbMetadata {
148+
NfbTimestamp timestamp;
149+
uint16_t matched;
150+
uint32_t hash;
151+
} __rte_packed;
152+
137153
telemetry::Content get_queue_telemetry();
154+
void getDynfieldInfo();
138155

139156
std::vector<rte_mbuf *> mbufs_;
140157
std::uint16_t pkts_read_;
@@ -145,6 +162,8 @@ class DpdkRingReader : public InputPlugin {
145162
rte_ring *m_ring;
146163
bool is_reader_ready = false;
147164
DpdkRingStats m_stats = {};
165+
bool m_nfbMetadataEnabled = false;
166+
NfbMetadataDynfieldInfo m_nfbMetadataDynfieldInfo = {};
148167
};
149168
} // namespace ipxp
150169

0 commit comments

Comments
 (0)