8
8
#include " ../utils/ether.h"
9
9
#include " ../utils/ip.h"
10
10
#include " ../utils/udp.h"
11
+ #include " ../utils/common.h"
12
+ #include " ../utils/codel.h"
13
+
14
+ using bess::utils::Codel;
15
+ using bess::pb::DRRArg;
11
16
12
17
uint32_t RoundToPowerTwo (uint32_t v) {
13
18
v--;
@@ -31,7 +36,8 @@ DRR::DRR()
31
36
max_queue_size_(kFlowQueueMax ),
32
37
max_number_flows_(kDefaultNumFlows ),
33
38
flow_ring_(nullptr ),
34
- current_flow_(nullptr ) {}
39
+ current_flow_(nullptr ),
40
+ generator_(NULL ) {}
35
41
36
42
DRR::~DRR () {
37
43
for (auto it = flows_.begin (); it != flows_.end ();) {
@@ -41,7 +47,7 @@ DRR::~DRR() {
41
47
std::free (flow_ring_);
42
48
}
43
49
44
- CommandResponse DRR::Init (const bess::pb:: DRRArg& arg) {
50
+ CommandResponse DRR::Init (const DRRArg& arg) {
45
51
CommandResponse err;
46
52
task_id_t tid;
47
53
@@ -70,11 +76,37 @@ CommandResponse DRR::Init(const bess::pb::DRRArg& arg) {
70
76
}
71
77
72
78
int err_num = 0 ;
73
- flow_ring_ = AddQueue (max_number_flows_, &err_num );
79
+ flow_ring_ = new LockLessQueue<Flow*> (max_number_flows_, true , true );
74
80
if (err_num != 0 ) {
75
81
return CommandFailure (-err_num);
76
82
}
77
83
84
+ /* get flow queue generator */
85
+ if (arg.type () == DRRArg::CODEL) {
86
+ const DRRArg::Codel& codel = arg.codel ();
87
+ uint64_t target;
88
+ uint64_t window;
89
+ if (!(target = codel.target ())) {
90
+ target = Codel<bess::Packet*>::kDefaultTarget ;
91
+ }
92
+
93
+ if (!(window = codel.window ())) {
94
+ window = Codel<bess::Packet*>::kDefaultWindow ;
95
+ }
96
+
97
+ generator_ =
98
+ Codel<bess::Packet*>::Factory (bess::Packet::Free, max_queue_size_, target, window);
99
+ } else {
100
+ const DRRArg::Llring& ring = arg.ring ();
101
+ size_t size;
102
+ if (!(size = ring.size ())) {
103
+ size = LockLessQueue<bess::Packet*>::kDefaultRingSize ;
104
+ }
105
+
106
+ generator_ = LockLessQueue<bess::Packet*>::Factory (
107
+ size, !ring.multiple_producer (), !ring.multiple_consumer ());
108
+ }
109
+
78
110
return CommandSuccess ();
79
111
}
80
112
@@ -101,7 +133,7 @@ void DRR::ProcessBatch(bess::PacketBatch* batch) {
101
133
// if the Flow doesn't exist create one
102
134
// and add the packet to the new Flow
103
135
if (it == nullptr ) {
104
- if (llring_full ( flow_ring_)) {
136
+ if (flow_ring_-> Full ( )) {
105
137
bess::Packet::Free (pkt);
106
138
} else {
107
139
AddNewFlow (pkt, id, &err);
@@ -140,7 +172,7 @@ struct task_result DRR::RunTask(void*) {
140
172
uint32_t DRR::GetNextBatch (bess::PacketBatch* batch, int * err) {
141
173
Flow* f;
142
174
uint32_t total_bytes = 0 ;
143
- uint32_t count = llring_count ( flow_ring_);
175
+ uint32_t count = flow_ring_-> Size ( );
144
176
if (current_flow_) {
145
177
count++;
146
178
}
@@ -155,33 +187,30 @@ uint32_t DRR::GetNextBatch(bess::PacketBatch* batch, int* err) {
155
187
if (batch_size == batch->cnt ()) {
156
188
break ;
157
189
} else {
158
- count = llring_count ( flow_ring_);
190
+ count = flow_ring_-> Size ( );
159
191
batch_size = batch->cnt ();
160
192
}
161
193
}
162
194
count--;
163
195
164
196
f = GetNextFlow (err);
165
- if (*err != 0 ) {
197
+ if (*err) {
166
198
return total_bytes;
167
199
} else if (f == nullptr ) {
168
200
continue ;
169
201
}
170
202
171
- uint32_t bytes = GetNextPackets (batch, f, err );
203
+ uint32_t bytes = GetNextPackets (batch, f);
172
204
total_bytes += bytes;
173
- if (*err != 0 ) {
174
- return total_bytes;
175
- }
176
205
177
- if (llring_empty ( f->queue ) && !f->next_packet ) {
206
+ if (f->queue -> Empty ( ) && !f->next_packet ) {
178
207
f->deficit = 0 ;
179
208
}
180
209
181
210
// if the flow doesn't have any more packets to give, reenqueue it
182
211
if (!f->next_packet || f->next_packet ->total_len () > f->deficit ) {
183
- *err = llring_enqueue ( flow_ring_, f);
184
- if (*err != 0 ) {
212
+ *err = flow_ring_-> Push ( f);
213
+ if (*err) {
185
214
return total_bytes;
186
215
}
187
216
} else {
@@ -198,18 +227,18 @@ DRR::Flow* DRR::GetNextFlow(int* err) {
198
227
double now = get_epoch_time ();
199
228
200
229
if (!current_flow_) {
201
- *err = llring_dequeue ( flow_ring_, reinterpret_cast < void **>(&f) );
202
- if (*err < 0 ) {
230
+ *err = flow_ring_-> Pop (f );
231
+ if (*err) {
203
232
return nullptr ;
204
233
}
205
234
206
- if (llring_empty ( f->queue ) && !f->next_packet ) {
235
+ if (f->queue -> Empty ( ) && !f->next_packet ) {
207
236
// if the flow expired, remove it
208
237
if (now - f->timer > kTtl ) {
209
238
RemoveFlow (f);
210
239
} else {
211
- *err = llring_enqueue ( flow_ring_, f);
212
- if (*err < 0 ) {
240
+ *err = flow_ring_-> Push ( f);
241
+ if (*err) {
213
242
return nullptr ;
214
243
}
215
244
}
@@ -224,15 +253,15 @@ DRR::Flow* DRR::GetNextFlow(int* err) {
224
253
return f;
225
254
}
226
255
227
- uint32_t DRR::GetNextPackets (bess::PacketBatch* batch, Flow* f, int * err ) {
256
+ uint32_t DRR::GetNextPackets (bess::PacketBatch* batch, Flow* f) {
228
257
uint32_t total_bytes = 0 ;
229
258
bess::Packet* pkt;
230
259
231
- while (!batch->full () && (!llring_empty ( f->queue ) || f->next_packet )) {
260
+ while (!batch->full () && (!f->queue -> Empty ( ) || f->next_packet )) {
232
261
// makes sure there isn't already a packet at the front
233
262
if (!f->next_packet ) {
234
- * err = llring_dequeue ( f->queue , reinterpret_cast < void **>(& pkt) );
235
- if (* err < 0 ) {
263
+ int err = f->queue -> Pop ( pkt);
264
+ if (err) {
236
265
return total_bytes;
237
266
}
238
267
} else {
@@ -274,21 +303,21 @@ void DRR::AddNewFlow(bess::Packet* pkt, FlowId id, int* err) {
274
303
Flow* f = new Flow (id);
275
304
276
305
// TODO(joshua) do proper error checking
277
- f->queue = AddQueue ( static_cast < int >( kFlowQueueSize ), err );
306
+ f->queue = generator_ ( );
278
307
279
- if (*err != 0 ) {
308
+ if (*err) {
280
309
return ;
281
310
}
282
311
283
312
flows_.Insert (id, f);
284
313
285
314
Enqueue (f, pkt, err);
286
- if (*err != 0 ) {
315
+ if (*err) {
287
316
return ;
288
317
}
289
318
290
319
// puts flow in round robin
291
- *err = llring_enqueue ( flow_ring_, f);
320
+ *err = flow_ring_-> Push ( f);
292
321
}
293
322
294
323
void DRR::RemoveFlow (Flow* f) {
@@ -299,77 +328,34 @@ void DRR::RemoveFlow(Flow* f) {
299
328
delete f;
300
329
}
301
330
302
- llring* DRR::AddQueue (uint32_t slots, int * err) {
303
- int bytes = llring_bytes_with_slots (slots);
304
- int ret;
305
-
306
- llring* queue = static_cast <llring*>(aligned_alloc (alignof (llring), bytes));
307
- if (!queue) {
308
- *err = -ENOMEM;
309
- return nullptr ;
310
- }
311
-
312
- ret = llring_init (queue, slots, 1 , 1 );
313
- if (ret) {
314
- std::free (queue);
315
- *err = -EINVAL;
316
- return nullptr ;
317
- }
318
- return queue;
319
- }
320
331
321
332
void DRR::Enqueue (Flow* f, bess::Packet* newpkt, int * err) {
322
333
// if the queue is full. drop the packet.
323
- if (llring_count ( f->queue ) >= max_queue_size_) {
334
+ if (f->queue -> Size ( ) >= max_queue_size_) {
324
335
bess::Packet::Free (newpkt);
325
336
return ;
326
337
}
327
338
328
339
// creates a new queue if there is not enough space for the new packet
329
340
// in the old queue
330
- if (llring_full ( f->queue )) {
341
+ if (f->queue -> Full ( )) {
331
342
uint32_t slots =
332
- RoundToPowerTwo (llring_count ( f->queue ) * kQueueGrowthFactor );
333
- f-> queue = ResizeQueue ( f->queue , slots, err );
334
- if (*err != 0 ) {
343
+ RoundToPowerTwo (f->queue -> Size ( ) * kQueueGrowthFactor );
344
+ *err = f->queue -> Resize ( slots);
345
+ if (*err) {
335
346
bess::Packet::Free (newpkt);
336
347
return ;
337
348
}
338
349
}
339
350
340
- *err = llring_enqueue ( f->queue , reinterpret_cast < void *> (newpkt) );
341
- if (*err == 0 ) {
351
+ *err = f->queue -> Push (newpkt);
352
+ if (! *err) {
342
353
f->timer = get_epoch_time ();
343
354
} else {
344
355
bess::Packet::Free (newpkt);
345
356
}
346
357
}
347
358
348
- llring* DRR::ResizeQueue (llring* old_queue, uint32_t new_size, int * err) {
349
- llring* new_queue = AddQueue (new_size, err);
350
- if (*err != 0 ) {
351
- return nullptr ;
352
- }
353
-
354
- // migrates packets from the old queue
355
- if (old_queue) {
356
- bess::Packet* pkt;
357
-
358
- while (llring_dequeue (old_queue, reinterpret_cast <void **>(&pkt)) == 0 ) {
359
- *err = llring_enqueue (new_queue, pkt);
360
- if (*err == -LLRING_ERR_NOBUF) {
361
- bess::Packet::Free (pkt);
362
- *err = 0 ;
363
- } else if (*err != 0 ) {
364
- std::free (new_queue);
365
- return nullptr ;
366
- }
367
- }
368
-
369
- std::free (old_queue);
370
- }
371
- return new_queue;
372
- }
373
359
374
360
CommandResponse DRR::SetQuantumSize (uint32_t size) {
375
361
if (size == 0 ) {
0 commit comments