These are some notes about a discussion several of us (Adrian, Matt, Randall, Drew, Jonathan) had recently about TCP callouts, particularly in an RSS world.
These are my (Jonathan's) notes (and I've fleshed out the idea more than we discussed), so any errors are mine. (But, credit can go to the group.)
Create N threads per RSS bucket to handle TCP “session state maintenance” (which I am basically defining as the same things our timers do for us today).
Place the TCPCB in the callout wheel based on the time of the next event that needs to occur.
When the TCPCB hits the front of the callout wheel, evaluate its state in a sane, holistic way and take whatever action needs to be taken for the TCPCB.
If the TCPCB is locked, just reschedule the callout (up to X number of times, at which point you block).
Fudge things so you will evaluate all actions that are “about” to happen (e.g. in the next half-millisecond or so) at the same time.
Ideally, co-locate the “session state maintenance” (i.e. “timer”) threads on the same core as the RSS bucket.
If you really want to take this a step further, you could even do things like:
When incoming packets arrive on a different CPU, queue them to be handled by the correct TCP “session state maintenance” thread.
When the user does something that would create a call to tcp_output(), schedule the call to occur within the TCP “session state maintenance” thread.
This is just a thumbnail sketch, but it should give the general idea. Hopefully, this will decrease cache misses, reduce lock contention, reduce the number of times we reschedule callouts, etc.