* [PATCH v3 01/10] dql: Dynamic queue limits
@ 2011-11-23 5:52 Tom Herbert
2011-11-23 14:58 ` Eric Dumazet
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Tom Herbert @ 2011-11-23 5:52 UTC (permalink / raw)
To: davem, netdev
Implementation of dynamic queue limits (dql). This is a libary which
allows a queue limit to be dynamically managed. The goal of dql is
to set the queue limit, number of objects to the queue, to be minimized
without allowing the queue to be starved.
dql would be used with a queue which has these properties:
1) Objects are queued up to some limit which can be expressed as a
count of objects.
2) Periodically a completion process executes which retires consumed
objects.
3) Starvation occurs when limit has been reached, all queued data has
actually been consumed but completion processing has not yet run,
so queuing new data is blocked.
4) Minimizing the amount of queued data is desirable.
A canonical example of such a queue would be a NIC HW transmit queue.
The queue limit is dynamic, it will increase or decrease over time
depending on the workload. The queue limit is recalculated each time
completion processing is done. Increases occur when the queue is
starved and can exponentially increase over successive intervals.
Decreases occur when more data is being maintained in the queue than
needed to prevent starvation. The number of extra objects, or "slack",
is measured over successive intervals, and to avoid hysteresis the
limit is only reduced by the miminum slack seen over a configurable
time period.
dql API provides routines to manage the queue:
- dql_init is called to intialize the dql structure
- dql_reset is called to reset dynamic values
- dql_queued called when objects are being enqueued
- dql_avail returns availability in the queue
- dql_completed is called when objects have be consumed in the queue
Configuration consists of:
- max_limit, maximum limit
- min_limit, minimum limit
- slack_hold_time, time to measure instances of slack before reducing
queue limit
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/dynamic_queue_limits.h | 81 +++++++++++++++++++++
lib/Kconfig | 3 +
lib/Makefile | 2 +
lib/dynamic_queue_limits.c | 132 ++++++++++++++++++++++++++++++++++
4 files changed, 218 insertions(+), 0 deletions(-)
create mode 100644 include/linux/dynamic_queue_limits.h
create mode 100644 lib/dynamic_queue_limits.c
diff --git a/include/linux/dynamic_queue_limits.h b/include/linux/dynamic_queue_limits.h
new file mode 100644
index 0000000..8953187
--- /dev/null
+++ b/include/linux/dynamic_queue_limits.h
@@ -0,0 +1,81 @@
+/*
+ * Dynamic queue limits (dql) - Definitions
+ *
+ * Copyright (c) 2011, Tom Herbert <therbert@google.com>
+ *
+ * This header file contains the definitions for dynamic queue limits (dql).
+ * dql would be used in conjunction with a producer/consumer type queue
+ * (possibly a HW queue). Such a queue would have these general properties:
+ *
+ * 1) Objects are queued up to some limit specified as number of objects.
+ * 2) Periodically a completion process executes which retires consumed
+ * objects.
+ * 3) Starvation occurs when limit has been reached, all queued data has
+ * actually been consumed, but completion processing has not yet run
+ * so queuing new data is blocked.
+ * 4) Minimizing the amount of queued data is desirable.
+ *
+ * The goal of dql is to calculate the limit as the minimum number of objects
+ * needed to prevent starvation.
+ *
+ * The dql implementation does not implement any locking for the dql data
+ * structures, the higher layer should provide this.
+ */
+
+#ifndef _LINUX_DQL_H
+#define _LINUX_DQL_H
+
+#ifdef __KERNEL__
+
+struct dql {
+ unsigned long num_queued; /* Total ever queued */
+ unsigned long last_obj_cnt; /* Count at last queuing */
+
+ unsigned long limit ____cacheline_aligned_in_smp; /* Current limit */
+ unsigned long prev_ovlimit; /* Previous over limit */
+
+ unsigned long prev_num_queued; /* Previous queue total */
+ unsigned long num_completed; /* Total ever completed */
+
+ unsigned long prev_last_obj_cnt; /* Previous queuing cnt */
+
+ unsigned long lowest_slack; /* Lowest slack found */
+ unsigned long slack_start_time; /* Time slacks seen */
+
+ unsigned long max_limit ____cacheline_aligned_in_smp; /* Max limit */
+ unsigned long min_limit; /* Minimum limit */
+ unsigned slack_hold_time; /* Time to measure slack */
+};
+
+/* Set some static maximums */
+#define DQL_MAX_OBJECT (-1UL / 16)
+#define DQL_MAX_LIMIT ((-1UL / 2) - DQL_MAX_OBJECT)
+
+/* Record number of objects queued. */
+static inline void dql_queued(struct dql *dql, unsigned long count)
+{
+ BUG_ON(count > DQL_MAX_OBJECT);
+ BUG_ON(dql->num_queued - dql->num_completed > DQL_MAX_LIMIT);
+
+ dql->num_queued += count;
+ dql->last_obj_cnt = count;
+}
+
+/* Returns how many objects can be queued, < 0 indicates over limit. */
+static inline long dql_avail(struct dql *dql)
+{
+ return dql->limit - (dql->num_queued - dql->num_completed);
+}
+
+/* Record number of completed objects and recalculate the limit. */
+extern void dql_completed(struct dql *dql, unsigned long count);
+
+/* Reset dql state */
+extern void dql_reset(struct dql *dql);
+
+/* Initialize dql state */
+extern int dql_init(struct dql *dql, unsigned hold_time);
+
+#endif /* _KERNEL_ */
+
+#endif /* _LINUX_DQL_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 32f3e5a..63b5782 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -244,6 +244,9 @@ config CPU_RMAP
bool
depends on SMP
+config DQL
+ bool
+
#
# Netlink attribute parsing support is select'ed if needed
#
diff --git a/lib/Makefile b/lib/Makefile
index a4da283..ff00d4d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -115,6 +115,8 @@ obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o
obj-$(CONFIG_CORDIC) += cordic.o
+obj-$(CONFIG_DQL) += dynamic_queue_limits.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
new file mode 100644
index 0000000..9b9edb0
--- /dev/null
+++ b/lib/dynamic_queue_limits.c
@@ -0,0 +1,132 @@
+/*
+ * Dynamic byte queue limits. See include/linux/dynamic_queue_limits.h
+ *
+ * Copyright (c) 2011, Tom Herbert <therbert@google.com>
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/dynamic_queue_limits.h>
+
+#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
+
+/* Records completed count and recalculates the queue limit */
+void dql_completed(struct dql *dql, unsigned long count)
+{
+ unsigned long inprogress, prev_inprogress, limit;
+ unsigned long ovlimit, all_prev_completed, completed;
+
+ /* Can't complete more than what's in queue */
+ BUG_ON(count > dql->num_queued - dql->num_completed);
+
+ completed = dql->num_completed + count;
+ limit = dql->limit;
+ ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
+ inprogress = dql->num_queued - completed;
+ prev_inprogress = dql->prev_num_queued - dql->num_completed;
+ all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
+
+ if ((ovlimit && !inprogress) ||
+ (dql->prev_ovlimit && all_prev_completed)) {
+ /*
+ * Queue considered starved if:
+ * - The queue was over-limit in the last interval,
+ * and there is no more data in the queue.
+ * OR
+ * - The queue was over-limit in the previous interval and
+ * when enqueuing it was possible that all queued data
+ * had been consumed. This covers the case when queue
+ * may have becomes starved between completion processing
+ * running and next time enqueue was scheduled.
+ *
+ * When queue is starved increase the limit by the amount
+ * of bytes both sent and completed in the last interval,
+ * plus any previous over-limit.
+ */
+ limit += POSDIFF(completed, dql->prev_num_queued) +
+ dql->prev_ovlimit;
+ dql->slack_start_time = jiffies;
+ dql->lowest_slack = -1UL;
+ } else if (inprogress && prev_inprogress && !all_prev_completed) {
+ /*
+ * Queue was not starved, check if the limit can be decreased.
+ * A decrease is only considered if the queue has been busy in
+ * the whole interval (the check above).
+ *
+ * If there is slack, the amount of execess data queued above
+ * the the amount needed to prevent starvation, the queue limit
+ * can be decreased. To avoid hysteresis we consider the
+ * minimum amount of slack found over several iterations of the
+ * completion routine.
+ */
+ unsigned long slack, slack_last_objs;
+
+ /*
+ * Slack is the maximum of
+ * - The queue limit plus previous over-limit minus twice
+ * the number of objects completed. Note that two times
+ * number of completed bytes is a basis for an upper bound
+ * of the limit.
+ * - Portion of objects in the last queuing operation that
+ * was not part of non-zero previous over-limit. That is
+ * "round down" by non-overlimit portion of the last
+ * queueing operation.
+ */
+ slack = POSDIFF(limit + dql->prev_ovlimit,
+ 2 * (completed - dql->num_completed));
+ slack_last_objs = dql->prev_ovlimit ?
+ POSDIFF(dql->prev_last_obj_cnt, dql->prev_ovlimit) : 0;
+
+ slack = max(slack, slack_last_objs);
+
+ if (slack < dql->lowest_slack)
+ dql->lowest_slack = slack;
+
+ if (time_after(jiffies,
+ dql->slack_start_time + dql->slack_hold_time)) {
+ limit = POSDIFF(limit, dql->lowest_slack);
+ dql->slack_start_time = jiffies;
+ dql->lowest_slack = -1UL;
+ }
+ }
+
+ /* Enforce bounds on limit */
+ limit = clamp(limit, dql->min_limit, dql->max_limit);
+
+ if (limit != dql->limit) {
+ dql->limit = limit;
+ ovlimit = 0;
+ }
+
+ dql->prev_ovlimit = ovlimit;
+ dql->prev_last_obj_cnt = dql->last_obj_cnt;
+ dql->num_completed = completed;
+ dql->prev_num_queued = dql->num_queued;
+}
+EXPORT_SYMBOL(dql_completed);
+
+void dql_reset(struct dql *dql)
+{
+ /* Reset all dynamic values */
+ dql->limit = 0;
+ dql->num_queued = 0;
+ dql->num_completed = 0;
+ dql->last_obj_cnt = 0;
+ dql->prev_num_queued = 0;
+ dql->prev_last_obj_cnt = 0;
+ dql->prev_ovlimit = 0;
+ dql->lowest_slack = -1UL;
+ dql->slack_start_time = jiffies;
+}
+EXPORT_SYMBOL(dql_reset);
+
+int dql_init(struct dql *dql, unsigned hold_time)
+{
+ dql->max_limit = DQL_MAX_LIMIT;
+ dql->min_limit = 0;
+ dql->slack_hold_time = hold_time;
+ dql_reset(dql);
+ return 0;
+}
+EXPORT_SYMBOL(dql_init);
--
1.7.3.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 5:52 [PATCH v3 01/10] dql: Dynamic queue limits Tom Herbert
@ 2011-11-23 14:58 ` Eric Dumazet
2011-11-23 15:05 ` Eric Dumazet
2011-11-23 15:35 ` David Laight
2011-11-23 16:37 ` Stephen Hemminger
2011-11-23 17:27 ` Dave Taht
2 siblings, 2 replies; 7+ messages in thread
From: Eric Dumazet @ 2011-11-23 14:58 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
Le mardi 22 novembre 2011 à 21:52 -0800, Tom Herbert a écrit :
> Implementation of dynamic queue limits (dql). This is a libary which
> allows a queue limit to be dynamically managed. The goal of dql is
> to set the queue limit, number of objects to the queue, to be minimized
> without allowing the queue to be starved.
>
> dql would be used with a queue which has these properties:
>
> 1) Objects are queued up to some limit which can be expressed as a
> count of objects.
> 2) Periodically a completion process executes which retires consumed
> objects.
> 3) Starvation occurs when limit has been reached, all queued data has
> actually been consumed but completion processing has not yet run,
> so queuing new data is blocked.
> 4) Minimizing the amount of queued data is desirable.
>
> A canonical example of such a queue would be a NIC HW transmit queue.
>
> The queue limit is dynamic, it will increase or decrease over time
> depending on the workload. The queue limit is recalculated each time
> completion processing is done. Increases occur when the queue is
> starved and can exponentially increase over successive intervals.
> Decreases occur when more data is being maintained in the queue than
> needed to prevent starvation. The number of extra objects, or "slack",
> is measured over successive intervals, and to avoid hysteresis the
> limit is only reduced by the miminum slack seen over a configurable
> time period.
>
> dql API provides routines to manage the queue:
> - dql_init is called to intialize the dql structure
> - dql_reset is called to reset dynamic values
> - dql_queued called when objects are being enqueued
> - dql_avail returns availability in the queue
> - dql_completed is called when objects have be consumed in the queue
>
> Configuration consists of:
> - max_limit, maximum limit
> - min_limit, minimum limit
> - slack_hold_time, time to measure instances of slack before reducing
> queue limit
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> include/linux/dynamic_queue_limits.h | 81 +++++++++++++++++++++
> lib/Kconfig | 3 +
> lib/Makefile | 2 +
> lib/dynamic_queue_limits.c | 132 ++++++++++++++++++++++++++++++++++
> 4 files changed, 218 insertions(+), 0 deletions(-)
> create mode 100644 include/linux/dynamic_queue_limits.h
> create mode 100644 lib/dynamic_queue_limits.c
>
> diff --git a/include/linux/dynamic_queue_limits.h b/include/linux/dynamic_queue_limits.h
> new file mode 100644
> index 0000000..8953187
> --- /dev/null
> +++ b/include/linux/dynamic_queue_limits.h
> @@ -0,0 +1,81 @@
> +/*
> + * Dynamic queue limits (dql) - Definitions
> + *
> + * Copyright (c) 2011, Tom Herbert <therbert@google.com>
> + *
> + * This header file contains the definitions for dynamic queue limits (dql).
> + * dql would be used in conjunction with a producer/consumer type queue
> + * (possibly a HW queue). Such a queue would have these general properties:
> + *
> + * 1) Objects are queued up to some limit specified as number of objects.
> + * 2) Periodically a completion process executes which retires consumed
> + * objects.
> + * 3) Starvation occurs when limit has been reached, all queued data has
> + * actually been consumed, but completion processing has not yet run
> + * so queuing new data is blocked.
> + * 4) Minimizing the amount of queued data is desirable.
> + *
> + * The goal of dql is to calculate the limit as the minimum number of objects
> + * needed to prevent starvation.
> + *
> + * The dql implementation does not implement any locking for the dql data
> + * structures, the higher layer should provide this.
> + */
Maybe give a hint on the fact that all dql_queued() must be serialized,
all dql_completed() must be serialized, but can use a different lock
(a dql_completed() can be run while a dql_queued() is run)
> +
> +#ifndef _LINUX_DQL_H
> +#define _LINUX_DQL_H
> +
> +#ifdef __KERNEL__
> +
> +struct dql {
> + unsigned long num_queued; /* Total ever queued */
> + unsigned long last_obj_cnt; /* Count at last queuing */
> +
> + unsigned long limit ____cacheline_aligned_in_smp; /* Current limit */
> + unsigned long prev_ovlimit; /* Previous over limit */
> +
> + unsigned long prev_num_queued; /* Previous queue total */
> + unsigned long num_completed; /* Total ever completed */
> +
> + unsigned long prev_last_obj_cnt; /* Previous queuing cnt */
> +
> + unsigned long lowest_slack; /* Lowest slack found */
> + unsigned long slack_start_time; /* Time slacks seen */
> +
> + unsigned long max_limit ____cacheline_aligned_in_smp; /* Max limit */
> + unsigned long min_limit; /* Minimum limit */
> + unsigned slack_hold_time; /* Time to measure slack */
> +};
> +
Hmm, please dont do that, it will add two cache lines in transmit path,
and a third one for very seldom used data.
What is needed tx fast path are : num_queued, last_obj_cnt, limit and
num_completed.
So I suggest :
struct dql {
/* part used in dql_queued() */
unsigned long num_queued; /* Total ever queued */
unsigned long last_obj_cnt; /* Count at last queuing */
unsigned long limit; /* Current limit */
unsigned long num_completed; /* Total ever completed */
/* part used in dql_completed() */
unsigned long prev_ovlimit; /* Previous over limit */
unsigned long prev_num_queued; /* Previous queue total */
unsigned long prev_last_obj_cnt; /* Previous queuing cnt */
unsigned long lowest_slack; /* Lowest slack found */
unsigned long slack_start_time; /* Time slacks seen */
unsigned long max_limit; /* Max limit */
unsigned long min_limit; /* Minimum limit */
unsigned int slack_hold_time; /* Time to measure slack */
};
Another question is : Is DQL planned to work on 32bit arch ?
A fast interface can probably send more than 2^32 bytes for large
slack_hold_time values, and wrap around.
If yes : We can use "unsigned int" instead of "unsigned long" to lower
memory need on 64bit arch.
If no, "unsigned long" type is not enough on 32bit, or we need to limit
slack_hold_time to small intervals...
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 14:58 ` Eric Dumazet
@ 2011-11-23 15:05 ` Eric Dumazet
2011-11-23 15:35 ` David Laight
1 sibling, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2011-11-23 15:05 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
Le mercredi 23 novembre 2011 à 15:58 +0100, Eric Dumazet a écrit :
> Another question is : Is DQL planned to work on 32bit arch ?
>
> A fast interface can probably send more than 2^32 bytes for large
> slack_hold_time values, and wrap around.
>
> If yes : We can use "unsigned int" instead of "unsigned long" to lower
> memory need on 64bit arch.
>
> If no, "unsigned long" type is not enough on 32bit, or we need to limit
> slack_hold_time to small intervals...
>
>
Hmm, reading again the code, 32bit counters should be more than enough,
instead of "unsigned long", on all arches.
unsigned long is only needed for slack_start_time (to store jiffies)
This would lower sizeof( struct dql) to 48 or 56 bytes.
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 14:58 ` Eric Dumazet
2011-11-23 15:05 ` Eric Dumazet
@ 2011-11-23 15:35 ` David Laight
1 sibling, 0 replies; 7+ messages in thread
From: David Laight @ 2011-11-23 15:35 UTC (permalink / raw)
To: Eric Dumazet, Tom Herbert; +Cc: davem, netdev
> Another question is : Is DQL planned to work on 32bit arch ?
>
> A fast interface can probably send more than 2^32 bytes for large
> slack_hold_time values, and wrap around.
>
> If yes : We can use "unsigned int" instead of "unsigned long" to lower
> memory need on 64bit arch.
>
> If no, "unsigned long" type is not enough on 32bit, or we
> need to limit slack_hold_time to small intervals...
Another option would be divide the byte counts by (say) 16.
This would be good enough for the purpose, and increase the
time-to-wrap by a factor of 16.
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 5:52 [PATCH v3 01/10] dql: Dynamic queue limits Tom Herbert
2011-11-23 14:58 ` Eric Dumazet
@ 2011-11-23 16:37 ` Stephen Hemminger
2011-11-23 23:53 ` David Miller
2011-11-23 17:27 ` Dave Taht
2 siblings, 1 reply; 7+ messages in thread
From: Stephen Hemminger @ 2011-11-23 16:37 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
On Tue, 22 Nov 2011 21:52:21 -0800 (PST)
Tom Herbert <therbert@google.com> wrote:
> Implementation of dynamic queue limits (dql). This is a libary which
> allows a queue limit to be dynamically managed. The goal of dql is
> to set the queue limit, number of objects to the queue, to be minimized
> without allowing the queue to be starved.
>
> dql would be used with a queue which has these properties:
>
> 1) Objects are queued up to some limit which can be expressed as a
> count of objects.
> 2) Periodically a completion process executes which retires consumed
> objects.
> 3) Starvation occurs when limit has been reached, all queued data has
> actually been consumed but completion processing has not yet run,
> so queuing new data is blocked.
> 4) Minimizing the amount of queued data is desirable.
>
> A canonical example of such a queue would be a NIC HW transmit queue.
>
> The queue limit is dynamic, it will increase or decrease over time
> depending on the workload. The queue limit is recalculated each time
> completion processing is done. Increases occur when the queue is
> starved and can exponentially increase over successive intervals.
> Decreases occur when more data is being maintained in the queue than
> needed to prevent starvation. The number of extra objects, or "slack",
> is measured over successive intervals, and to avoid hysteresis the
> limit is only reduced by the miminum slack seen over a configurable
> time period.
>
> dql API provides routines to manage the queue:
> - dql_init is called to intialize the dql structure
> - dql_reset is called to reset dynamic values
> - dql_queued called when objects are being enqueued
> - dql_avail returns availability in the queue
> - dql_completed is called when objects have be consumed in the queue
>
> Configuration consists of:
> - max_limit, maximum limit
> - min_limit, minimum limit
> - slack_hold_time, time to measure instances of slack before reducing
> queue limit
>
> Signed-off-by: Tom Herbert <therbert@google.com>
Some minor stuff:
1. Since linux/dql.h is only kernel components (not API), it should
be net/dql.h
2. Don't make it a config option. "Do or do not, there is no try"
Config options are useless for distributions. I assume the plan
is that devices using DQL will enable it in their config.
Therefore adding device with DQL should modify the Kconfig for that
device.
3. Rather using -1ul in DQL_MAX_ why not use ULONG_MAX?
4. dql_avail should be:
static inline long dql_avail(const struct dql *dql)
{
return dql->limit - (dql->num_queued - dql->num_completed);
}
5. dql_init should be:
void dql_init(struct dql *dql, unsigned hold_time)
For clarity, IMHO would be better to change dql_completed()
so the code read like the comments.
Rather than:
completed = dql->num_completed + count;
limit = dql->limit;
ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
inprogress = dql->num_queued - completed;
prev_inprogress = dql->prev_num_queued - dql->num_completed;
all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
if ((ovlimit && !inprogress) ||
(dql->prev_ovlimit && all_prev_completed)) {
Instead:
if (dql_queue_starved(dql)) {
...
} else if (dql_queue_busy(dql)) {
...
Where dql_queue_starved and dql_queue_busy are inline's
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 16:37 ` Stephen Hemminger
@ 2011-11-23 23:53 ` David Miller
0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2011-11-23 23:53 UTC (permalink / raw)
To: shemminger; +Cc: therbert, netdev
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 23 Nov 2011 08:37:12 -0800
> 1. Since linux/dql.h is only kernel components (not API), it should
> be net/dql.h
It's a library routine under lib/, meant to be available to anyone not
just networking components even though networking is the only current
consumer.
His placement of the header file is therefore correct as-is.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 01/10] dql: Dynamic queue limits
2011-11-23 5:52 [PATCH v3 01/10] dql: Dynamic queue limits Tom Herbert
2011-11-23 14:58 ` Eric Dumazet
2011-11-23 16:37 ` Stephen Hemminger
@ 2011-11-23 17:27 ` Dave Taht
2 siblings, 0 replies; 7+ messages in thread
From: Dave Taht @ 2011-11-23 17:27 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
On Wed, Nov 23, 2011 at 6:52 AM, Tom Herbert <therbert@google.com> wrote:
> Implementation of dynamic queue limits (dql). This is a libary which
> allows a queue limit to be dynamically managed. The goal of dql is
> to set the queue limit, number of objects to the queue, to be minimized
> without allowing the queue to be starved.
Dear Tom:
I have been fiddling with v3 of your patch series for much of the day,
artificially imposing 10Mbit and 100Mbit limits on the network with
ethtool.
The performance of multiple tcp streams 'feels' quite good across
multiple, saturating workloads over the LFN, and short distances, but
the data I collected today was too muddled and confusing to publish.
I need to finish patching this into a couple other boxes before
rebuilding the testbed,
and judging from the code review comments it would seem a good idea to
wait for another go-round.
I did a build on top of commit b4bbb02934e4511d9083f15c23e90703482e84ad
for ubuntu here:
http://huchra.bufferbloat.net/~d/bql/
the usual caveats apply to development kernels... I ran all day without a crash,
testing the e1000e driver, the qfq qdisc, red, and sfq.
two drivers (forcedeth, bnx2x_) did not apply on top of that commit.
If anyone cares, here are also the various QFQ + RED scheduler scripts
I've been fiddling with. These seemed to help at 100Mbit, in the
previous series.
https://github.com/dtaht/deBloat/blob/master/wip/
eqfq (pure qfq), eqfq.red and eqfq.red.10mbit are the only three
seriously tested at the moment.
Would love to know what/how qfq does to cpu at a gigabit (some red
tuning would be needed on top of the script) on a machine that can
drive it, now that there's drivers that stop gobbling packets so
greedily...
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-11-23 23:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-23 5:52 [PATCH v3 01/10] dql: Dynamic queue limits Tom Herbert
2011-11-23 14:58 ` Eric Dumazet
2011-11-23 15:05 ` Eric Dumazet
2011-11-23 15:35 ` David Laight
2011-11-23 16:37 ` Stephen Hemminger
2011-11-23 23:53 ` David Miller
2011-11-23 17:27 ` Dave Taht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox