SSU: Increase CoDel drop threshold at UDPSender queue

Increase min and max queue size
Tweak stats
Util: Allow creation of CoDel queues with non-default parameters
New params are tentative, may be adjusted later
This commit is contained in:
zzz
2021-03-08 08:12:10 -05:00
parent 0b71fcf2e6
commit 82b7eea5f0
4 changed files with 53 additions and 18 deletions

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Git";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 5;
public final static long BUILD = 6;
/** for example "-test" */
public final static String EXTRA = "";

View File

@@ -35,8 +35,10 @@ class UDPSender {
// Queue needs to be big enough that we can compete with NTCP for
// bandwidth requests, and so CoDel can work well.
// When full, packets back up into the PacketPusher thread, pre-CoDel.
private static final int MIN_QUEUE_SIZE = 64;
private static final int MAX_QUEUE_SIZE = 384;
private static final int MIN_QUEUE_SIZE = 128;
private static final int MAX_QUEUE_SIZE = 768;
private static final int CODEL_TARGET = 100;
private static final int CODEL_INTERVAL = 500;
public UDPSender(RouterContext ctx, DatagramSocket socket, String name, SocketListener lsnr) {
_context = ctx;
@@ -44,7 +46,7 @@ class UDPSender {
_log = ctx.logManager().getLog(UDPSender.class);
long maxMemory = SystemVersion.getMaxMemory();
int qsize = (int) Math.max(MIN_QUEUE_SIZE, Math.min(MAX_QUEUE_SIZE, maxMemory / (1024*1024)));
_outboundQueue = new CoDelBlockingQueue<UDPPacket>(ctx, "UDP-Sender", qsize);
_outboundQueue = new CoDelBlockingQueue<UDPPacket>(ctx, "UDP-Sender", qsize, CODEL_TARGET, CODEL_INTERVAL);
_socket = socket;
_runner = new Runner();
_name = name;
@@ -283,13 +285,13 @@ class UDPSender {
if (throttleTime > 10)
_context.statManager().addRateData("udp.sendBWThrottleTime", throttleTime, acquireTime - packet.getBegin());
if (packet.getMarkedType() == 1)
_context.statManager().addRateData("udp.sendACKTime", throttleTime, packet.getLifetime());
_context.statManager().addRateData("udp.pushTime", packet.getLifetime(), packet.getLifetime());
_context.statManager().addRateData("udp.sendPacketSize", size, packet.getLifetime());
_context.statManager().addRateData("udp.sendACKTime", throttleTime);
_context.statManager().addRateData("udp.pushTime", packet.getLifetime());
_context.statManager().addRateData("udp.sendPacketSize", size);
} catch (IOException ioe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error sending to " + packet.getPacket().getAddress(), ioe);
_context.statManager().addRateData("udp.sendException", 1, packet.getLifetime());
_context.statManager().addRateData("udp.sendException", 1);
if (_socket.isClosed()) {
if (_keepRunning) {
_keepRunning = false;

View File

@@ -56,17 +56,17 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
*
* I2P: Raise to 15 due to multithreading environment
*
* Maybe need to make configurable per-instance.
*/
private static final long TARGET = 15;
private static final int TARGET = 15;
private final long _target;
/**
* Quote:
* A setting of 100 ms works well across a range of RTTs from 10 ms to 1 second
*
* Maybe need to make configurable per-instance.
*/
private static final long INTERVAL = 100;
private static final int INTERVAL = 100;
private final long _interval;
//private static final int MAXPACKET = 512;
private final String STAT_DROP;
@@ -75,14 +75,28 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
private static final long BACKLOG_TIME = 2*1000;
/**
* Target 15, interval 100
*
* @param name for stats
*/
public CoDelBlockingQueue(I2PAppContext ctx, String name, int capacity) {
this(ctx, name, capacity, TARGET, INTERVAL);
}
/**
* @param target the target max latency (ms)
* @param interval how long above target to start dropping (ms)
* @param name for stats
* @since 0.9.50
*/
public CoDelBlockingQueue(I2PAppContext ctx, String name, int capacity, int target, int interval) {
super(capacity);
_context = ctx;
_log = ctx.logManager().getLog(CoDelBlockingQueue.class);
_name = name;
_capacity = capacity;
_target = target;
_interval = interval;
STAT_DROP = ("codel." + name + ".drop").intern();
STAT_DELAY = ("codel." + name + ".delay").intern();
ctx.statManager().createRateStat(STAT_DROP, "queue delay of dropped items", "Router", RATES);
@@ -207,13 +221,13 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
long sojurn = _now - entry.getEnqueueTime();
_context.statManager().addRateData(STAT_DELAY, sojurn);
// I2P use isEmpty instead of size() < MAXPACKET
if (sojurn < TARGET || isEmpty()) {
if (sojurn < _target || isEmpty()) {
_first_above_time = 0;
} else {
if (_first_above_time == 0) {
// just went above from below. if we stay above
// for at least INTERVAL we'll say it's ok to drop
_first_above_time = _now + INTERVAL;
// for at least _interval we'll say it's ok to drop
_first_above_time = _now + _interval;
} else if (_now >= _first_above_time) {
ok_to_drop = true;
}
@@ -270,7 +284,7 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
}
}
} else if (ok_to_drop &&
(_now - _drop_next < INTERVAL || _now - _first_above_time >= INTERVAL)) {
(_now - _drop_next < _interval || _now - _first_above_time >= _interval)) {
// If we get here, then we're not in dropping state. If the sojourn time has been above
// target for interval, then we decide whether it's time to enter dropping state.
// We do so if we've been either in dropping state recently or above target for a relatively
@@ -287,7 +301,7 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
_dropping = true;
// If we're in a drop cycle, the drop rate that controlled the queue
// on the last cycle is a good starting point to control it now.
if (_now - _drop_next < INTERVAL)
if (_now - _drop_next < _interval)
_count = _count > 2 ? _count - 2 : 1;
else
_count = 1;
@@ -313,6 +327,6 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
* Caller must synch on this
*/
private void control_law(long t) {
_drop_next = t + (long) (INTERVAL / Math.sqrt(_count));
_drop_next = t + (long) (_interval / Math.sqrt(_count));
}
}