X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Flpar.c;h=4d534476f62c76754433b2c73d313967595e5843;hb=584b130e51fc0e8214c8b4499b404e8728356fd9;hp=562d2d4e86c829c1728fc60f93d2b48aff0e8f08;hpb=7134cf10f759b177fa0410dcc9caeaaf09dd0336;p=collectd.git diff --git a/src/lpar.c b/src/lpar.c index 562d2d4e..4d534476 100644 --- a/src/lpar.c +++ b/src/lpar.c @@ -34,7 +34,7 @@ (double)(_system_configuration.Xfrac)) #endif -#define NS_TO_TICKS(ns) ((ns) / XINTFRAC) +#define CLOCKTICKS_TO_TICKS(cticks) ((cticks) / XINTFRAC) static const char *config_keys[] = { @@ -45,45 +45,12 @@ static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static _Bool pool_stats = 0; static _Bool report_by_serial = 0; +#if PERFSTAT_SUPPORTS_DONATION static _Bool donate_flag = 0; +#endif static char serial[SYS_NMLN]; -static u_longlong_t time_old; -static u_longlong_t user_old, - syst_old, - idle_old, - wait_old; -static u_longlong_t pool_busy_time_old, - pool_max_time_old; -static u_longlong_t idle_donated_old, - busy_donated_old, - busy_stolen_old, - idle_stolen_old; - - -static void save_last_values (perfstat_partition_total_t *lparstats) -{ - time_old = lparstats->timebase_last; - - user_old = lparstats->puser; - syst_old = lparstats->psys; - idle_old = lparstats->pidle; - wait_old = lparstats->pwait; - - if (donate_flag) - { - idle_donated_old = lparstats->idle_donated_purr; - busy_donated_old = lparstats->busy_donated_purr; - busy_stolen_old = lparstats->busy_stolen_purr; - idle_stolen_old = lparstats->idle_stolen_purr; - } - - if (pool_stats) - { - pool_busy_time_old = lparstats->pool_busy_time; - pool_max_time_old = lparstats->pool_max_time; - } -} /* void save_last_values */ +static perfstat_partition_total_t lparstats_old; static int lpar_config (const char *key, const char *value) { @@ -111,12 +78,11 @@ static int lpar_config (const char *key, const char *value) static int lpar_init (void) { - perfstat_partition_total_t lparstats; int status; /* Retrieve the initial metrics. Returns the number of structures filled. */ status = perfstat_partition_total (/* name = */ NULL, /* (must be NULL) */ - &lparstats, sizeof (perfstat_partition_total_t), + &lparstats_old, sizeof (perfstat_partition_total_t), /* number = */ 1 /* (must be 1) */); if (status != 1) { @@ -127,21 +93,21 @@ static int lpar_init (void) return (-1); } - if (!lparstats.type.b.shared_enabled && lparstats.type.b.donate_enabled) +#if PERFSTAT_SUPPORTS_DONATION + if (!lparstats_old.type.b.shared_enabled + && lparstats_old.type.b.donate_enabled) { donate_flag = 1; } +#endif - if (pool_stats && !lparstats.type.b.pool_util_authority) + if (pool_stats && !lparstats_old.type.b.pool_util_authority) { WARNING ("lpar plugin: This partition does not have pool authority. " "Disabling CPU pool statistics collection."); pool_stats = 0; } - /* Save the initial data */ - save_last_values (&lparstats); - return (0); } /* int lpar_init */ @@ -204,10 +170,11 @@ static int lpar_read (void) } /* Number of ticks since we last run. */ - ticks = lparstats.timebase_last - time_old; + ticks = lparstats.timebase_last - lparstats_old.timebase_last; if (ticks == 0) { - /* The stats have not been updated. Return now to avoid dividing by zero */ + /* The stats have not been updated. Return now to avoid + * dividing by zero */ return (0); } @@ -217,6 +184,10 @@ static int lpar_read (void) * capacity not used by the partition may be assigned to a different * partition by the hypervisor, so "idle" is hopefully a very small * number. + * + * A dedicated partition may donate its CPUs to another partition and + * may steal ticks from somewhere else (another partition or maybe the + * shared pool, I don't know --octo). */ /* entitled_proc_capacity is in 1/100th of a CPU */ @@ -224,31 +195,32 @@ static int lpar_read (void) lpar_submit ("entitled", entitled_proc_capacity); /* The number of ticks actually spent in the various states */ - user_ticks = lparstats.puser - user_old; - syst_ticks = lparstats.psys - syst_old; - wait_ticks = lparstats.pwait - wait_old; - idle_ticks = lparstats.pidle - idle_old; + user_ticks = lparstats.puser - lparstats_old.puser; + syst_ticks = lparstats.psys - lparstats_old.psys; + wait_ticks = lparstats.pwait - lparstats_old.pwait; + idle_ticks = lparstats.pidle - lparstats_old.pidle; consumed_ticks = user_ticks + syst_ticks + wait_ticks + idle_ticks; lpar_submit ("user", (double) user_ticks / (double) ticks); - lpar_submit ("sys", (double) syst_ticks / (double) ticks); + lpar_submit ("system", (double) syst_ticks / (double) ticks); lpar_submit ("wait", (double) wait_ticks / (double) ticks); lpar_submit ("idle", (double) idle_ticks / (double) ticks); +#if PERFSTAT_SUPPORTS_DONATION if (donate_flag) { + /* donated => ticks given to another partition + * stolen => ticks received from another partition */ u_longlong_t idle_donated_ticks, busy_donated_ticks; u_longlong_t idle_stolen_ticks, busy_stolen_ticks; - idle_donated_ticks = lparstats.idle_donated_purr - idle_donated_old; - busy_donated_ticks = lparstats.busy_donated_purr - busy_donated_old; - idle_stolen_ticks = lparstats.idle_stolen_purr - idle_stolen_old; - busy_stolen_ticks = lparstats.busy_stolen_purr - busy_stolen_old; - /* FYI: PURR == Processor Utilization of Resources Register * SPURR == Scaled PURR */ - /* donated => ticks given to another partition - * stolen => ticks received from another partition */ + idle_donated_ticks = lparstats.idle_donated_purr - lparstats_old.idle_donated_purr; + busy_donated_ticks = lparstats.busy_donated_purr - lparstats_old.busy_donated_purr; + idle_stolen_ticks = lparstats.idle_stolen_purr - lparstats_old.idle_stolen_purr; + busy_stolen_ticks = lparstats.busy_stolen_purr - lparstats_old.busy_stolen_purr; + lpar_submit ("idle_donated", (double) idle_donated_ticks / (double) ticks); lpar_submit ("busy_donated", (double) busy_donated_ticks / (double) ticks); lpar_submit ("idle_stolen", (double) idle_stolen_ticks / (double) ticks); @@ -257,26 +229,34 @@ static int lpar_read (void) /* Donated ticks will be accounted for as stolen ticks in other LPARs */ consumed_ticks += idle_stolen_ticks + busy_stolen_ticks; } +#endif lpar_submit ("consumed", (double) consumed_ticks / (double) ticks); if (pool_stats) { char typinst[DATA_MAX_NAME_LEN]; - u_longlong_t pool_busy_ns, pool_max_ns; - - pool_busy_ns = lparstats.pool_busy_time - pool_busy_time_old; - pool_max_ns = lparstats.pool_max_time - pool_max_time_old; + u_longlong_t pool_idle_cticks; + double pool_idle_cpus; + double pool_busy_cpus; + + /* We're calculating "busy" from "idle" and the total number of + * CPUs, because the "busy" member didn't exist in early versions + * of libperfstat. It was added somewhere between AIX 5.3 ML5 and ML9. */ + pool_idle_cticks = lparstats.pool_idle_time - lparstats_old.pool_idle_time; + pool_idle_cpus = CLOCKTICKS_TO_TICKS ((double) pool_idle_cticks) / (double) ticks; + pool_busy_cpus = ((double) lparstats.phys_cpus_pool) - pool_idle_cpus; + if (pool_busy_cpus < 0.0) + pool_busy_cpus = 0.0; - /* Pool stats are in CPU x ns */ ssnprintf (typinst, sizeof (typinst), "pool-%X-busy", lparstats.pool_id); - lpar_submit (typinst, NS_TO_TICKS ((double) pool_busy_ns) / (double) ticks); + lpar_submit (typinst, pool_busy_cpus); - ssnprintf (typinst, sizeof (typinst), "pool-%X-total", lparstats.pool_id); - lpar_submit (typinst, NS_TO_TICKS ((double) pool_max_ns) / (double) ticks); + ssnprintf (typinst, sizeof (typinst), "pool-%X-idle", lparstats.pool_id); + lpar_submit (typinst, pool_idle_cpus); } - save_last_values (&lparstats); + memcpy (&lparstats_old, &lparstats, sizeof (lparstats_old)); return (0); } /* int lpar_read */