Commit 12b6c7df authored by Andrea Shepard's avatar Andrea Shepard
Browse files

Make queue thresholds and flush size for global scheduler into config options

parent a28cfa12
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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");
+13 −0
Original line number Diff line number Diff line
@@ -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. */
+29 −9
Original line number Diff line number Diff line
@@ -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;
}
+3 −0
Original line number Diff line number Diff line
@@ -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_