-
Notifications
You must be signed in to change notification settings - Fork 82
/
todpdkdevice.hh
194 lines (133 loc) · 5.41 KB
/
todpdkdevice.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef CLICK_TODPDKDEVICE_USERLEVEL_HH
#define CLICK_TODPDKDEVICE_USERLEVEL_HH
#include <click/config.h>
#include <click/batchelement.hh>
#include <click/sync.hh>
#include <click/dpdkdevice.hh>
#include "queuedevice.hh"
CLICK_DECLS
/*
=title ToDPDKDevice
=c
ToDPDKDevice(PORT [, QUEUE, N_QUEUES, I<keywords> IQUEUE, BLOCKING, etc.])
=s netdevices
sends packets to network device using Intel's DPDK (user-level)
=d
Sends packets to a network device with DPDK port identifier PORT. As DPDK does
not support polling, this element only supports PUSH. It will build a batch of
packets inside an internal queue (limited to IQUEUE packets) until it reaches
BURST packets, and then send the batch to DPDK. If the batch is not ready after
TIMEOUT ms, it will flush the batch of packets even if it doesn't cointain
BURST packets.
Arguments:
=over 8
=item PORT
Integer or PCI address. Port identifier of the device, or a PCI address in the
format fffff:ff:ff.f
=item QUEUE
Integer. A specific hardware queue to use. Default is 0.
=item N_QUEUES
Integer. Number of hardware queues to use. -1 or default is to use as many
queues as threads which can end up in this element.
=item IQUEUE
Integer. Size of the internal queue, i.e. number of packets that we can buffer
before pushing them to the DPDK framework. If IQUEUE is bigger than BURST,
some packets could be buffered in the internal queue when the output ring is
full. Defaults to 1024.
=item BLOCKING
Boolean. If true, when there is no more space in the output device ring, and
the IQUEUE is full, we'll block until some packet could be sent. If false the
packet will be dropped. Defaults to true.
=item BURST
Integer. Number of packets to batch before sending them out. A bigger BURST
leads to more latency, but a better throughput. The default value of 32 is
recommended as it is what DPDK will do under the hood. Prefer to set the
TIMEOUT parameter to 0 if the throughput is low as it will maintain
performance.
=item TIMEOUT
Integer. Set a timeout to flush the internal queue. It is useful under low
throughput as it could take a long time before reaching BURST packet in the
internal queue. The timeout is expressed in milliseconds. Setting the timer to
0 is not a bad idea as it will schedule after the source element (such as a
FromDPDKDevice) will have finished its burst, or all incoming packets. This
would therefore ensure that a flush is done right after all packets have been
processed by the Click pipeline. Setting a negative value disable the timer,
this is generally acceptable if the thoughput of this element rarely drops
below 32000 pps (~50 Mbps with maximal size packets) with a BURST of 32, as the
internal queue will wait on average 1 ms before containing 32 packets. Defaults
to 0 (immediate flush). The timeout will be disabled (-1) if BURST is 1, as the
packets will never wait in the internal queue.
=item NDESC
Integer. Number of descriptors per ring. The default is 1024.
=item ALLOW_NONEXISTENT
Boolean. Do not fail if the PORT do not existent. If it's the case the task
will never run and this element will behave like Idle.
=back
This element is only available at user level, when compiled with DPDK support.
=e
... -> ToDPDKDevice(2, QUEUE 0, BLOCKING true)
=h count read-only
Returns the number of packets sent by the device.
=h dropped read-only
Returns the number of packets dropped by the device.
=h reset_counts write-only
Resets n_send and n_dropped counts to zero.
=a DPDKInfo, FromDPDKDevice */
class ToDPDKDevice : public TXQueueDevice {
public:
ToDPDKDevice() CLICK_COLD;
~ToDPDKDevice() CLICK_COLD;
const char *class_name() const override { return "ToDPDKDevice"; }
const char *port_count() const override { return PORTS_1_0; }
const char *processing() const override { return PUSH; }
int configure_phase() const override {
return CONFIGURE_PHASE_PRIVILEGED;
}
bool can_live_reconfigure() const { return false; }
int configure(Vector<String> &, ErrorHandler *) override CLICK_COLD;
int initialize(ErrorHandler *) override CLICK_COLD;
void cleanup(CleanupStage stage) override CLICK_COLD;
static String statistics_handler(Element *e, void * thunk) CLICK_COLD;
void add_handlers() CLICK_COLD;
enum {
h_opackets,h_obytes,h_oerrors
};
#if HAVE_IQUEUE
void run_timer(Timer *);
#endif
#if HAVE_BATCH
void push_batch(int port, PacketBatch *head);
#endif
void push(int port, Packet *p);
uint16_t port_id() {
return _dev->port_id;
}
protected:
inline void warn_congestion();
inline void enqueue(rte_mbuf* &q, rte_mbuf* mbuf, const Packet* p);
#if HAVE_IQUEUE
inline void set_flush_timer(DPDKDevice::TXInternalQueue &iqueue);
void flush_internal_tx_queue(DPDKDevice::TXInternalQueue &);
per_thread<DPDKDevice::TXInternalQueue> _iqueues;
#endif
DPDKDevice* _dev;
int _timeout;
bool _congestion_warning_printed;
bool _create;
uint32_t _tso;
bool _tco;
bool _uco;
bool _ipco;
friend class FromDPDKDevice;
};
inline void ToDPDKDevice::warn_congestion() {
if (!_congestion_warning_printed) {
if (!_blocking)
click_chatter("%s: packet dropped", name().c_str());
else
click_chatter("%s: congestion warning", name().c_str());
_congestion_warning_printed = true;
}
}
CLICK_ENDDECLS
#endif // CLICK_TODPDKDEVICE_USERLEVEL_HH