commit 12b6c7df4aaf3224bc5649ef69a06dccc58ae961 Author: Andrea Shepard andrea@torproject.org Date: Tue Oct 7 09:53:57 2014 -0700
Make queue thresholds and flush size for global scheduler into config options --- src/or/config.c | 22 ++++++++++++++++++++++ src/or/or.h | 13 +++++++++++++ src/or/scheduler.c | 38 +++++++++++++++++++++++++++++--------- src/or/scheduler.h | 3 +++ 4 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c index 86d7c6e..c124372 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -367,6 +367,9 @@ static config_var_t option_vars_[] = { V(ServerDNSSearchDomains, BOOL, "0"), V(ServerDNSTestAddresses, CSV, "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"), + V(SchedulerLowWaterMark, MEMUNIT, "16 kB"), + V(SchedulerHighWaterMark, MEMUNIT, "32 kB"), + V(SchedulerMaxFlushCells, UINT, "16"), V(ShutdownWaitLength, INTERVAL, "30 seconds"), V(SocksListenAddress, LINELIST, NULL), V(SocksPolicy, LINELIST, NULL), @@ -1522,6 +1525,25 @@ options_act(const or_options_t *old_options) return -1; }
+ /* Set up scheduler thresholds */ + if (options->SchedulerLowWaterMark > 0 && + options->SchedulerHighWaterMark > options->SchedulerLowWaterMark) { + scheduler_set_watermarks(options->SchedulerLowWaterMark, + options->SchedulerHighWaterMark, + (options->SchedulerMaxFlushCells > 0) ? + options->SchedulerMaxFlushCells : 16); + } else { + if (options->SchedulerLowWaterMark == 0) { + log_warn(LD_GENERAL, "Bad SchedulerLowWaterMark option"); + } + + if (options->SchedulerHighWaterMark <= options->SchedulerLowWaterMark) { + log_warn(LD_GENERAL, "Bad SchedulerHighWaterMark option"); + } + + return -1; + } + /* Set up accounting */ if (accounting_parse_options(options, 0)<0) { log_warn(LD_CONFIG,"Error in accounting options"); diff --git a/src/or/or.h b/src/or/or.h index 320931d..25df54a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4229,6 +4229,19 @@ typedef struct {
/** Should we send the timestamps that pre-023 hidden services want? */ int Support022HiddenServices; + + /** Low-water mark for global scheduler - start sending when estimated + * queued size falls below this threshold. + */ + uint32_t SchedulerLowWaterMark; + /** High-water mark for global scheduler - stop sending when estimated + * queued size exceeds this threshold. + */ + uint32_t SchedulerHighWaterMark; + /** Flush size for global scheduler - flush this many cells at a time + * when sending. + */ + unsigned int SchedulerMaxFlushCells; } or_options_t;
/** Persistent state for an onion router, as saved to disk. */ diff --git a/src/or/scheduler.c b/src/or/scheduler.c index c161393..c2ede84 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -21,16 +21,20 @@ #include <event.h> #endif
-#define SCHED_Q_LOW_WATER 16384 -#define SCHED_Q_HIGH_WATER (2 * SCHED_Q_LOW_WATER) +/* + * Scheduler high/low watermarks + */ + +static uint32_t sched_q_low_water = 16384; +static uint32_t sched_q_high_water = 32768;
/* * Maximum cells to flush in a single call to channel_flush_some_cells(); * setting this low means more calls, but too high and we could overshoot - * SCHED_Q_HIGH_WATER. + * sched_q_high_water. */
-#define SCHED_MAX_FLUSH_CELLS 16 +static uint32_t sched_max_flush_cells = 16;
/* * Write scheduling works by keeping track of which channels can @@ -343,7 +347,7 @@ scheduler_more_work(void) { tor_assert(channels_pending);
- return ((scheduler_get_queue_heuristic() < SCHED_Q_LOW_WATER) && + return ((scheduler_get_queue_heuristic() < sched_q_low_water) && ((smartlist_len(channels_pending) > 0))) ? 1 : 0; }
@@ -387,12 +391,12 @@ scheduler_run, (void))
log_debug(LD_SCHED, "We have a chance to run the scheduler");
- if (scheduler_get_queue_heuristic() < SCHED_Q_LOW_WATER) { + if (scheduler_get_queue_heuristic() < sched_q_low_water) { n_chans_before = smartlist_len(channels_pending); q_len_before = channel_get_global_queue_estimate(); q_heur_before = scheduler_get_queue_heuristic();
- while (scheduler_get_queue_heuristic() <= SCHED_Q_HIGH_WATER && + while (scheduler_get_queue_heuristic() <= sched_q_high_water && smartlist_len(channels_pending) > 0) { /* Pop off a channel */ chan = smartlist_pqueue_pop(channels_pending, @@ -410,10 +414,10 @@ scheduler_run, (void))
flushed = 0; while (flushed < n_cells && - scheduler_get_queue_heuristic() <= SCHED_Q_HIGH_WATER) { + scheduler_get_queue_heuristic() <= sched_q_high_water) { flushed_this_time = channel_flush_some_cells(chan, - MIN(SCHED_MAX_FLUSH_CELLS, + MIN(sched_max_flush_cells, n_cells - flushed)); if (flushed_this_time <= 0) break; flushed += flushed_this_time; @@ -686,3 +690,19 @@ scheduler_update_queue_heuristic(time_t now) /* else no update needed, or time went backward */ }
+/** + * Set scheduler watermarks and flush size + */ + +void +scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush) +{ + /* Sanity assertions - caller should ensure these are true */ + tor_assert(lo > 0); + tor_assert(hi > lo); + tor_assert(max_flush > 0); + + sched_q_low_water = lo; + sched_q_high_water = hi; + sched_max_flush_cells = max_flush; +} diff --git a/src/or/scheduler.h b/src/or/scheduler.h index 8854d5a..404776b 100644 --- a/src/or/scheduler.h +++ b/src/or/scheduler.h @@ -34,6 +34,9 @@ void scheduler_adjust_queue_size(channel_t *chan, char dir, uint64_t adj); /* Notify scheduler that a channel's queue position may have changed */ void scheduler_touch_channel(channel_t *chan);
+/* Adjust the watermarks from config file*/ +void scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush); + /* Things only scheduler.c and its test suite should see */
#ifdef SCHEDULER_PRIVATE_