-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrated Codel into DRR #476
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments. I think drr.cc
could use a few more comments.
core/modules/drr.cc
Outdated
@@ -274,21 +303,21 @@ void DRR::AddNewFlow(bess::Packet* pkt, FlowId id, int* err) { | |||
Flow* f = new Flow(id); | |||
|
|||
// TODO(joshua) do proper error checking | |||
f->queue = AddQueue(static_cast<int>(kFlowQueueSize), err); | |||
f->queue = generator_(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that there are a fixed number of flows, I wonder if it might be worth considering preallocating these queues, avoiding some of the initial allocation costs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that there are only two types of Queue, I am somewhat concerned that the generator/factory mechanism might be a little over-engineered. Can we just simply do something like this...?
if (queue type is codel) {
f->queue = Codel(codel params);
} if (queue type is llring) {
f->queue = LockLessQueue(llring params);
}
This is less fancy, but shorter and simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I guess the main point of the factory is that it binds the parameters to the generator so that DRR doesn't have to have a place to store each queue type's parameters. I could just store these parameters and use this code if you think that is better? but I could also help simplify things down as panda suggested and have the factory take the protobuf message instead?
if (*err != 0) { | ||
RoundToPowerTwo(f->queue->Size() * kQueueGrowthFactor); | ||
*err = f->queue->Resize(slots); | ||
if (*err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code from the last PR did not indicate that the queue needed to survive a failed Resize
operation. In general I would have assumed a queue for which Resize
failed is no longer valid, in which case you should remove the flow to avoid bad accesses further down the line. Also it might be useful to log something so we know things have gone bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my current implementation of LockLessQueue and Codel, the old queue is not effected if the resize fails. is that too restrictive of an assumption to make? I can put it in resize
method description of queue.h
core/modules/drr.cc
Outdated
if (err_num != 0) { | ||
return CommandFailure(-err_num); | ||
} | ||
|
||
/* get flow queue generator */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might help readability if you split out the code for creating a generator from DRRArg::Codel
and DRRArg::Llring
to different functions -- perhaps they could be in static functions in codel.h
and lock_less_queue.h
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//
for comments ;)
core/modules/drr.cc
Outdated
@@ -274,21 +303,21 @@ void DRR::AddNewFlow(bess::Packet* pkt, FlowId id, int* err) { | |||
Flow* f = new Flow(id); | |||
|
|||
// TODO(joshua) do proper error checking | |||
f->queue = AddQueue(static_cast<int>(kFlowQueueSize), err); | |||
f->queue = generator_(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that there are only two types of Queue, I am somewhat concerned that the generator/factory mechanism might be a little over-engineered. Can we just simply do something like this...?
if (queue type is codel) {
f->queue = Codel(codel params);
} if (queue type is llring) {
f->queue = LockLessQueue(llring params);
}
This is less fancy, but shorter and simpler.
protobuf/module_msg.proto
Outdated
uint64 window = 2; /// window in microseconds between changing states in codel | ||
} | ||
|
||
QueueType type = 4; /// which queuetype is used for each flow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having QueueType
, we can do
oneof params {
Llring ring = 4;
Codel codel = 5;
}
This is more semantically correct (only either of them can be set), and simpler (neither Enum
nor type indicator is required).
In my opinion, Llring ring
should be renamed DropTailQueue
or something like that. The fact that the underlying queue is lockless is just internal implementation details; external users need to know what it does (plain old queue without active queue management), not how it is implemented.
I don't see much value for multiple_producer
and multiple_consumer
parameters. These parameters should be hidden from users; the system must not crash even if some parameters are not correctly set. Also, given that the module is not thread-safe, there is no point for mult-producer/consumer parameters set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok. I will make the respective changes.
core/modules/drr.cc
Outdated
@@ -41,7 +47,7 @@ DRR::~DRR() { | |||
std::free(flow_ring_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be delete flow_ring_
, since it was allocated via new
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I missed this in converting from llring.
core/modules/drr.h
Outdated
@@ -237,7 +220,8 @@ class DRR final : public Module { | |||
|
|||
// state map used to reunite packets with their flow | |||
CuckooMap<FlowId, Flow*, Hash, EqualTo> flows_; | |||
llring* flow_ring_; // llring used for round robin. | |||
LockLessQueue<Flow*>* flow_ring_; // queue used for round robin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it is not part of this PR, I am not quite convinced that this module needs LockLessQueue
to maintain a list of flows. All operations are single-item enqueue/dequeues so it would not give you any performance advantage (actually it will hurt). I'd rather recommend using std::deque
to keep the code less foreign.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. I will do this.
What's the status of this PR? |
I pushed the changes requested in the review and these chnages are awaiting further review. The code should also be run again now that the codel update has been merged. |
3d87c6e
to
aac0ccc
Compare
Uses the added functions in the commit Extended Utility Codel to allow the use of locklessqueue and Codel in DRR for each flow's queue. Main changes:
Note: this pr will fail build until the Extended Utility Codel commit is merged because it is dependent on the methods in that pr.