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

misc fixes #1

Closed
wants to merge 2 commits into from
Closed

misc fixes #1

wants to merge 2 commits into from

Conversation

clifffrey
Copy link
Collaborator

This is my first attempt at using an official github pull request... we'll see how it goes.

There is one more change that needs to be made (adding a barrier in master.cc:process_pending), but I don't fully understand the exact sequence of events that are the problem there, so I'd rather leave that commit message up to Eddie.

Cliff Frey added 2 commits October 17, 2010 13:43
When running with this config on my machine, I would experience hangs
when running the following config/command.  The bug seems slightly
more likely to happen if you comment out the .set_now() line in
infinitesource.cc.

time ./userlevel/click --threads=4 -p 7777 foo.config

//////////////////
is1::InfiniteSource(DATA \<00 00 c0 ae 67 ef  00 00 00 00 00 00  08 00>, LIMIT 1000000, STOP false, BURST 1)
     -> q1::ThreadSafeQueue(CAPACITY 1)
     -> uq1::Unqueue(BURST 1)
     -> Discard;
is2::InfiniteSource(DATA \<00 00 c0 ae 67 ef  00 00 00 00 00 00  08 00>, LIMIT 1100000, STOP true, BURST 1)
     -> q2::ThreadSafeQueue(CAPACITY 1)
     -> uq2::Unqueue(BURST 1)
     -> Discard;
StaticThreadSched(is1 0, uq1 1, is2 2, uq2 3);
//////////////////

The hang is that q2.length = 0, is2.count = xxxx, is2.active = true,
and is2.scheduled = false (even though it should be true).

Thread 1 - InfiniteSource
-------------
 run task:
1a:    unschedule task;
1b:    push packet to queue; -- success, queue is now full
1c:    reschedule task;
 run task again:
1d:    unschedule task;
1e:    check downstream nonfull notifier
1f:    if notifier is on, then reschedule

Thread 2 - Unqueue
-------------
 run task:
2a:   pull packet from queue;
2b:   queue goes nonfull;
2c:   queue wakes notifier;
2d:   notifier checks if InfiniteSource task is scheduled
2e:   if task was not already scheduled, schedules InfiniteSource task;

The memory ordering condition is that 1e cannot see 2c at the same
time as 2d cannot see 1d.  To protect from this, we must add memory
barriers somewhere between 1d and 1e and also somewhere between 2c and
2d.

For the 1d -> 1e case, the logical places to add the barrier are
either after the write (after the unschedule() call in
routerthread.cc:run_tasks) or before the read (at the start of
notifier.hh:active).  I can see arguments for trying to keep both
memory barriers associated with the notifier code, and I can also see
arguments for always putting the memory barriers after the relevant
writes..

For the 2c -> 2d case, I believe that the only real choice is to put
the barrier in notifier.hh:set_active.
@clifffrey
Copy link
Collaborator Author

hmm, I deem my first attempt at a pull request as a failure. I definitely should have used a real branch, rather than "master^", but in addition, it is weird/annoying that I can't figure out how to change the pull request now that I've made it...

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

Successfully merging this pull request may close these issues.

None yet

1 participant