[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 2/2] x86/idle: update to include further package/core residency MSRs



On Mon, 2014-03-17 at 13:39 +0000, Jan Beulich wrote:
> With the number of these growing it becomes increasingly desirable to
> not repeatedly alter the sysctl interface to accommodate them. Replace
> the explicit listing of numbered states by arrays, unused fields of
> which will remain untouched by the hypercall.
> 
> The adjusted sysctl interface at once fixes an unrelated shortcoming
> of the original one: The "nr" field, specifying the size of the
> "triggers" and "residencies" arrays, has to be an input (along with
> being an output), which the previous implementation didn't obey to.
> 
> Note that the bouncing direction in the libxc interface at once gets
> corrected to OUT (was BOTH).
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
> Acked-by: Keir Fraser <keir@xxxxxxx>

Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

I assume you will apply.

> ---
> v2: Fully replace old interface and merge in previously separate patch
>     adjusting xenpm.c. Use calloc() for array allocations in xenpm.c.
> 
> --- 2014-03-17.orig/tools/libxc/xc_pm.c       2014-03-17 08:16:19.000000000 
> +0100
> +++ 2014-03-17/tools/libxc/xc_pm.c    2014-03-17 12:19:38.000000000 +0100
> @@ -123,45 +123,53 @@ int xc_pm_get_max_cx(xc_interface *xch, 
>  int xc_pm_get_cxstat(xc_interface *xch, int cpuid, struct xc_cx_stat *cxpt)
>  {
>      DECLARE_SYSCTL;
> -    DECLARE_NAMED_HYPERCALL_BOUNCE(triggers, cxpt->triggers, 0, 
> XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
> -    DECLARE_NAMED_HYPERCALL_BOUNCE(residencies, cxpt->residencies, 0, 
> XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
> -    int max_cx, ret;
> +    DECLARE_NAMED_HYPERCALL_BOUNCE(triggers, cxpt->triggers,
> +                                   cxpt->nr * sizeof(*cxpt->triggers),
> +                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
> +    DECLARE_NAMED_HYPERCALL_BOUNCE(residencies, cxpt->residencies,
> +                                   cxpt->nr * sizeof(*cxpt->residencies),
> +                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
> +    DECLARE_NAMED_HYPERCALL_BOUNCE(pc, cxpt->pc,
> +                                   cxpt->nr_pc * sizeof(*cxpt->pc),
> +                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
> +    DECLARE_NAMED_HYPERCALL_BOUNCE(cc, cxpt->cc,
> +                                   cxpt->nr_cc * sizeof(*cxpt->cc),
> +                                   XC_HYPERCALL_BUFFER_BOUNCE_OUT);
> +    int ret = -1;
>  
> -    if( !cxpt->triggers || !cxpt->residencies )
> -        return -EINVAL;
> -
> -    if ( (ret = xc_pm_get_max_cx(xch, cpuid, &max_cx)) )
> -        goto unlock_0;
> -
> -    HYPERCALL_BOUNCE_SET_SIZE(triggers, max_cx * sizeof(uint64_t));
> -    HYPERCALL_BOUNCE_SET_SIZE(residencies, max_cx * sizeof(uint64_t));
> -
> -    ret = -1;
>      if ( xc_hypercall_bounce_pre(xch, triggers) )
>          goto unlock_0;
>      if ( xc_hypercall_bounce_pre(xch, residencies) )
>          goto unlock_1;
> +    if ( xc_hypercall_bounce_pre(xch, pc) )
> +        goto unlock_2;
> +    if ( xc_hypercall_bounce_pre(xch, cc) )
> +        goto unlock_3;
>  
>      sysctl.cmd = XEN_SYSCTL_get_pmstat;
>      sysctl.u.get_pmstat.type = PMSTAT_get_cxstat;
>      sysctl.u.get_pmstat.cpuid = cpuid;
> +    sysctl.u.get_pmstat.u.getcx.nr = cxpt->nr;
> +    sysctl.u.get_pmstat.u.getcx.nr_pc = cxpt->nr_pc;
> +    sysctl.u.get_pmstat.u.getcx.nr_cc = cxpt->nr_cc;
>      set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.triggers, triggers);
>      set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.residencies, 
> residencies);
> +    set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.pc, pc);
> +    set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.cc, cc);
>  
>      if ( (ret = xc_sysctl(xch, &sysctl)) )
> -        goto unlock_2;
> +        goto unlock_4;
>  
>      cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr;
>      cxpt->last = sysctl.u.get_pmstat.u.getcx.last;
>      cxpt->idle_time = sysctl.u.get_pmstat.u.getcx.idle_time;
> -    cxpt->pc2 = sysctl.u.get_pmstat.u.getcx.pc2;
> -    cxpt->pc3 = sysctl.u.get_pmstat.u.getcx.pc3;
> -    cxpt->pc6 = sysctl.u.get_pmstat.u.getcx.pc6;
> -    cxpt->pc7 = sysctl.u.get_pmstat.u.getcx.pc7;
> -    cxpt->cc3 = sysctl.u.get_pmstat.u.getcx.cc3;
> -    cxpt->cc6 = sysctl.u.get_pmstat.u.getcx.cc6;
> -    cxpt->cc7 = sysctl.u.get_pmstat.u.getcx.cc7;
> +    cxpt->nr_pc = sysctl.u.get_pmstat.u.getcx.nr_pc;
> +    cxpt->nr_cc = sysctl.u.get_pmstat.u.getcx.nr_cc;
>  
> +unlock_4:
> +    xc_hypercall_bounce_post(xch, cc);
> +unlock_3:
> +    xc_hypercall_bounce_post(xch, pc);
>  unlock_2:
>      xc_hypercall_bounce_post(xch, residencies);
>  unlock_1:
> --- 2014-03-17.orig/tools/libxc/xenctrl.h     2014-01-14 13:33:16.000000000 
> +0100
> +++ 2014-03-17/tools/libxc/xenctrl.h  2014-03-17 12:20:20.000000000 +0100
> @@ -1935,18 +1935,15 @@ int xc_pm_get_pxstat(xc_interface *xch, 
>  int xc_pm_reset_pxstat(xc_interface *xch, int cpuid);
>  
>  struct xc_cx_stat {
> -    uint32_t nr;    /* entry nr in triggers & residencies, including C0 */
> +    uint32_t nr;           /* entry nr in triggers[]/residencies[], incl C0 
> */
>      uint32_t last;         /* last Cx state */
>      uint64_t idle_time;    /* idle time from boot */
>      uint64_t *triggers;    /* Cx trigger counts */
>      uint64_t *residencies; /* Cx residencies */
> -    uint64_t pc2;
> -    uint64_t pc3;
> -    uint64_t pc6;
> -    uint64_t pc7;
> -    uint64_t cc3;
> -    uint64_t cc6;
> -    uint64_t cc7;
> +    uint32_t nr_pc;        /* entry nr in pc[] */
> +    uint32_t nr_cc;        /* entry nr in cc[] */
> +    uint64_t *pc;          /* 1-biased indexing (i.e. excl C0) */
> +    uint64_t *cc;          /* 1-biased indexing (i.e. excl C0) */
>  };
>  typedef struct xc_cx_stat xc_cx_stat_t;
>  
> --- 2014-03-17.orig/tools/misc/xenpm.c        2013-07-16 08:16:10.000000000 
> +0200
> +++ 2014-03-17/tools/misc/xenpm.c     2014-03-17 12:24:45.000000000 +0100
> @@ -29,6 +29,9 @@
>  #include <inttypes.h>
>  #include <sys/time.h>
>  
> +#define MAX_PKG_RESIDENCIES 12
> +#define MAX_CORE_RESIDENCIES 8
> +
>  #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
>  
>  static xc_interface *xc_handle;
> @@ -102,7 +105,7 @@ static void parse_cpuid_and_int(int argc
>  
>  static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
>  {
> -    int i;
> +    unsigned int i;
>  
>      printf("cpu id               : %d\n", cpuid);
>      printf("total C-states       : %d\n", cxstat->nr);
> @@ -115,17 +118,14 @@ static void print_cxstat(int cpuid, stru
>          printf("                       residency  [%20"PRIu64" ms]\n",
>                 cxstat->residencies[i]/1000000UL);
>      }
> -    printf("pc2                  : [%20"PRIu64" ms]\n"
> -           "pc3                  : [%20"PRIu64" ms]\n"
> -           "pc6                  : [%20"PRIu64" ms]\n"
> -           "pc7                  : [%20"PRIu64" ms]\n",
> -            cxstat->pc2/1000000UL, cxstat->pc3/1000000UL,
> -            cxstat->pc6/1000000UL, cxstat->pc7/1000000UL);
> -    printf("cc3                  : [%20"PRIu64" ms]\n"
> -           "cc6                  : [%20"PRIu64" ms]\n"
> -           "cc7                  : [%20"PRIu64" ms]\n",
> -            cxstat->cc3/1000000UL, cxstat->cc6/1000000UL,
> -            cxstat->cc7/1000000UL);
> +    for ( i = 0; i < MAX_PKG_RESIDENCIES && i < cxstat->nr_pc; ++i )
> +        if ( cxstat->pc[i] )
> +           printf("pc%d                  : [%20"PRIu64" ms]\n", i + 1,
> +                  cxstat->pc[i] / 1000000UL);
> +    for ( i = 0; i < MAX_CORE_RESIDENCIES && i < cxstat->nr_cc; ++i )
> +        if ( cxstat->cc[i] )
> +           printf("cc%d                  : [%20"PRIu64" ms]\n", i + 1,
> +                  cxstat->cc[i] / 1000000UL);
>      printf("\n");
>  }
>  
> @@ -145,24 +145,36 @@ static int get_cxstat_by_cpuid(xc_interf
>      if ( !max_cx_num )
>          return -ENODEV;
>  
> -    cxstat->triggers = malloc(max_cx_num * sizeof(uint64_t));
> -    if ( !cxstat->triggers )
> -        return -ENOMEM;
> -    cxstat->residencies = malloc(max_cx_num * sizeof(uint64_t));
> -    if ( !cxstat->residencies )
> +    cxstat->triggers = calloc(max_cx_num, sizeof(*cxstat->triggers));
> +    cxstat->residencies = calloc(max_cx_num, sizeof(*cxstat->residencies));
> +    cxstat->pc = calloc(MAX_PKG_RESIDENCIES, sizeof(*cxstat->pc));
> +    cxstat->cc = calloc(MAX_CORE_RESIDENCIES, sizeof(*cxstat->cc));
> +    if ( !cxstat->triggers || !cxstat->residencies ||
> +         !cxstat->pc || !cxstat->cc )
>      {
> +        free(cxstat->cc);
> +        free(cxstat->pc);
> +        free(cxstat->residencies);
>          free(cxstat->triggers);
>          return -ENOMEM;
>      }
>  
> +    cxstat->nr = max_cx_num;
> +    cxstat->nr_pc = MAX_PKG_RESIDENCIES;
> +    cxstat->nr_cc = MAX_CORE_RESIDENCIES;
> +
>      ret = xc_pm_get_cxstat(xc_handle, cpuid, cxstat);
>      if( ret )
>      {
>          ret = -errno;
>          free(cxstat->triggers);
>          free(cxstat->residencies);
> +        free(cxstat->pc);
> +        free(cxstat->cc);
>          cxstat->triggers = NULL;
>          cxstat->residencies = NULL;
> +        cxstat->pc = NULL;
> +        cxstat->cc = NULL;
>      }
>  
>      return ret;
> @@ -198,6 +210,8 @@ static int show_cxstat_by_cpuid(xc_inter
>  
>      free(cxstatinfo.triggers);
>      free(cxstatinfo.residencies);
> +    free(cxstatinfo.pc);
> +    free(cxstatinfo.cc);
>      return 0;
>  }
>  
> @@ -482,25 +496,26 @@ static void signal_int_handler(int signo
>              /* print out CC? and PC? */
>              for ( i = 0; i < socket_nr; i++ )
>              {
> +                unsigned int n;
>                  uint64_t res;
> +
>                  for ( j = 0; j <= info.max_cpu_index; j++ )
>                  {
>                      if ( cpu_to_socket[j] == socket_ids[i] )
>                          break;
>                  }
>                  printf("\nSocket %d\n", socket_ids[i]);
> -                res = cxstat_end[j].pc2 - cxstat_start[j].pc2;
> -                printf("\tPC2\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL,
> -                       100UL * res / (double)sum_cx[j]);
> -                res = cxstat_end[j].pc3 - cxstat_start[j].pc3;
> -                printf("\tPC3\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
> -                       100UL * res / (double)sum_cx[j]);
> -                res = cxstat_end[j].pc6 - cxstat_start[j].pc6;
> -                printf("\tPC6\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
> -                       100UL * res / (double)sum_cx[j]);
> -                res = cxstat_end[j].pc7 - cxstat_start[j].pc7;
> -                printf("\tPC7\t%"PRIu64" ms\t%.2f%%\n",  res / 1000000UL, 
> -                       100UL * res / (double)sum_cx[j]);
> +                for ( n = 0; n < MAX_PKG_RESIDENCIES; ++n )
> +                {
> +                    if ( n >= cxstat_end[j].nr_pc )
> +                        continue;
> +                    res = cxstat_end[j].pc[n];
> +                    if ( n < cxstat_start[j].nr_pc )
> +                        res -= cxstat_start[j].pc[n];
> +                    printf("\tPC%u\t%"PRIu64" ms\t%.2f%%\n",
> +                           n + 1, res / 1000000UL,
> +                           100UL * res / (double)sum_cx[j]);
> +                }
>                  for ( k = 0; k < core_nr; k++ )
>                  {
>                      for ( j = 0; j <= info.max_cpu_index; j++ )
> @@ -510,15 +525,17 @@ static void signal_int_handler(int signo
>                              break;
>                      }
>                      printf("\t Core %d CPU %d\n", core_ids[k], j);
> -                    res = cxstat_end[j].cc3 - cxstat_start[j].cc3;
> -                    printf("\t\tCC3\t%"PRIu64" ms\t%.2f%%\n",  res / 
> 1000000UL, 
> -                           100UL * res / (double)sum_cx[j]);
> -                    res = cxstat_end[j].cc6 - cxstat_start[j].cc6;
> -                    printf("\t\tCC6\t%"PRIu64" ms\t%.2f%%\n",  res / 
> 1000000UL, 
> -                           100UL * res / (double)sum_cx[j]);
> -                    res = cxstat_end[j].cc7 - cxstat_start[j].cc7;
> -                    printf("\t\tCC7\t%"PRIu64" ms\t%.2f%%\n",  res / 
> 1000000UL,
> -                           100UL * res / (double)sum_cx[j]);
> +                    for ( n = 0; n < MAX_CORE_RESIDENCIES; ++n )
> +                    {
> +                        if ( n >= cxstat_end[j].nr_cc )
> +                            continue;
> +                        res = cxstat_end[j].cc[n];
> +                        if ( n < cxstat_start[j].nr_cc )
> +                            res -= cxstat_start[j].cc[n];
> +                        printf("\t\tCC%u\t%"PRIu64" ms\t%.2f%%\n",
> +                               n + 1, res / 1000000UL,
> +                               100UL * res / (double)sum_cx[j]);
> +                    }
>                  }
>              }
>          }
> @@ -529,6 +546,8 @@ static void signal_int_handler(int signo
>      {
>          free(cxstat[i].triggers);
>          free(cxstat[i].residencies);
> +        free(cxstat[i].pc);
> +        free(cxstat[i].cc);
>          free(pxstat[i].trans_pt);
>          free(pxstat[i].pt);
>      }
> --- 2014-03-17.orig/xen/arch/x86/acpi/cpu_idle.c      2014-03-05 
> 09:52:16.000000000 +0100
> +++ 2014-03-17/xen/arch/x86/acpi/cpu_idle.c   2014-03-04 17:38:39.000000000 
> +0100
> @@ -62,13 +62,17 @@
>  
>  #define GET_HW_RES_IN_NS(msr, val) \
>      do { rdmsrl(msr, val); val = tsc_ticks2ns(val); } while( 0 )
> -#define GET_PC2_RES(val)  GET_HW_RES_IN_NS(0x60D, val) /* SNB only */
> +#define GET_PC2_RES(val)  GET_HW_RES_IN_NS(0x60D, val) /* SNB onwards */
>  #define GET_PC3_RES(val)  GET_HW_RES_IN_NS(0x3F8, val)
>  #define GET_PC6_RES(val)  GET_HW_RES_IN_NS(0x3F9, val)
>  #define GET_PC7_RES(val)  GET_HW_RES_IN_NS(0x3FA, val)
> +#define GET_PC8_RES(val)  GET_HW_RES_IN_NS(0x630, val) /* some Haswells only 
> */
> +#define GET_PC9_RES(val)  GET_HW_RES_IN_NS(0x631, val) /* some Haswells only 
> */
> +#define GET_PC10_RES(val) GET_HW_RES_IN_NS(0x632, val) /* some Haswells only 
> */
> +#define GET_CC1_RES(val)  GET_HW_RES_IN_NS(0x660, val) /* Silvermont only */
>  #define GET_CC3_RES(val)  GET_HW_RES_IN_NS(0x3FC, val)
>  #define GET_CC6_RES(val)  GET_HW_RES_IN_NS(0x3FD, val)
> -#define GET_CC7_RES(val)  GET_HW_RES_IN_NS(0x3FE, val) /* SNB only */
> +#define GET_CC7_RES(val)  GET_HW_RES_IN_NS(0x3FE, val) /* SNB onwards */
>  
>  static void lapic_timer_nop(void) { }
>  void (*__read_mostly lapic_timer_off)(void);
> @@ -111,8 +115,13 @@ struct hw_residencies
>  {
>      uint64_t pc2;
>      uint64_t pc3;
> +    uint64_t pc4;
>      uint64_t pc6;
>      uint64_t pc7;
> +    uint64_t pc8;
> +    uint64_t pc9;
> +    uint64_t pc10;
> +    uint64_t cc1;
>      uint64_t cc3;
>      uint64_t cc6;
>      uint64_t cc7;
> @@ -128,6 +137,12 @@ static void do_get_hw_residencies(void *
>  
>      switch ( c->x86_model )
>      {
> +    /* 4th generation Intel Core (Haswell) */
> +    case 0x45:
> +        GET_PC8_RES(hw_res->pc8);
> +        GET_PC9_RES(hw_res->pc9);
> +        GET_PC10_RES(hw_res->pc10);
> +        /* fall through */
>      /* Sandy bridge */
>      case 0x2A:
>      case 0x2D:
> @@ -137,7 +152,6 @@ static void do_get_hw_residencies(void *
>      /* Haswell */
>      case 0x3C:
>      case 0x3F:
> -    case 0x45:
>      case 0x46:
>      /* future */
>      case 0x3D:
> @@ -160,6 +174,22 @@ static void do_get_hw_residencies(void *
>          GET_CC3_RES(hw_res->cc3);
>          GET_CC6_RES(hw_res->cc6);
>          break;
> +    /* various Atoms */
> +    case 0x27:
> +        GET_PC3_RES(hw_res->pc2); /* abusing GET_PC3_RES */
> +        GET_PC6_RES(hw_res->pc4); /* abusing GET_PC6_RES */
> +        GET_PC7_RES(hw_res->pc6); /* abusing GET_PC7_RES */
> +        break;
> +    /* Silvermont */
> +    case 0x37:
> +    case 0x4A:
> +    case 0x4D:
> +    case 0x5A:
> +    case 0x5D:
> +        GET_PC7_RES(hw_res->pc6); /* abusing GET_PC7_RES */
> +        GET_CC1_RES(hw_res->cc1);
> +        GET_CC6_RES(hw_res->cc6);
> +        break;
>      }
>  }
>  
> @@ -179,10 +209,16 @@ static void print_hw_residencies(uint32_
>  
>      get_hw_residencies(cpu, &hw_res);
>  
> -    printk("PC2[%"PRId64"] PC3[%"PRId64"] PC6[%"PRId64"] PC7[%"PRId64"]\n",
> -           hw_res.pc2, hw_res.pc3, hw_res.pc6, hw_res.pc7);
> -    printk("CC3[%"PRId64"] CC6[%"PRId64"] CC7[%"PRId64"]\n",
> -           hw_res.cc3, hw_res.cc6,hw_res.cc7);
> +    printk("PC2[%"PRIu64"] PC%d[%"PRIu64"] PC6[%"PRIu64"] PC7[%"PRIu64"]\n",
> +           hw_res.pc2,
> +           hw_res.pc4 ? 4 : 3, hw_res.pc4 ?: hw_res.pc3,
> +           hw_res.pc6, hw_res.pc7);
> +    if ( hw_res.pc8 | hw_res.pc9 | hw_res.pc10 )
> +        printk("PC8[%"PRIu64"] PC9[%"PRIu64"] PC10[%"PRIu64"]\n",
> +               hw_res.pc8, hw_res.pc9, hw_res.pc10);
> +    printk("CC%d[%"PRIu64"] CC6[%"PRIu64"] CC7[%"PRIu64"]\n",
> +           hw_res.cc1 ? 1 : 3, hw_res.cc1 ?: hw_res.cc3,
> +           hw_res.cc6, hw_res.cc7);
>  }
>  
>  static char* acpi_cstate_method_name[] =
> @@ -1097,19 +1133,21 @@ int pmstat_get_cx_stat(uint32_t cpuid, s
>      struct acpi_processor_power *power = processor_powers[cpuid];
>      uint64_t idle_usage = 0, idle_res = 0;
>      uint64_t usage[ACPI_PROCESSOR_MAX_POWER], res[ACPI_PROCESSOR_MAX_POWER];
> -    int i;
> -    struct hw_residencies hw_res;
> +    unsigned int i, nr, nr_pc = 0, nr_cc = 0;
>  
>      if ( power == NULL )
>      {
>          stat->last = 0;
>          stat->nr = 0;
>          stat->idle_time = 0;
> +        stat->nr_pc = 0;
> +        stat->nr_cc = 0;
>          return 0;
>      }
>  
>      stat->last = power->last_state ? power->last_state->idx : 0;
>      stat->idle_time = get_cpu_idle_time(cpuid);
> +    nr = min(stat->nr, power->count);
>  
>      /* mimic the stat when detail info hasn't been registered by dom0 */
>      if ( pm_idle_save == NULL )
> @@ -1118,14 +1156,14 @@ int pmstat_get_cx_stat(uint32_t cpuid, s
>  
>          usage[1] = idle_usage = 1;
>          res[1] = idle_res = stat->idle_time;
> -
> -        memset(&hw_res, 0, sizeof(hw_res));
>      }
>      else
>      {
> +        struct hw_residencies hw_res;
> +
>          stat->nr = power->count;
>  
> -        for ( i = 1; i < power->count; i++ )
> +        for ( i = 1; i < nr; i++ )
>          {
>              spin_lock_irq(&power->stat_lock);
>              usage[i] = power->states[i].usage;
> @@ -1137,22 +1175,42 @@ int pmstat_get_cx_stat(uint32_t cpuid, s
>          }
>  
>          get_hw_residencies(cpuid, &hw_res);
> +
> +#define PUT_xC(what, n) do { \
> +        if ( stat->nr_##what >= n && \
> +             copy_to_guest_offset(stat->what, n - 1, &hw_res.what##n, 1) ) \
> +            return -EFAULT; \
> +        if ( hw_res.what##n ) \
> +            nr_##what = n; \
> +    } while ( 0 )
> +#define PUT_PC(n) PUT_xC(pc, n)
> +        PUT_PC(2);
> +        PUT_PC(3);
> +        PUT_PC(4);
> +        PUT_PC(6);
> +        PUT_PC(7);
> +        PUT_PC(8);
> +        PUT_PC(9);
> +        PUT_PC(10);
> +#undef PUT_PC
> +#define PUT_CC(n) PUT_xC(cc, n)
> +        PUT_CC(1);
> +        PUT_CC(3);
> +        PUT_CC(6);
> +        PUT_CC(7);
> +#undef PUT_CC
> +#undef PUT_xC
>      }
>  
>      usage[0] = idle_usage;
>      res[0] = NOW() - idle_res;
>  
> -    if ( copy_to_guest(stat->triggers, usage, stat->nr) ||
> -         copy_to_guest(stat->residencies, res, stat->nr) )
> +    if ( copy_to_guest(stat->triggers, usage, nr) ||
> +         copy_to_guest(stat->residencies, res, nr) )
>          return -EFAULT;
>  
> -    stat->pc2 = hw_res.pc2;
> -    stat->pc3 = hw_res.pc3;
> -    stat->pc6 = hw_res.pc6;
> -    stat->pc7 = hw_res.pc7;
> -    stat->cc3 = hw_res.cc3;
> -    stat->cc6 = hw_res.cc6;
> -    stat->cc7 = hw_res.cc7;
> +    stat->nr_pc = nr_pc;
> +    stat->nr_cc = nr_cc;
>  
>      return 0;
>  }
> --- 2014-03-17.orig/xen/include/public/sysctl.h       2013-05-27 
> 09:58:49.000000000 +0200
> +++ 2014-03-17/xen/include/public/sysctl.h    2014-03-04 17:34:15.000000000 
> +0100
> @@ -34,7 +34,7 @@
>  #include "xen.h"
>  #include "domctl.h"
>  
> -#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000A
> +#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000B
>  
>  /*
>   * Read console content from Xen buffer ring.
> @@ -226,13 +226,10 @@ struct pm_cx_stat {
>      uint64_aligned_t idle_time;                 /* idle time from boot */
>      XEN_GUEST_HANDLE_64(uint64) triggers;    /* Cx trigger counts */
>      XEN_GUEST_HANDLE_64(uint64) residencies; /* Cx residencies */
> -    uint64_aligned_t pc2;
> -    uint64_aligned_t pc3;
> -    uint64_aligned_t pc6;
> -    uint64_aligned_t pc7;
> -    uint64_aligned_t cc3;
> -    uint64_aligned_t cc6;
> -    uint64_aligned_t cc7;
> +    uint32_t nr_pc;                          /* entry nr in pc[] */
> +    uint32_t nr_cc;                          /* entry nr in cc[] */
> +    XEN_GUEST_HANDLE_64(uint64) pc;          /* 1-biased indexing */
> +    XEN_GUEST_HANDLE_64(uint64) cc;          /* 1-biased indexing */
>  };
>  
>  struct xen_sysctl_get_pmstat {
> 
> 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.