Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

TheJStone
Copy link
Contributor

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:

  1. change calls to queue's within drr to match Queue template
  2. add the ability to specify queuetype and arguments within protobuf message and construct that queue in drr.

Note: this pr will fail build until the Extended Utility Codel commit is merged because it is dependent on the methods in that pr.

Copy link
Member

@apanda apanda left a 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.

@@ -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_();
Copy link
Member

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.

Copy link
Member

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.

Copy link
Contributor Author

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) {
Copy link
Member

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.

Copy link
Contributor Author

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

if (err_num != 0) {
return CommandFailure(-err_num);
}

/* get flow queue generator */
Copy link
Member

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// for comments ;)

@@ -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_();
Copy link
Member

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.

uint64 window = 2; /// window in microseconds between changing states in codel
}

QueueType type = 4; /// which queuetype is used for each flow
Copy link
Member

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.

Copy link
Contributor Author

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.

@@ -41,7 +47,7 @@ DRR::~DRR() {
std::free(flow_ring_);
Copy link
Member

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?

Copy link
Contributor Author

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.

@@ -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.
Copy link
Member

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.

Copy link
Contributor Author

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.

@barath
Copy link
Contributor

barath commented Jun 20, 2017

What's the status of this PR?

@TheJStone
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants