debuggers.hg

changeset 22661:00fc33d9f691

credit2: Calculate load average

Calculate a per-runqueue decaying load average.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
author Keir Fraser <keir@xen.org>
date Fri Dec 24 08:29:53 2010 +0000 (2010-12-24)
parents 597e3fee23bc
children cf1ea603b340
files xen/common/sched_credit2.c
line diff
     1.1 --- a/xen/common/sched_credit2.c	Fri Dec 24 08:29:27 2010 +0000
     1.2 +++ b/xen/common/sched_credit2.c	Fri Dec 24 08:29:53 2010 +0000
     1.3 @@ -175,6 +175,18 @@ integer_param("sched_credit2_migrate_res
     1.4  #define RQD(_ops, _cpu)     (&CSCHED_PRIV(_ops)->rqd[c2r(_ops, _cpu)])
     1.5  
     1.6  /*
     1.7 + * Shifts for load average.
     1.8 + * - granularity: Reduce granularity of time by a factor of 1000, so we can use 32-bit maths
     1.9 + * - window shift: Given granularity shift, make the window about 1 second
    1.10 + * - scale shift: Shift up load by this amount rather than using fractions; 128 corresponds 
    1.11 + *   to a load of 1.
    1.12 + */
    1.13 +#define LOADAVG_GRANULARITY_SHIFT (10)
    1.14 +int opt_load_window_shift=18;
    1.15 +#define  LOADAVG_WINDOW_SHIFT_MIN 4
    1.16 +integer_param("credit2_load_window_shift", opt_load_window_shift);
    1.17 +
    1.18 +/*
    1.19   * Per-runqueue data
    1.20   */
    1.21  struct csched_runqueue_data {
    1.22 @@ -190,6 +202,8 @@ struct csched_runqueue_data {
    1.23      cpumask_t idle,        /* Currently idle */
    1.24          tickled;           /* Another cpu in the queue is already targeted for this one */
    1.25      int load;              /* Instantaneous load: Length of queue  + num non-idle threads */
    1.26 +    s_time_t load_last_update;  /* Last time average was updated */
    1.27 +    s_time_t avgload;           /* Decaying queue load */
    1.28  };
    1.29  
    1.30  /*
    1.31 @@ -204,6 +218,8 @@ struct csched_private {
    1.32      int runq_map[NR_CPUS];
    1.33      cpumask_t active_queues; /* Queues which may have active cpus */
    1.34      struct csched_runqueue_data rqd[NR_CPUS];
    1.35 +
    1.36 +    int load_window_shift;
    1.37  };
    1.38  
    1.39  /*
    1.40 @@ -273,13 +289,34 @@ static void
    1.41  update_load(const struct scheduler *ops,
    1.42              struct csched_runqueue_data *rqd, int change, s_time_t now)
    1.43  {
    1.44 +    struct csched_private *prv = CSCHED_PRIV(ops);
    1.45 +    s_time_t delta=-1;
    1.46 +
    1.47 +    now >>= LOADAVG_GRANULARITY_SHIFT;
    1.48 +
    1.49 +    if ( rqd->load_last_update + (1ULL<<prv->load_window_shift) < now )
    1.50 +    {
    1.51 +        rqd->avgload = rqd->load << (1ULL<prv->load_window_shift);
    1.52 +    }
    1.53 +    else
    1.54 +    {
    1.55 +        delta = now - rqd->load_last_update;
    1.56 +
    1.57 +        rqd->avgload =
    1.58 +            ( ( delta * ( (unsigned long long)rqd->load << prv->load_window_shift ) )
    1.59 +              + ( ((1ULL<<prv->load_window_shift) - delta) * rqd->avgload ) ) >> prv->load_window_shift;
    1.60 +    }
    1.61 +
    1.62      rqd->load += change;
    1.63 -
    1.64 +    rqd->load_last_update = now;
    1.65      {
    1.66          struct {
    1.67 -            unsigned load:4;
    1.68 +            unsigned load:4, avgload:28;
    1.69 +            int delta;
    1.70          } d;
    1.71          d.load = rqd->load;
    1.72 +        d.avgload = rqd->avgload;
    1.73 +        d.delta = delta;
    1.74          trace_var(TRC_CSCHED2_UPDATE_LOAD, 0,
    1.75                    sizeof(d),
    1.76                    (unsigned char *)&d);
    1.77 @@ -1610,6 +1647,15 @@ csched_init(struct scheduler *ops)
    1.78             " WARNING: This is experimental software in development.\n" \
    1.79             " Use at your own risk.\n");
    1.80  
    1.81 +    printk(" load_window_shift: %d\n", opt_load_window_shift);
    1.82 +
    1.83 +    if ( opt_load_window_shift < LOADAVG_WINDOW_SHIFT_MIN )
    1.84 +    {
    1.85 +        printk("%s: opt_load_window_shift %d below min %d, resetting\n",
    1.86 +               __func__, opt_load_window_shift, LOADAVG_WINDOW_SHIFT_MIN);
    1.87 +        opt_load_window_shift = LOADAVG_WINDOW_SHIFT_MIN;
    1.88 +    }
    1.89 +
    1.90      /* Basically no CPU information is available at this point; just
    1.91       * set up basic structures, and a callback when the CPU info is
    1.92       * available. */
    1.93 @@ -1631,6 +1677,8 @@ csched_init(struct scheduler *ops)
    1.94          prv->rqd[i].id = -1;
    1.95      }
    1.96  
    1.97 +    prv->load_window_shift = opt_load_window_shift;
    1.98 +
    1.99      return 0;
   1.100  }
   1.101