Skip to content
Extraits de code Groupes Projets
Valider b20822f4 rédigé par Tom Barbette's avatar Tom Barbette
Parcourir les fichiers

RecordTimestamp: Enable the use of callbacks instead of marking packets

on-path
parent c7747342
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
#include <click/args.hh> #include <click/args.hh>
#include <click/error.hh> #include <click/error.hh>
#include <click/hashtable.hh>
#if HAVE_DPDK
#include "../elements/userlevel/todpdkdevice.hh"
#endif
CLICK_DECLS CLICK_DECLS
...@@ -32,13 +37,43 @@ RecordTimestamp::RecordTimestamp() : ...@@ -32,13 +37,43 @@ RecordTimestamp::RecordTimestamp() :
RecordTimestamp::~RecordTimestamp() { RecordTimestamp::~RecordTimestamp() {
} }
inline uint16_t
RecordTimestamp::calc_latency(uint16_t port __rte_unused, uint16_t qidx,
struct rte_mbuf **pkts, uint16_t nb_pkts, void *ptr)
{
RecordTimestamp* rt = ((RecordTimestamp*)ptr);
for (unsigned i = 0; i < nb_pkts; i++) {
unsigned char *data = rte_pktmbuf_mtod(pkts[i], unsigned char *);
uint64_t n = (*(reinterpret_cast<const uint64_t *>(data + rt->_offset)));
if (rt->_sample > 1) {
if (n % rt->_sample == 0)
n = n / rt->_sample;
else
continue;
}
//click_chatter("Record qidx%d %p{element} -> %d",qidx, rt, n);
rt->_timestamps[n] = TimestampT::now_steady();
}
return nb_pkts;
}
int RecordTimestamp::configure(Vector<String> &conf, ErrorHandler *errh) { int RecordTimestamp::configure(Vector<String> &conf, ErrorHandler *errh) {
uint32_t n = 0; uint32_t n = 0;
Element *e = NULL; Element *e = NULL;
#if HAVE_DPDK
ToDPDKDevice* _tx_dev;
int _tx_dev_id = 0;
#endif
if (Args(conf, this, errh) if (Args(conf, this, errh)
.read("COUNTER", e) .read("COUNTER", e)
.read("N", n) .read("N", n)
.read("OFFSET", _offset) .read("TXDEV", ElementCastArg("ToDPDKDevice"), _tx_dev)
.read("TXDEV_QID", _tx_dev_id)
.read_or_set("OFFSET", _offset, -1)
.read_or_set("DYNAMIC", _dynamic, false) .read_or_set("DYNAMIC", _dynamic, false)
.read_or_set("NET_ORDER", _net_order, false) .read_or_set("NET_ORDER", _net_order, false)
.read_or_set("SAMPLE", _sample, false) .read_or_set("SAMPLE", _sample, false)
...@@ -56,6 +91,26 @@ int RecordTimestamp::configure(Vector<String> &conf, ErrorHandler *errh) { ...@@ -56,6 +91,26 @@ int RecordTimestamp::configure(Vector<String> &conf, ErrorHandler *errh) {
if (_np) { if (_np) {
_net_order = _np->has_net_order(); _net_order = _np->has_net_order();
} }
#if HAVE_DPDK
if (_tx_dev) {
if (_dynamic || _offset < 0)
return errh->error("TXDEV is only compatible with OFFSET given and non-dynamic mode");
if (_net_order)
return errh->error("TXDEV is only compatible with non-net order");
_timestamps.resize(_timestamps.size() == 0? _timestamps.capacity():_timestamps.size() * 2, Timestamp::uninitialized_t());
DPDKDevice::all_initialized.post(new Router::FctFuture([this,_tx_dev,_tx_dev_id](ErrorHandler* errh) {
if (rte_eth_add_tx_callback(_tx_dev->port_id(), _tx_dev_id, calc_latency, this) == 0) {
return errh->error("Port %d/%d Callback could not be set %d: %s", _tx_dev->port_id(), _tx_dev_id, rte_errno, rte_strerror(rte_errno));
}
return 0;
},this));
} else
#endif
if (ninputs() != 1 or noutputs() !=1)
return errh->error("You need to pass either TXDEV or use the element in path.");
return 0; return 0;
} }
...@@ -71,8 +126,7 @@ RecordTimestamp::rmaction(Packet *p) { ...@@ -71,8 +126,7 @@ RecordTimestamp::rmaction(Packet *p) {
else else
return; return;
} }
assert(i < ULLONG_MAX); while (unlikely(i >= (unsigned)_timestamps.size())) {
while (i >= (unsigned)_timestamps.size()) {
if (!_dynamic && i >= (unsigned)_timestamps.capacity()) { if (!_dynamic && i >= (unsigned)_timestamps.capacity()) {
click_chatter("Fatal error: DYNAMIC is not set and record timestamp reserved capacity is too small. Use N to augment the capacity."); click_chatter("Fatal error: DYNAMIC is not set and record timestamp reserved capacity is too small. Use N to augment the capacity.");
assert(false); assert(false);
...@@ -99,6 +153,8 @@ void RecordTimestamp::push_batch(int, PacketBatch *batch) { ...@@ -99,6 +153,8 @@ void RecordTimestamp::push_batch(int, PacketBatch *batch) {
} }
#endif #endif
CLICK_ENDDECLS CLICK_ENDDECLS
ELEMENT_REQUIRES(userlevel) ELEMENT_REQUIRES(userlevel)
EXPORT_ELEMENT(RecordTimestamp) EXPORT_ELEMENT(RecordTimestamp)
...@@ -5,10 +5,15 @@ ...@@ -5,10 +5,15 @@
#include <click/batchelement.hh> #include <click/batchelement.hh>
#include <click/timestamp.hh> #include <click/timestamp.hh>
#include <click/tsctimestamp.hh> #include <click/tsctimestamp.hh>
#include <click/hashtable.hh>
#include "numberpacket.hh" #include "numberpacket.hh"
CLICK_DECLS CLICK_DECLS
#if HAVE_DPDK
struct rte_mbuf;
class ToDPDKDevice;
#endif
class NumberPacket; class NumberPacket;
#define TimestampT TSCTimestamp #define TimestampT TSCTimestamp
#define TimestampUnread TSCTimestamp(1) #define TimestampUnread TSCTimestamp(1)
...@@ -70,7 +75,7 @@ public: ...@@ -70,7 +75,7 @@ public:
~RecordTimestamp() CLICK_COLD; ~RecordTimestamp() CLICK_COLD;
const char *class_name() const override { return "RecordTimestamp"; } const char *class_name() const override { return "RecordTimestamp"; }
const char *port_count() const override { return PORTS_1_1; } const char *port_count() const override { return "0-1/="; }
const char *processing() const override { return PUSH; } const char *processing() const override { return PUSH; }
const char *flow_code() const override { return "x/x"; } const char *flow_code() const override { return "x/x"; }
...@@ -93,11 +98,16 @@ public: ...@@ -93,11 +98,16 @@ public:
NumberPacket::read_number_of_packet(p, offset, net_order); NumberPacket::read_number_of_packet(p, offset, net_order);
} }
#if HAVE_DPDK
inline static uint16_t calc_latency(uint16_t port, uint16_t qidx,
struct rte_mbuf **pkts, uint16_t nb_pkts, void *ptr);
#endif
private: private:
int _offset; int _offset;
bool _dynamic; bool _dynamic;
bool _net_order; bool _net_order;
uint32_t _sample; uint32_t _sample;
ToDPDKDevice* _tx_dev;
Vector<TimestampT> _timestamps; Vector<TimestampT> _timestamps;
NumberPacket *_np; NumberPacket *_np;
}; };
......
...@@ -149,6 +149,10 @@ public: ...@@ -149,6 +149,10 @@ public:
#endif #endif
void push(int port, Packet *p); void push(int port, Packet *p);
uint16_t port_id() {
return _dev->port_id;
}
protected: protected:
inline void warn_congestion(); inline void warn_congestion();
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <click/args.hh> #include <click/args.hh>
#include <click/etheraddress.hh> #include <click/etheraddress.hh>
#include <click/timer.hh> #include <click/timer.hh>
#include <click/router.hh>
#if RTE_VERSION < RTE_VERSION_NUM(19,8,0,0) #if RTE_VERSION < RTE_VERSION_NUM(19,8,0,0)
#define rte_ipv4_hdr ipv4_hdr #define rte_ipv4_hdr ipv4_hdr
...@@ -232,6 +233,8 @@ public: ...@@ -232,6 +233,8 @@ public:
static int get_port_numa_node(portid_t port_id); static int get_port_numa_node(portid_t port_id);
static Router::ChildrenFuture all_initialized;
#if HAVE_FLOW_API #if HAVE_FLOW_API
int set_mode( int set_mode(
String mode, int num_pools, Vector<int> vf_vlan, String mode, int num_pools, Vector<int> vf_vlan,
......
...@@ -1283,7 +1283,7 @@ int DPDKDevice::initialize(ErrorHandler *errh) ...@@ -1283,7 +1283,7 @@ int DPDKDevice::initialize(ErrorHandler *errh)
} }
} }
#endif #endif
all_initialized.solve_initialize(errh);
return 0; return 0;
} }
...@@ -1579,6 +1579,7 @@ HashTable<portid_t, DPDKDevice*> DPDKDevice::_devs; ...@@ -1579,6 +1579,7 @@ HashTable<portid_t, DPDKDevice*> DPDKDevice::_devs;
struct rte_mempool** DPDKDevice::_pktmbuf_pools = 0; struct rte_mempool** DPDKDevice::_pktmbuf_pools = 0;
unsigned DPDKDevice::_nr_pktmbuf_pools = 0; unsigned DPDKDevice::_nr_pktmbuf_pools = 0;
bool DPDKDevice::no_more_buffer_msg_printed = false; bool DPDKDevice::no_more_buffer_msg_printed = false;
Router::ChildrenFuture DPDKDevice::all_initialized;
CLICK_ENDDECLS CLICK_ENDDECLS
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter