You can subscribe to this list here.
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(14) |
Aug
(8) |
Sep
(14) |
Oct
(7) |
Nov
(9) |
Dec
(7) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
(11) |
Feb
(4) |
Mar
(6) |
Apr
(3) |
May
(7) |
Jun
(12) |
Jul
(4) |
Aug
(6) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(2) |
2011 |
Jan
(2) |
Feb
(3) |
Mar
(10) |
Apr
(7) |
May
(5) |
Jun
(3) |
Jul
(7) |
Aug
(6) |
Sep
(1) |
Oct
(1) |
Nov
(4) |
Dec
(6) |
2012 |
Jan
|
Feb
(4) |
Mar
(1) |
Apr
(2) |
May
(21) |
Jun
(6) |
Jul
(3) |
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(10) |
2013 |
Jan
(10) |
Feb
(8) |
Mar
|
Apr
(9) |
May
(33) |
Jun
(11) |
Jul
(16) |
Aug
(3) |
Sep
(8) |
Oct
(1) |
Nov
(16) |
Dec
(7) |
2014 |
Jan
(19) |
Feb
(71) |
Mar
(46) |
Apr
(16) |
May
(1) |
Jun
(18) |
Jul
(6) |
Aug
(12) |
Sep
(7) |
Oct
(4) |
Nov
(9) |
Dec
(7) |
2015 |
Jan
(15) |
Feb
(6) |
Mar
(10) |
Apr
(7) |
May
(16) |
Jun
(21) |
Jul
(6) |
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
2016 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2018 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Nathan F. <nf...@au...> - 2011-02-23 20:24:50
|
This patch is a pass at cleaning up the code to get rid of some of the warnings that are generated at build time. There are no functional changes as part of this patch. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/drmgr/common_cpu.c | 10 +++++----- src/drmgr/common_ofdt.c | 2 +- src/drmgr/common_pci.c | 16 ++++++++++------ src/drmgr/dr.h | 12 ++++++------ src/drmgr/drmgr.c | 2 +- src/drmgr/drmig_chrp_pmig.c | 2 +- src/drmgr/drslot_chrp_mem.c | 5 +++-- src/drmgr/ofdt.h | 4 ++-- src/lparstat.c | 28 ++++++++++++++++------------ src/ppc64_cpu.c | 3 ++- 10 files changed, 47 insertions(+), 37 deletions(-) Index: powerpc-utils/src/drmgr/ofdt.h =================================================================== --- powerpc-utils.orig/src/drmgr/ofdt.h 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/drmgr/ofdt.h 2011-02-23 10:14:37.000000000 -0600 @@ -132,8 +132,8 @@ set_drc_info(struct dr_node *node, struc node->drc_index = drc->index; node->drc_power = drc->powerdomain; - sprintf(node->drc_name, drc->name); - sprintf(node->drc_type, drc->type); + snprintf(node->drc_name, DR_STR_MAX, "%s", drc->name); + snprintf(node->drc_type, DR_STR_MAX, "%s", drc->type); } struct dr_connector *get_drc_info(const char *); Index: powerpc-utils/src/drmgr/dr.h =================================================================== --- powerpc-utils.orig/src/drmgr/dr.h 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/drmgr/dr.h 2011-02-23 11:55:02.000000000 -0600 @@ -34,7 +34,7 @@ static inline void dbg(char *fmt, ...) { va_list ap; char buf[256]; - int len; + int len, rc; va_start(ap, fmt); memset(buf, 0, 256); @@ -42,10 +42,10 @@ static inline void dbg(char *fmt, ...) va_end(ap); if (log_fd) - write(log_fd, buf, len); + rc = write(log_fd, buf, len); if (debug >= 4) - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); } @@ -53,7 +53,7 @@ static inline void err_msg(char *fmt, .. { va_list ap; char buf[256]; - int len; + int len, rc; va_start(ap, fmt); memset(buf, 0, 256); @@ -61,10 +61,10 @@ static inline void err_msg(char *fmt, .. len += vsnprintf(buf + len, 256 - len, fmt, ap); va_end(ap); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); if (log_fd) - write(log_fd, buf, len); + rc = write(log_fd, buf, len); } static inline int is_dot_dir(char * _p) Index: powerpc-utils/src/drmgr/common_cpu.c =================================================================== --- powerpc-utils.orig/src/drmgr/common_cpu.c 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/drmgr/common_cpu.c 2011-02-23 12:02:37.000000000 -0600 @@ -121,7 +121,7 @@ init_thread_info(struct dr_info *dr_info thread = zalloc(sizeof(*thread)); thread->id = i; - sprintf(thread->path, path); + snprintf(thread->path, DR_PATH_MAX, "%s", path); rc = get_int_attribute(thread->path, "physical_id", &thread->phys_id, @@ -194,7 +194,7 @@ cpu_index_to_path(struct dr_node *cpu) closedir(d); if (found) - sprintf(cpu->ofdt_path, path); + snprintf(cpu->ofdt_path, DR_PATH_MAX, "%s", path); return rc; } @@ -207,7 +207,7 @@ update_cpu_node(struct dr_node *cpu, con int rc; if (path) { - sprintf(cpu->ofdt_path, path); + snprintf(cpu->ofdt_path, DR_PATH_MAX, "%s", path); } else { rc = cpu_index_to_path(cpu); if (rc) { @@ -535,8 +535,8 @@ init_cache_info(struct dr_info *dr_info) return -1; } - sprintf(cache->name, ent->d_name); - sprintf(cache->path, path); + snprintf(cache->name, DR_BUF_SZ, "%s", ent->d_name); + snprintf(cache->path, DR_BUF_SZ, "%s", path); cache->removed = 0; cache->next = cache_list; Index: powerpc-utils/src/drmgr/common_ofdt.c =================================================================== --- powerpc-utils.orig/src/drmgr/common_ofdt.c 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/drmgr/common_ofdt.c 2011-02-23 12:03:24.000000000 -0600 @@ -243,7 +243,7 @@ get_drc_info(const char *of_path) rc = build_connectors_list(&prop_grp, n_drcs, list); - sprintf(list->ofdt_path, of_path); + snprintf(list->ofdt_path, DR_PATH_MAX, "%s", of_path); list->all_next = all_drc_lists; all_drc_lists = list; Index: powerpc-utils/src/drmgr/drmgr.c =================================================================== --- powerpc-utils.orig/src/drmgr/drmgr.c 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/drmgr/drmgr.c 2011-02-23 12:12:54.000000000 -0600 @@ -414,7 +414,7 @@ main(int argc, char *argv[]) for (i = 1; i < argc; i++) offset += sprintf(log_msg + offset, "%s ", argv[i]); log_msg[offset] = '\0'; - syslog(LOG_LOCAL0 | LOG_INFO, log_msg); + syslog(LOG_LOCAL0 | LOG_INFO, "%s", log_msg); dbg("%s\n", log_msg); Index: powerpc-utils/src/drmgr/drmig_chrp_pmig.c =================================================================== --- powerpc-utils.orig/src/drmgr/drmig_chrp_pmig.c 2011-02-23 12:14:17.000000000 -0600 +++ powerpc-utils/src/drmgr/drmig_chrp_pmig.c 2011-02-23 12:14:33.000000000 -0600 @@ -641,7 +641,7 @@ drmig_chrp_pmig(struct options *opts) devtree_update(); dbg("Refreshing RMC via refrsrc\n"); - system("/usr/sbin/rsct/bin/refrsrc IBM.ManagementServer"); + rc = system("/usr/sbin/rsct/bin/refrsrc IBM.ManagementServer"); return 0; } Index: powerpc-utils/src/drmgr/drslot_chrp_mem.c =================================================================== --- powerpc-utils.orig/src/drmgr/drslot_chrp_mem.c 2011-02-23 12:22:30.000000000 -0600 +++ powerpc-utils/src/drmgr/drslot_chrp_mem.c 2011-02-23 12:47:16.000000000 -0600 @@ -210,7 +210,7 @@ get_mem_node_lmbs(struct lmb_list_head * break; } - sprintf(lmb->ofdt_path, path); + snprintf(lmb->ofdt_path, DR_PATH_MAX, "%s", path); lmb->is_owned = 1; /* Find the lmb size for this lmb */ @@ -705,6 +705,7 @@ set_mem_scn_state(struct mem_scn *mem_sc int file; char path[DR_PATH_MAX]; int rc = 0; + int unused; memset(path, 0, DR_PATH_MAX); sprintf(path, "%s/state", mem_scn->sysfs_path); @@ -718,7 +719,7 @@ set_mem_scn_state(struct mem_scn *mem_sc return -1; } - write(file, state_strs[state], strlen(state_strs[state])); + unused = write(file, state_strs[state], strlen(state_strs[state])); close(file); if (get_mem_scn_state(mem_scn) != state) { Index: powerpc-utils/src/lparstat.c =================================================================== --- powerpc-utils.orig/src/lparstat.c 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/lparstat.c 2011-02-23 12:50:12.000000000 -0600 @@ -50,7 +50,7 @@ void get_sysdata(char *name, char **desc } else if (se->value[0] == '\0') { sprintf(value, SE_NOT_VALID); } else { - sprintf(value, se->value); + sprintf(value, "%s", se->value); } *descr = se->descr; @@ -99,7 +99,7 @@ int get_time_base() return -1; se = get_sysentry("timebase"); - sprintf(se->value, tb); + sprintf(se->value, "%s", tb); return 0; } @@ -127,6 +127,7 @@ int parse_lparcfg() { FILE *f; char line[128]; + char *unused; f = fopen(LPARCFG_FILE, "r"); if (!f) { @@ -135,7 +136,7 @@ int parse_lparcfg() } /* parse the file skipping the first line */ - fgets(line, 128, f); + unused = fgets(line, 128, f); while (fgets(line, 128, f) != NULL) { char *name, *value, *nl; struct sysentry *se; @@ -168,12 +169,13 @@ int parse_proc_stat() int i, entries = 6; long long statvals[entries]; struct sysentry *se; + char *unused; char *names[] = {"cpu_total", "cpu_user", "cpu_nice", "cpu_sys", "cpu_idle", "cpu_iowait"}; /* we just need the first line */ f = fopen("/proc/stat", "r"); - fgets(line, 128, f); + unused = fgets(line, 128, f); fclose(f); statvals[0] = 0; @@ -208,7 +210,7 @@ void get_smt_state(struct sysentry *se, else value = "Dedicated"; - sprintf(buf, value); + sprintf(buf, "%s", value); } void get_capped_mode(struct sysentry *se, char *buf) @@ -220,7 +222,7 @@ void get_capped_mode(struct sysentry *se else value = "Uncapped"; - sprintf(buf, value); + sprintf(buf, "%s", value); } void get_percent_entry(struct sysentry *se, char *buf) @@ -271,9 +273,10 @@ void get_name(const char *file, char *bu { FILE *f; char tmpbuf[64]; + int rc; f = fopen(file, "r"); - fread(tmpbuf, 64, 1, f); + rc = fread(tmpbuf, 64, 1, f); fclose(f); sprintf(buf, "%s", tmpbuf); @@ -301,10 +304,10 @@ void get_mem_total(struct sysentry *se, { FILE *f; char line[128]; - char *mem, *nl; + char *mem, *nl, *unused; f = fopen("/proc/meminfo", "r"); - fgets(line, 128, f); + unused = fgets(line, 128, f); fclose(f); mem = strchr(line, ':'); @@ -315,7 +318,7 @@ void get_mem_total(struct sysentry *se, nl = strchr(mem, '\n'); *nl = '\0'; - sprintf(buf, mem); + sprintf(buf, "%s", mem); } void get_smt_mode(struct sysentry *se, char *buf) @@ -323,9 +326,10 @@ void get_smt_mode(struct sysentry *se, c FILE *f; char line[128]; char *cmd = "/usr/sbin/ppc64_cpu --smt"; + char *unused; f = popen(cmd, "r"); - fgets(line, 128, f); + unused = fgets(line, 128, f); pclose(f); /* The output is either "SMT is on" or "SMT is off", we can cheat @@ -411,7 +415,7 @@ void print_default_output(int interval, char user[32], sys[32], wait[32], idle[32], physc[32], entc[32]; char lbusy[32], vcsw[32], phint[32]; - memset(buf, 128, 0); + memset(buf, 0, 128); get_sysdata("shared_processor_mode", &descr, value); offset = sprintf(buf, "type=%s ", value); get_sysdata("capped", &descr, value); Index: powerpc-utils/src/ppc64_cpu.c =================================================================== --- powerpc-utils.orig/src/ppc64_cpu.c 2011-02-23 09:18:47.000000000 -0600 +++ powerpc-utils/src/ppc64_cpu.c 2011-02-23 12:30:24.000000000 -0600 @@ -50,12 +50,13 @@ int threads_in_system = 0; int get_attribute(char *path, const char *fmt, int *value) { FILE *fp; + int rc; fp = fopen(path, "r"); if (fp == NULL) return -1; - fscanf(fp, fmt, value); + rc = fscanf(fp, fmt, value); fclose(fp); return 0; Index: powerpc-utils/src/drmgr/common_pci.c =================================================================== --- powerpc-utils.orig/src/drmgr/common_pci.c 2011-02-23 12:42:29.000000000 -0600 +++ powerpc-utils/src/drmgr/common_pci.c 2011-02-23 12:45:44.000000000 -0600 @@ -45,7 +45,7 @@ alloc_dr_node(struct dr_connector *drc, get_property(of_path, "ibm,loc-code", node->loc_code, sizeof(node->loc_code)); - sprintf(node->ofdt_path, of_path); + snprintf(node->ofdt_path, DR_PATH_MAX, "%s", of_path); } return node; @@ -268,7 +268,8 @@ add_child_node(struct dr_node *parent, c if ((! strcmp(parent->drc_type, "SLOT")) && (parent->dev_type == PCI_DLPAR_DEV)) - sprintf(child->ofdt_dname, parent->ofdt_dname); + snprintf(child->ofdt_dname, DR_STR_MAX, "%s", + parent->ofdt_dname); else get_property(child_path, "name", child->ofdt_dname, sizeof(child->ofdt_dname)); @@ -376,7 +377,8 @@ examine_child(struct dr_node *node, char if (! node->is_owned) { if (node->drc_index == my_drc_index) { /* Update node path */ - sprintf(node->ofdt_path, child_path); + snprintf(node->ofdt_path, DR_PATH_MAX, "%s", + child_path); node->is_owned = 1; used = 1; @@ -464,14 +466,15 @@ devspec_check_node(struct dr_node *node, return 0; if (! strcmp(full_of_path, node->ofdt_path)) { - sprintf(node->sysfs_dev_path, sysfs_path); + snprintf(node->sysfs_dev_path, DR_PATH_MAX, "%s", sysfs_path); *found = 1; return 0; } for (child = node->children; child; child = child->next) { if (! strcmp(full_of_path, child->ofdt_path)) { - sprintf(child->sysfs_dev_path, sysfs_path); + snprintf(child->sysfs_dev_path, DR_PATH_MAX, "%s", + sysfs_path); *found = 1; return 0; } @@ -765,7 +768,8 @@ update_phb_ic_info(struct dr_node *node_ for (node = node_list; node; node = node->next) { if ((node->dev_type == PHB_DEV) && (node->drc_index == my_drc_index)) { - sprintf(node->phb_ic_ofdt_path, ofdt_path); + snprintf(node->phb_ic_ofdt_path, DR_PATH_MAX, + "%s", ofdt_path); break; } } |
From: Nathan F. <nf...@au...> - 2011-02-23 20:23:00
|
On newer systems the preference is to have the libraries linked against specified last in the call to ld. The current setup of Makefiles causes the libraries to be listed towards the front of the ld command. The cause of this is that the current Makefile.am files use the XXX_LDFLAGS macro to specify the libraries to link with. Instead it should be using the XXX_LDADD macro. This patch corrects this. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/Makefile.am | 22 +++++++++++----------- src/drmgr/Makefile.am | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) Index: powerpc-utils/src/Makefile.am =================================================================== --- powerpc-utils.orig/src/Makefile.am 2011-02-23 09:20:50.000000000 -0600 +++ powerpc-utils/src/Makefile.am 2011-02-23 10:02:55.000000000 -0600 @@ -8,38 +8,38 @@ sbin_PROGRAMS = activate_firmware usysid nvram lsprop ppc64_cpu lparstat activate_firmware_SOURCES = activate_fw.c -activate_firmware_LDFLAGS = -lrtas +activate_firmware_LDADD = -lrtas usysident_SOURCES = usysident.c librtas_error.c librtas_error.h -usysident_LDFLAGS = -lrtas +usysident_LDADD = -lrtas usysattn_SOURCES = usysident.c librtas_error.c librtas_error.h -usysattn_LDFLAGS = -lrtas +usysattn_LDADD = -lrtas set_poweron_time_SOURCES = set_poweron_time.c librtas_error.c librtas_error.h -set_poweron_time_LDFLAGS = -lrtas +set_poweron_time_LDADD = -lrtas rtas_ibm_get_vpd_SOURCES = rtas_ibm_get_vpd.c librtas_error.c librtas_error.h -rtas_ibm_get_vpd_LDFLAGS = -lrtas +rtas_ibm_get_vpd_LDADD = -lrtas serv_config_SOURCES = serv_config.c librtas_error.c librtas_error.h -serv_config_LDFLAGS = -lrtas +serv_config_LDADD = -lrtas uesensor_SOURCES = uesensor.c librtas_error.c librtas_error.h -uesensor_LDFLAGS = -lrtas +uesensor_LDADD = -lrtas rtas_event_decode_SOURCES = rtas_event_decode.c -rtas_event_decode_LDFLAGS = -lrtasevent +rtas_event_decode_LDADD = -lrtasevent sys_ident_SOURCES = sys_ident.c -sys_ident_LDFLAGS = -lrtas +sys_ident_LDADD = -lrtas nvram_SOURCES = nvram.c nvram.h -nvram_LDFLAGS = -ldl +nvram_LDADD = -ldl lsprop_SOURCES = lsprop.c ppc64_cpu_SOURCES = ppc64_cpu.c librtas_error.c librtas_error.h -ppc64_cpu_LDFLAGS = -lrtas -lpthread +ppc64_cpu_LDADD = -lrtas -lpthread lparstat_SOURCES = lparstat.c lparstat.h Index: powerpc-utils/src/drmgr/Makefile.am =================================================================== --- powerpc-utils.orig/src/drmgr/Makefile.am 2011-02-23 09:20:50.000000000 -0600 +++ powerpc-utils/src/drmgr/Makefile.am 2011-02-23 09:21:20.000000000 -0600 @@ -1,5 +1,4 @@ AM_CFLAGS = -Wall -g -AM_LDFLAGS = -lrtas sbin_PROGRAMS = drmgr lsslot @@ -8,7 +7,9 @@ drmgr_SOURCES = common.c common_cpu.c co drslot_chrp_cpu.c drslot_chrp_hea.c drslot_chrp_mem.c \ drslot_chrp_pci.c drslot_chrp_phb.c drslot_chrp_slot.c \ ofdt.h rtas_calls.c rtas_calls.h +drmgr_LDADD = -lrtas lsslot_SOURCES = lsslot.c lsslot.h lsslot_chrp_cpu.c common.c \ common_cpu.c common_pci.c common_ofdt.c ofdt.h \ rtas_calls.c rtas_calls.h drslot_chrp_mem.c +lsslot_LDADD = -lrtas |
From: Nathan F. <nf...@au...> - 2011-02-23 20:16:25
|
Update the release m4_define in configure.ac for the 1.2.7 release. Signed-off-by: Nathan Fontenot <nf...@au...> --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: powerpc-utils/configure.ac =================================================================== --- powerpc-utils.orig/configure.ac 2011-02-23 12:55:15.000000000 -0600 +++ powerpc-utils/configure.ac 2011-02-23 12:55:25.000000000 -0600 @@ -1,6 +1,6 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -m4_define([ppu_version], 1.2.6) +m4_define([ppu_version], 1.2.7) AC_PREREQ([2.63]) AC_INIT([powerpc-utils], ppu_version, [nf...@au...]) |
From: Nathan F. <nf...@au...> - 2011-01-31 17:47:54
|
This patch updates the searching algorithm used for finding an available lmb to remove. The new algorithm will try to add lmbs starting from the lowest address of the first lmb that can be added, and remove lmbs from the highest addressed lmb that can be removed. Previously, removes were done on the lowest addressed lmb that could be removed. I think this update should help alleviate any possible fragmenting of the lmbs that can occur across multiple DLPAR add/remove operations. Signed-off-by: Nathan Fontenot <nf...@au...> --- diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c index 95cfab4..69a790e 100644 --- a/src/drmgr/drslot_chrp_mem.c +++ b/src/drmgr/drslot_chrp_mem.c @@ -423,6 +423,7 @@ static struct dr_node * get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) { struct dr_node *lmb; + struct dr_node *usable_lmb = NULL; int balloon_active = ams_balloon_active(); for (lmb = lmb_list->lmbs; lmb; lmb = lmb->next) { @@ -446,6 +447,8 @@ get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) rc = dr_entity_sense(lmb->drc_index); if (rc != STATE_UNUSABLE) continue; + + usable_lmb = lmb; break; case REMOVE: @@ -453,20 +456,22 @@ get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) if ((!balloon_active && !lmb->is_removable) || (!lmb->is_owned)) continue; - break; + + usable_lmb = lmb; + continue; } /* Found an available lmb */ break; } - if (lmb) + if (usable_lmb) dbg("Found available lmb, %s, drc index 0x%x\n", - lmb->drc_name, lmb->drc_index); + usable_lmb->drc_name, usable_lmb->drc_index); else dbg("Could not find available lmb\n"); - return lmb; + return usable_lmb; } /** |
From: Nathan F. <nf...@au...> - 2011-01-21 16:37:29
|
This is the initial checkin of the lparstat command code. The work for the first release of this command is not quite complete so this patch does not update the .spec file to install the command. I will submit a patch for that once work is complete for the initial release. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/Makefile.am | 3 src/Makefile.in | 18 +- src/lparstat.c | 479 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lparstat.h | 256 +++++++++++++++++++++++++++++ 4 files changed, 750 insertions(+), 6 deletions(-) Index: powerpc-utils/src/lparstat.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ powerpc-utils/src/lparstat.c 2011-01-21 08:59:53.000000000 -0600 @@ -0,0 +1,479 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <getopt.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include "lparstat.h" + +#define LPARCFG_FILE "/proc/ppc64/lparcfg" +#define SE_NOT_FOUND "???" +#define SE_NOT_VALID "-" + +struct sysentry *get_sysentry(char *name) +{ + struct sysentry *se = &system_data[0]; + + while (se->name[0] != '\0') { + if (!strcmp(se->name, name)) + return se; + se++; + } + + return NULL; +} + +void get_sysdata(char *name, char **descr, char *value) +{ + struct sysentry *se; + + se = get_sysentry(name); + if (!se) { + *descr = name; + sprintf(value, SE_NOT_FOUND); + return; + } + + if (se->get) { + se->get(se, value); + } else if (se->value[0] == '\0') { + sprintf(value, SE_NOT_VALID); + } else { + sprintf(value, se->value); + } + + *descr = se->descr; +} + +void get_time() +{ + struct timeval t; + struct sysentry *se; + + gettimeofday(&t, 0); + + se = get_sysentry("time"); + sprintf(se->value, "%ld", t.tv_sec + t.tv_usec); +} + +long long elapsed_time() +{ + long long newtime, oldtime = 0; + struct sysentry *se; + + se = get_sysentry("time"); + newtime = strtoll(se->value, NULL, 0); + oldtime = strtoll(se->old_value, NULL, 0); + + return newtime - oldtime; +} + +int get_time_base() +{ + FILE *f; + char buf[80]; + char *tb = NULL; + struct sysentry *se; + + f = fopen("/proc/cpuinfo", "r"); + while ((fgets(buf, 80, f)) != NULL) { + if (!strncmp(buf, "timebase", 8)) { + tb = strchr(buf, ':') + 2; + break; + } + } + fclose(f); + + if (!tb) + return -1; + + se = get_sysentry("timebase"); + sprintf(se->value, tb); + return 0; +} + +void get_cpu_physc(struct sysentry *unused_se, char *buf) +{ + struct sysentry *se; + float elapsed; + float new_purr, old_purr; + float timebase, physc; + + elapsed = elapsed_time(); + + se = get_sysentry("timebase"); + timebase = atoi(se->value); + + se = get_sysentry("purr"); + new_purr = strtoll(se->value, NULL, 0); + old_purr = strtoll(se->old_value, NULL, 0); + + physc = (new_purr - old_purr)/timebase/elapsed; + sprintf(buf, "%.2f", physc); +} + +int parse_lparcfg() +{ + FILE *f; + char line[128]; + + f = fopen(LPARCFG_FILE, "r"); + if (!f) { + fprintf(stderr, "Could not open %s\n", LPARCFG_FILE); + return -1; + } + + /* parse the file skipping the first line */ + fgets(line, 128, f); + while (fgets(line, 128, f) != NULL) { + char *name, *value, *nl; + struct sysentry *se; + + if (line[0] == '\n') + continue; + + name = &line[0]; + value = strchr(line, '='); + *value = '\0'; + value++; + + nl = strchr(value, '\n'); + *nl = '\0'; + + se = get_sysentry(name); + if (se) + strncpy(se->value, value, SYSDATA_VALUE_SZ); + } + + fclose(f); + return 0; +} + +int parse_proc_stat() +{ + FILE *f; + char line[128]; + char *value; + int i, entries = 6; + long long statvals[entries]; + struct sysentry *se; + char *names[] = {"cpu_total", "cpu_user", "cpu_nice", "cpu_sys", + "cpu_idle", "cpu_iowait"}; + + /* we just need the first line */ + f = fopen("/proc/stat", "r"); + fgets(line, 128, f); + fclose(f); + + statvals[0] = 0; + value = line; + for (i = 1; i <= entries; i++) { + int v; + value = strchr(value, ' ') + 1; + if (i == 1) + value++; + v = atoi(value); + statvals[i] = v; + statvals[0] += v; + } + + for (i = 0; i < entries; i++) { + se = get_sysentry(names[i]); + sprintf(se->value, "%lld", statvals[i]); + } + + se = get_sysentry("cpu_lbusy"); + sprintf(se->value, "%lld", statvals[1] + statvals[3]); + + return 0; +} + +void get_smt_state(struct sysentry *se, char *buf) +{ + char *value = "?"; + + if (se->value[0] == '1') + value = "Shared"; + else + value = "Dedicated"; + + sprintf(buf, value); +} + +void get_capped_mode(struct sysentry *se, char *buf) +{ + char *value = "?"; + + if (se->value[0] == '1') + value = "Capped"; + else + value = "Uncapped"; + + sprintf(buf, value); +} + +void get_percent_entry(struct sysentry *se, char *buf) +{ + int value, p, r; + + value = atoi(se->value); + p = value / 100; + r = value % 100; + + sprintf(buf, "%d.%d", p, r); +} + +void get_phys_cpu_percentage(struct sysentry *se, char *buf) +{ + struct sysentry *tmp_se; + int entcap, active; + + tmp_se = get_sysentry("DesEntCap"); + entcap = atoi(tmp_se->value); + + tmp_se = get_sysentry("partition_active_processors"); + active = atoi(tmp_se->value); + + sprintf(buf, "%d", entcap/active); +} + +void get_active_cpus_in_pool(struct sysentry *se, char *buf) +{ + struct sysentry *tmp; + + tmp = get_sysentry("pool_capacity"); + sprintf(buf, "%d", atoi(tmp->value)/100); +} + +void get_memory_mode(struct sysentry *se, char *buf) +{ + struct sysentry *tmp; + + tmp = get_sysentry("entitled_memory"); + if (tmp->value[0] == '\0') + sprintf(buf, "Dedicated"); + else + sprintf(buf, "Shared"); +} + +void get_name(const char *file, char *buf) +{ + FILE *f; + char tmpbuf[64]; + + f = fopen(file, "r"); + fread(tmpbuf, 64, 1, f); + fclose(f); + + sprintf(buf, "%s", tmpbuf); +} + +void get_node_name(struct sysentry *se, char *buf) +{ + char *nl; + + get_name("/proc/sys/kernel/hostname", buf); + + /* For some reason this doesn't get null-terminated and makes + * for ugly output. + */ + nl = strchr(buf, '\n'); + *nl = '\0'; +} + +void get_partition_name(struct sysentry *se, char *buf) +{ + return get_name("/proc/device-tree/ibm,partition-name", buf); +} + +void get_mem_total(struct sysentry *se, char *buf) +{ + FILE *f; + char line[128]; + char *mem, *nl; + + f = fopen("/proc/meminfo", "r"); + fgets(line, 128, f); + fclose(f); + + mem = strchr(line, ':'); + do { + mem++; + } while (*mem == ' '); + + nl = strchr(mem, '\n'); + *nl = '\0'; + + sprintf(buf, mem); +} + +void get_smt_mode(struct sysentry *se, char *buf) +{ + FILE *f; + char line[128]; + char *cmd = "/usr/sbin/ppc64_cpu --smt"; + + f = popen(cmd, "r"); + fgets(line, 128, f); + pclose(f); + + /* The output is either "SMT is on" or "SMT is off", we can cheat + * by looking at line[8] for either 'n' or 'f'. + */ + if (line[8] == 'n') + sprintf(buf, "On"); + else if (line[8] == 'f') + sprintf(buf, "Off"); + else + sprintf(buf, "Unknown"); +} + +long long get_cpu_time_diff() +{ + long long old_total = 0, new_total = 0; + struct sysentry *se; + + se = get_sysentry("cpu_total"); + new_total = strtoll(se->value, NULL, 0); + old_total = strtoll(se->old_value, NULL, 0); + + return new_total - old_total; +} + +void get_cpu_stat(struct sysentry *se, char *buf) +{ + float total, percent; + float old_val, new_val; + + total = get_cpu_time_diff(); + new_val = atoi(se->value); + old_val = atoi(se->old_value); + percent = (float)((new_val - old_val)/total) * 100; + sprintf(buf, "%.2f", percent); +} + +void init_sysdata(void) +{ + get_time(); + parse_lparcfg(); + parse_proc_stat(); + get_time_base(); +} + +void update_sysdata(void) +{ + struct sysentry *se = &system_data[0]; + while (se->name[0] != '\0') { + memcpy(se->old_value, se->value, SYSDATA_VALUE_SZ); + se++; + } + + init_sysdata(); +} + +int print_iflag_data() +{ + char *fmt = "%-45s: %s\n"; + char value[64]; + char *descr; + int i = 0; + + while (iflag_entries[i] != NULL) { + get_sysdata(iflag_entries[i], &descr, value); +#ifndef DEBUG + if (strcmp(value, SE_NOT_VALID) && strcmp(value, SE_NOT_FOUND)) +#endif + fprintf(stdout, fmt, descr, value); + i++; + } + + return 0; +} + +void print_default_output(int interval, int count) +{ + char *fmt = "%5s %5s %5s %5s %5s %5s %5s %5s %5s\n"; + char *descr; + char buf[128]; + int offset; + char value[32]; + char user[32], sys[32], wait[32], idle[32], physc[32], entc[32]; + char lbusy[32], vcsw[32], phint[32]; + + memset(buf, 128, 0); + get_sysdata("shared_processor_mode", &descr, value); + offset = sprintf(buf, "type=%s ", value); + get_sysdata("capped", &descr, value); + offset += sprintf(buf + offset, "mode=%s ", value); + get_sysdata("smt_state", &descr, value); + offset += sprintf(buf + offset, "smt=%s ", value); + get_sysdata("system_active_processors", &descr, value); + offset += sprintf(buf + offset, "lcpu=%s ", value); + get_sysdata("MemTotal", &descr, value); + offset += sprintf(buf + offset, "mem=%s ", value); + get_sysdata("active_cpus_in_pool", &descr, value); + offset += sprintf(buf + offset, "cpus=%s ", value); + get_sysdata("DesEntCap", &descr, value); + offset += sprintf(buf + offset, "ent=%s ", value); + + fprintf(stdout, "\nSystem Configuration\n%s\n\n", buf); + + fprintf(stdout, fmt, "\%user", "\%sys", "\%wait", "\%idle", "physc", + "\%entc", "lbusy", "vcsw", "phint"); + fprintf(stdout, fmt, "-----", "-----", "-----", "-----", "-----", + "-----", "-----", "-----", "-----"); + + do { + if (interval) { + sleep(interval); + update_sysdata(); + } + + get_sysdata("cpu_user", &descr, user); + get_sysdata("cpu_sys", &descr, sys); + get_sysdata("cpu_iowait", &descr, wait); + get_sysdata("cpu_idle", &descr, idle); + get_sysdata("cpu_lbusy", &descr, lbusy); + get_sysdata("dispatches", &descr, vcsw); + get_sysdata("physc", &descr, physc); + + fprintf(stdout, fmt, user, sys, wait, idle, physc, "XXX", + lbusy, vcsw, "XXX"); + } while (--count > 0); +} + +int main(int argc, char *argv[]) +{ + int interval = 0, count = 0; + int c; + int i_option = 0; + + while ((c = getopt(argc, argv, "i")) != -1) { + switch(c) { + case 'i': + i_option = 1; + break; + case '?': + default: + break; + } + } + + /* see if there is an interval specified */ + if (optind < argc) + interval = atoi(argv[optind++]); + + /* check for count specified */ + if (optind < argc) + count = atoi(argv[optind++]); + + init_sysdata(); + + if (i_option) + print_iflag_data(); + else + print_default_output(interval, count); + + return 0; +} Index: powerpc-utils/src/lparstat.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ powerpc-utils/src/lparstat.h 2011-01-21 08:59:57.000000000 -0600 @@ -0,0 +1,256 @@ +/* lparstat.h */ + +#define SYSDATA_VALUE_SZ 64 +#define SYSDATA_NAME_SZ 64 +#define SYSDATA_DESCR_SZ 128 + +struct sysentry { + char value[SYSDATA_VALUE_SZ]; /* value from file */ + char old_value[SYSDATA_VALUE_SZ]; /* previous value from file */ + char name[SYSDATA_NAME_SZ]; /* internal name */ + char descr[SYSDATA_DESCR_SZ]; /* description of data */ + void (*get)(struct sysentry *, char *); +}; + +extern void get_smt_state(struct sysentry *, char *); +extern void get_capped_mode(struct sysentry *, char *); +extern void get_memory_mode(struct sysentry *, char *); +extern void get_percent_entry(struct sysentry *, char *); +extern void get_phys_cpu_percentage(struct sysentry *, char *); +extern void get_active_cpus_in_pool(struct sysentry *, char *); +extern void get_partition_name(struct sysentry *, char *); +extern void get_node_name(struct sysentry *, char *); +extern void get_mem_total(struct sysentry *, char *); +extern void get_smt_mode(struct sysentry *, char *); +extern void get_cpu_stat(struct sysentry *, char *); +extern void get_cpu_physc(struct sysentry *, char *); + +struct sysentry system_data[] = { + /* System Names */ + {.name = "node_name", + .descr = "Node Name", + .get = &get_node_name}, + {.name = "partition_name", + .descr = "Partition Name", + .get = &get_partition_name}, + + /* lparcfg data */ + {.name = "serial_number", + .descr = "Serial Number"}, + {.name = "system_type", + .descr = "System Model"}, + {.name = "partition_id", + .descr = "Partition Number"}, + {.name = "group", + .descr = "Partition Group-ID"}, + {.name = "BoundThrds", + .descr = "Bound Threads"}, + {.name = "CapInc", + .descr = "Capacity Increment", + .get = &get_percent_entry}, + {.name = "DisWheRotPer", + .descr = "Dispatch Wheel Rotation Period"}, + {.name = "MinEntCap", + .descr = "Minimum Capacity", + .get = &get_percent_entry}, + {.name = "MinEntCapPerVP", + .descr = "Minimum Entitled Capacity per Virtual Processor"}, + {.name = "MinProcs", + .descr = "Minimum Virtual CPUs"}, + {.name = "partition_max_entitled_capacity", + .descr = "Maxiumum Capacity", + .get = &get_percent_entry}, + {.name = "system_potential_processors", + .descr = "Maximum System Processors"}, + {.name = "DesEntCap", + .descr = "Entitled Capacity", + .get = &get_percent_entry}, + {.name = "DesProcs", + .descr = "Desired Processors"}, + {.name = "DesVarCapWt", + .descr = "Desired Variable Capacity Weight"}, + {.name = "DedDonMode", + .descr = "Dedicated Donation Mode"}, + {.name = "partition_entitled_capcity", + .descr = "Partition Entitled Capacity"}, + {.name = "system_active_processors", + .descr = "Active Physical CPUs in system"}, + {.name = "pool", + .descr = "Shared Pool ID"}, + {.name = "pool_capacity", + .descr = "Maximum Capacity of Pool", + .get = &get_percent_entry}, + {.name = "pool_idle_time", + .descr = "Shared Processor Pool Idle Time"}, + {.name = "pool_num_procs", + .descr = "Shared Processor Pool Processors"}, + {.name = "unallocated_capacity_weight", + .descr = "Unallocated Weight"}, + {.name = "capacity_weight", + .descr = "Entitled Capacity of Pool"}, + {.name = "capped", + .descr = "Mode", + .get = &get_capped_mode}, + {.name = "unallocated_capacity", + .descr = "Unallocated Processor Capacity"}, + {.name = "physical_procs_allocated_to_virtualization", + .descr = "Physical Processor Allocated to Virtualization"}, + {.name = "max_proc_entitled_capacity", + .descr = "Maximum Processor Capacity Available to Pool"}, + {.name = "entitled_proc_capacity_available", + .descr = "Entitled Capacity of Pool"}, + {.name = "dispatches", + .descr = "Virtual Processor Dispatch Counter"}, + {.name = "dispatch_dispersions", + .descr = "Virtual Processor Dispersions"}, + {.name = "purr", + .descr = "Processor Utilization Resource Register"}, + {.name = "partition_active_processors", + .descr = "Online Virtual CPUs"}, + {.name = "partition_potential_processors", + .descr = "Maximum Virtual CPUs"}, + {.name = "shared_processor_mode", + .descr = "Type", + .get = &get_smt_state}, + {.name = "slb_size", + .descr = "SLB Entries"}, + {.name = "MinMem", + .descr = "Minimum Memory"}, + {.name = "DesMem", + .descr = "Desired Memory"}, + {.name = "entitled_memory", + .descr = "Total I/O Memory Entitlement"}, + {.name = "mapped_entitled_memory", + .descr = "Total I/O Mapped Entitled Memory"}, + {.name = "entitled_memory_group_number", + .descr = "Memory Group ID of LPAR"}, + {.name = "entitled_memory_pool_number", + .descr = "Memory Pool ID"}, + {.name = "entitled_memory_pool_size", + .descr = "Physical Memory in the Pool"}, + {.name = "entitled_memory_weight", + .descr = "Variable Memory Capacity Weight"}, + {.name = "unallocated_entitled_memory_weight", + .descr = "Unallocated Variable Memory Capacity Weight"}, + {.name = "unallocated_io_mapping_entitlement", + .descr = "Unallocated I/O Memory Entitlement"}, + {.name = "entitled_memory_loan_request", + .descr = "Entitled Memory Loan Request"}, + {.name = "backing_memory", + .descr = "Backing Memory"}, + {.name = "cmo_enabled", + .descr = "Active Memory Sharing Enabled"}, + {.name = "cmo_faults", + .descr = "Active Memory Sharing Page Faults"}, + {.name = "cmo_fault_time_usec", + .descr = "Active Memory Sharing Fault Time"}, + {.name = "cmo_primary_psp", + .descr = "Primary VIOS Partition ID"}, + {.name = "cmo_secondary_psp", + .descr = "Secondary VIOS Partition ID"}, + {.name = "cmo_page_size", + .descr = "Physical Page Size"}, + + /* /proc/meminfo */ + {.name = "MemTotal", + .descr = "Online Memory", + .get = &get_mem_total}, + + /* ppc64_cpu --smt */ + {.name = "smt_state", + .descr = "SMT", + .get = &get_smt_state}, + + /* /proc/stat */ + {.name = "cpu_total", + .descr = "CPU Total Time"}, + {.name = "cpu_user", + .descr = "CPU User Time", + .get = &get_cpu_stat}, + {.name = "cpu_nice", + .descr = "CPU Nice Time", + .get = &get_cpu_stat}, + {.name = "cpu_sys", + .descr = "CPU System Time", + .get = &get_cpu_stat}, + {.name = "cpu_idle", + .descr = "CPU Idle Time", + .get = &get_cpu_stat}, + {.name = "cpu_iowait", + .descr = "CPU I/O Wait Time", + .get = &get_cpu_stat}, + {.name = "cpu_lbusy", + .descr = "Logical CPU Utilization", + .get = &get_cpu_stat}, + + /* placeholders for derived values */ + {.name = "active_cpus_in_pool", + .descr = "Active CPUs in Pool", + .get = &get_active_cpus_in_pool}, + {.name = "phys_cpu_percentage", + .descr = "Physical CPU Percentage", + .get = &get_phys_cpu_percentage}, + {.name = "memory_mode", + .descr = "Memory Mode", + .get = &get_memory_mode}, + {.name = "physc", + .descr = "Physical CPU Consumed", + .get = &get_cpu_physc}, + + /* Time */ + {.name = "time", + .descr = "Time"}, + + /* /proc/cpuinfo */ + {.name = "timebase", + .descr = "Timebase"}, + + {.name[0] = '\0'}, +}; + +char *iflag_entries[] = { + "node_name", + "partition_name", + "partition_id", + "shared_processor_mode", + "capped", + "DesEntCap", + "group", + "pool", + "partition_active_processors", + "partition_potential_processors", + "MinProcs", + "MemTotal", + "MinMem", + "MaxMem", + "DesVarCapWt", + "MinEntCap", + "partition_max_entitled_capacity", + "CapInc", + "max_system_cpus", + "system_active_processors", + "active_cpus_in_pool", + "shared_cpus_in_system", + "pool_capacity", + "entitled_proc_capacity_available", + "unallocated_capacity", + "phys_cpu_percentage", + "unallocated_capacity_weight", + "memory_mode", + "entitled_memory", + "entitled_memory_weight", + "entitled_memory_pool_number", + "entitled_memory_pool_size", + "hypervisor_page_size", + "unallocated_entitled_memory_weight", + "unallocated_io_mapping_entitlement", + "entitled_memory_group_number", + "desired_virt_cpus", + "desired_memory", + "DesVarCapWt", + "desired_capacity", + "target_mem_factor", + "target_mem_size", + NULL +}; + Index: powerpc-utils/src/Makefile.am =================================================================== --- powerpc-utils.orig/src/Makefile.am 2011-01-21 09:02:45.000000000 -0600 +++ powerpc-utils/src/Makefile.am 2011-01-21 09:04:23.000000000 -0600 @@ -5,7 +5,7 @@ SUBDIRS = drmgr sbin_PROGRAMS = activate_firmware usysident usysattn set_poweron_time \ rtas_ibm_get_vpd serv_config uesensor rtas_event_decode sys_ident \ - nvram lsprop ppc64_cpu + nvram lsprop ppc64_cpu lparstat activate_firmware_SOURCES = activate_fw.c activate_firmware_LDFLAGS = -lrtas @@ -42,3 +42,4 @@ lsprop_SOURCES = lsprop.c ppc64_cpu_SOURCES = ppc64_cpu.c librtas_error.c librtas_error.h ppc64_cpu_LDFLAGS = -lrtas -lpthread +lparstat_SOURCES = lparstat.c lparstat.h Index: powerpc-utils/src/Makefile.in =================================================================== --- powerpc-utils.orig/src/Makefile.in 2011-01-21 09:03:19.000000000 -0600 +++ powerpc-utils/src/Makefile.in 2011-01-21 09:07:01.000000000 -0600 @@ -35,7 +35,7 @@ sbin_PROGRAMS = activate_firmware$(EXEEX rtas_ibm_get_vpd$(EXEEXT) serv_config$(EXEEXT) \ uesensor$(EXEEXT) rtas_event_decode$(EXEEXT) \ sys_ident$(EXEEXT) nvram$(EXEEXT) lsprop$(EXEEXT) \ - ppc64_cpu$(EXEEXT) + ppc64_cpu$(EXEEXT) lparstat$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -52,6 +52,9 @@ activate_firmware_OBJECTS = $(am_activat activate_firmware_LDADD = $(LDADD) activate_firmware_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(activate_firmware_LDFLAGS) $(LDFLAGS) -o $@ +am_lparstat_OBJECTS = lparstat.$(OBJEXT) +lparstat_OBJECTS = $(am_lparstat_OBJECTS) +lparstat_LDADD = $(LDADD) am_lsprop_OBJECTS = lsprop.$(OBJEXT) lsprop_OBJECTS = $(am_lsprop_OBJECTS) lsprop_LDADD = $(LDADD) @@ -114,14 +117,14 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUD $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(activate_firmware_SOURCES) $(lsprop_SOURCES) \ - $(nvram_SOURCES) $(ppc64_cpu_SOURCES) \ +SOURCES = $(activate_firmware_SOURCES) $(lparstat_SOURCES) \ + $(lsprop_SOURCES) $(nvram_SOURCES) $(ppc64_cpu_SOURCES) \ $(rtas_event_decode_SOURCES) $(rtas_ibm_get_vpd_SOURCES) \ $(serv_config_SOURCES) $(set_poweron_time_SOURCES) \ $(sys_ident_SOURCES) $(uesensor_SOURCES) $(usysattn_SOURCES) \ $(usysident_SOURCES) -DIST_SOURCES = $(activate_firmware_SOURCES) $(lsprop_SOURCES) \ - $(nvram_SOURCES) $(ppc64_cpu_SOURCES) \ +DIST_SOURCES = $(activate_firmware_SOURCES) $(lparstat_SOURCES) \ + $(lsprop_SOURCES) $(nvram_SOURCES) $(ppc64_cpu_SOURCES) \ $(rtas_event_decode_SOURCES) $(rtas_ibm_get_vpd_SOURCES) \ $(serv_config_SOURCES) $(set_poweron_time_SOURCES) \ $(sys_ident_SOURCES) $(uesensor_SOURCES) $(usysattn_SOURCES) \ @@ -250,6 +253,7 @@ nvram_LDFLAGS = -ldl lsprop_SOURCES = lsprop.c ppc64_cpu_SOURCES = ppc64_cpu.c librtas_error.c librtas_error.h ppc64_cpu_LDFLAGS = -lrtas -lpthread +lparstat_SOURCES = lparstat.c lparstat.h all: all-recursive .SUFFIXES: @@ -309,6 +313,9 @@ clean-sbinPROGRAMS: activate_firmware$(EXEEXT): $(activate_firmware_OBJECTS) $(activate_firmware_DEPENDENCIES) @rm -f activate_firmware$(EXEEXT) $(activate_firmware_LINK) $(activate_firmware_OBJECTS) $(activate_firmware_LDADD) $(LIBS) +lparstat$(EXEEXT): $(lparstat_OBJECTS) $(lparstat_DEPENDENCIES) + @rm -f lparstat$(EXEEXT) + $(LINK) $(lparstat_OBJECTS) $(lparstat_LDADD) $(LIBS) lsprop$(EXEEXT): $(lsprop_OBJECTS) $(lsprop_DEPENDENCIES) @rm -f lsprop$(EXEEXT) $(LINK) $(lsprop_OBJECTS) $(lsprop_LDADD) $(LIBS) @@ -351,6 +358,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/activate_fw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librtas_error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lparstat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsprop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nvram.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppc64_cpu.Po@am__quote@ |
From: Nathan F. <nf...@au...> - 2010-12-17 04:57:03
|
The latest version of powerpc-utils, version 1.2.6, has been posted to the sourceforge website. This version has all of the patches submitted to the mailing list in addition to a patch to revert powrepc-utils back to using automake 1.10. This should resolve build issues that have been seen on some distro installs. -Nathan |
From: Brian K. <br...@li...> - 2010-12-01 23:02:33
|
The /proc/ppc64/lparcfg file is cryptic and not well documented anywhere. Create a man page to document this for users. Signed-off-by: Brian King <br...@li...> --- man/Makefile.am | 4 man/Makefile.in | 4 man/lparcfg.5 | 334 ++++++++++++++++++++++++++++++++++++++++++++++++++ powerpc-utils.spec.in | 1 4 files changed, 339 insertions(+), 4 deletions(-) diff -puN man/Makefile.am~powerpc_utils_lparcfg man/Makefile.am --- powerpc-utils/man/Makefile.am~powerpc_utils_lparcfg 2010-12-01 11:23:45.000000000 -0600 +++ powerpc-utils-bjking1/man/Makefile.am 2010-12-01 11:23:45.000000000 -0600 @@ -2,11 +2,11 @@ man_MANS = activate_firmware.8 ibmvscsis uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 + hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 lparcfg.5 dist_man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 + hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 lparcfg.5 diff -puN man/Makefile.in~powerpc_utils_lparcfg man/Makefile.in --- powerpc-utils/man/Makefile.in~powerpc_utils_lparcfg 2010-12-01 11:23:45.000000000 -0600 +++ powerpc-utils-bjking1/man/Makefile.in 2010-12-01 11:23:45.000000000 -0600 @@ -166,13 +166,13 @@ man_MANS = activate_firmware.8 ibmvscsis uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 + hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 lparcfg.5 dist_man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 + hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 lparcfg.5 all: all-am diff -puN powerpc-utils.spec.in~powerpc_utils_lparcfg powerpc-utils.spec.in --- powerpc-utils/powerpc-utils.spec.in~powerpc_utils_lparcfg 2010-12-01 11:23:45.000000000 -0600 +++ powerpc-utils-bjking1/powerpc-utils.spec.in 2010-12-01 11:23:45.000000000 -0600 @@ -78,6 +78,7 @@ Utilities for maintaining and servicing /usr/share/man/man8/snap.8.gz /usr/share/man/man8/bootlist.8.gz /usr/share/man/man8/ofpathname.8.gz +/usr/share/man/man5/lparcfg.5.gz /usr/share/man/man1/amsstat.1.gz diff -puN /dev/null man/lparcfg.5 --- /dev/null 2009-12-15 17:58:07.000000000 -0600 +++ powerpc-utils-bjking1/man/lparcfg.5 2010-12-01 16:18:26.000000000 -0600 @@ -0,0 +1,334 @@ +.TH LPARCFG 5 "August 2010" +.SH NAME +/proc/ppc64/lparcfg - IBM Power LPAR Configuration Data +.SH SYNOPSIS +.BI "/proc/ppc64/lparcfg" +.sp +.BI "cat /proc/ppc64/lparcfg" +.SH DESCRIPTION +The +.B lparcfg +file is a virtual file which contains information +related to an IBM Power Logical Partition. +.SH OPTIONS +The fields displayed in the +.B lparcfg +file are sorted below according to the version of the +.B lparcfg +file. Generally, fields are only added and not removed (unless otherwise noted), so the latest version of +.B lparcfg +contains all fields in all previous versions of the file as well. +.PP +.B lparcfg 1.6 based values +.br +(Values added in lparcfg 1.7, 1.8, 1.9 are listed below) +.PP +.B serial_number +.br +The serial number of the physical system in which the partition resides +.PP +.B system_type +.br +The machine,type-model of the physical system in which the partition resides +.PP +.B partition_id +.br +The numeric partition ID. +.PP +.B R4 +.br +The hexadecimal representation of partition_entitled_capacity. This field is deprecated and not displayed on more recent versions of the Linux kernel ( +.B lparcfg 1.8 +or greater). The definition is only provided for historical purposes. +.PP +.B R5 +.br +The hexadecimal representation of unallocated_capacity. Not displayed on more recent versions of the Linux kernel. This field is deprecated and not displayed on more recent versions of the Linux kernel ( +.B lparcfg 1.8 +or greater). The definition is only provided for historical purposes. +.PP +.B R6 +.br +This is a hexadecimal value representing both the group and pool. This field is deprecated and not displayed on more recent versions of the Linux kernel ( +.B lparcfg 1.8 +or greater). The definition is only provided for historical purposes. +.PP +.B R7 +.br +This is a hexadecimal value representing capped, capacity_weight, unallocated_capacity_weight, pool_capacity, and system_active_processors. This field is deprecated and not displayed on more recent versions of the Linux kernel ( +.B lparcfg 1.8 +or greater). The definition is only provided for historical purposes. +.PP +.B BoundThrds +.br +For virtual processor dispatches, if the hypervisor always dispatches a set of virtual threads together on a physical processor, the threads are said to be bound. This allows an operating system to make scheduling decisions based on cache affinity and work load. Set to 1 if threads are bound, 0 otherwise. This value is informational and is not a tunable value. +.\" A change in this characteristic takes effect on the next reboot of the partition. +.PP +.B CapInc +.br +This defines the delta by which the entitled capacity of a partition can be incremented or decremented by DLPAR/WLM. The capacity increment is expressed as a percentage of a physical processor. This value is informational and is not a tunable value. +.\" A change in the capacity increment takes effect on the next reboot of the partition. This does not affect the number of virtual processors defined for the partition. +.PP +.B DisWheRotPer +.br +The duration of the hypervisor's scheduling window. The time over which the entitled capacity of a virtual processor has to be utilized by the partition. At the start of a dispatch wheel rotation period, each virtual processor is eligible for CPU time corresponding to its entitled capacity. If the entire entitled capacity of a virtual processor is not utilized during a dispatch wheel rotation period, the unused entitled capacity is lost. The dispatch wheel rotation period is expressed as N number of time base ticks. The dispatch wheel duration of a partition with a capacity increment of 100 is 0. This value is informational and is not a tunable value. +.PP +.B MinEntCap +.br +The minimum entitled capacity that is needed to boot the partition. The capacity is expressed as a percentage of a physical processor. The minimum entitled capacity is set by the system administrator in the partition definition. DLPAR cannot take the entitled capacity below the minimum entitled capacity. A change in the minimum entitled capacity takes effect on the next reboot of the partition. Linux running in a partition can give up its entitled capacity to be below the minimum entitled capacity, but this is generally not recommended. +.PP +.B MinEntCapPerVP +.br +The minimum entitled capacity that the platform requires for a virtual processor of any partition on the platform. The minimum capacity per virtual processor is enforced by the HMC in the partition definition and by the hypervisor. A change in the minimum entitled capacity per virtual processor takes effect on the next reboot of the partition. This is a physical system setting and is not considered a Linux partition tunable. +.PP +.B MinMem +.br +The minimum amount of main store that is needed to boot the partition. Minimum memory is expressed in MB of storage. The minimum memory is set by the system administrator in the partition definition. DLPAR cannot take the partition memory below the minimum memory. A change in the minimum memory takes effect on the next reboot of the partition. Linux running in a partition can always give up its memory to go below the minimum memory. +.PP +.B MinProcs +.br +The minimum number of virtual processors that are needed to boot the partition. The minimum number of virtual processors is set by the system administrator in the partition definition. DLPAR cannot take the number of virtual processors below the minimum number of processors. A change in the minimum number of processors takes effect on the next reboot of the partition. A partition can always give up its virtual processors to go below the minimum number of processors. The number of virtual processors is a simulated physical core view. Additional logical CPUs are defined in the Linux partition to account for the possible hardware threads. +.PP +.B partition_max_entitled_capacity +.br +The maximum entitled capacity currently that can be assigned to the partition through DLPAR/WLM. The capacity is expressed as a percentage of a physical processor. The Maximum entitled capacity is set up by the system administrator in the partition definition. A change in the maximum entitled capacity maximum takes effect on the next reboot of the partition. +.PP +.B system_potential_processors +.br +The maximum number of physical processors that can be active on the platform. A change in the maximum platform processors takes effect on the next reboot of the partition. +.PP +.B DesEntCap +.br +The desired entitled capacity is the number of processing units, expressed as a percentage of a physical processor, which is desired for a logical partition. The desired entitled capacity is the same as the desired processing units on the HMC. If the system has at least the desired number of processing units available when you activate the partition, then the system commits the desired number of processing units to the logical partition. If the desired number of processing units is not available, but at least the minimum number of processing units is available, then the system activates the logical partition with the processing units it has. +.PP +.B DesMem +.br +The desired memory set by the system administrator in the partition definition. The desired memory is expressed in MB of storage. The desired memory can change without a reboot of the partition. The desired memory that the partition is currently using may differ from the desired memory because of WLM actions or because of failed system memory. +.PP +.B DesProcs +.br +The desired number of virtual processors set by the system administrator in the partition definition. The desired number of processors can change without a reboot of the partition. The number of processors that the partition is currently using may differ from the desired number of processors because of WLM actions or because of failed system processors. +.PP +.B DesVarCapWt +.br +The desired variable capacity weight set by the system administrator in the partition definition. The desired variable capacity weight is a number between 0 and 255. The desired variable capacity weight can change without a reboot of the partition. The variable capacity weight that the partition is currently using may differ from the desired variable capacity because of WLM actions. +.PP +.B DedDonMode +.br +For a partition with a capacity increment of 100, the platform uses a dedicated CPU to actualize a virtual processor of the partition. For such a partition, the platform can increase the capacity of the shared processor pool by utilizing the unused processor capacity of the partition. If the platform supports the dedicated donate function, it can be enabled by the system administrator in the partition definition. The value of this characteristic can change without a reboot of the partition. The values for this field are 0 and 1. +.PP +.B partition_entitled_capacity +.br +Entitled Processor Capacity Percentage. The percentage of a physical processor that the hypervisor guarantees to be available to the partition's virtual processors (distributed in a uniform manner among the partition's virtual processors -- thus the number of virtual processors affects the time slice size) each dispatch cycle. Capacity ceded or conferred from one partition virtual processor extends the time slices offered to other partition processors. Capacity ceded or conferred after all of the partition's virtual processors have been dispatched is added to the variable capacity kitty. The initial, minimum and maximum constraint values of this parameter are determined by the partition configuration definition. The OS can set this parameter within the constraints imposed by the partition configuration definition minimum and maximums plus constraints imposed by partition aggregation. To change this value, echo the new partition_entitled_capacity into +.B /proc/ppc64/lparcfg +like this: +.br +.IP "" 7 +.B echo """partition_entitled_capacity=40"" > /proc/ppc64/lparcfg +.PP +.B group +.br +LPAR group number of the partition +.PP +.B system_active_processors +.br +The number of processors active on the underlying physical system. +.PP +.B pool +.br +The pool number of the shared processor pool for the partition. This field is not displayed in the case of a dedicated processor partition. +.PP +.B pool_capacity +.br +The number of physical processors active in the partition's processor pool. This field is not displayed in the case of a dedicated processor partition. This value is expressed as a percentage so is 100* the number of active physical processors. +.PP +.B pool_idle_time +.br +If no virtual processor is ready to run, the pool_idle_count is incremented the total number of idle processor cycles in the physical processor pool. This field contains the total number of idle processor cycles up to the current point in time. If unsupported or if performance information collection is not enabled for the partition on the HMC, this will report 0. This field is not displayed in the case of a dedicated processor partition. For more information, see the NOTES section below on PURR/PIC. +.PP +.B pool_num_procs +.br +The number of physical processors in the partition's processing pool. This field is not displayed in the case of a dedicated processor partition. +.PP +.B unallocated_capacity_weight +.br +Unallocated Variable Processor Capacity Weight. The amount of variable processor capacity weight that is currently available within the constraints of the partition's current environment for allocation to the partition's variable processor capacity weight. +.PP +.B capacity_weight +.br +Variable Processor Capacity Weight. The unitless factor that the hypervisor uses to assign processor capacity in addition to the Entitled Processor Capacity Percentage. This factor may take the values 0 to 255. In the case of a dedicated processor partition this value is 0. A virtual processor's time slice may be extended to allow it to use capacity unused by other partitions, or not needed to meet the Entitled Processor Capacity Percentage of the active partitions. A partition is offered a portion of this variable capacity kitty equal to: (Variable Processor Capacity Weight for the partition) / (summation of Variable Processor Capacity Weights for all competing partitions). The initial value of this parameter is determined by the partition configuration definition. The OS can set this parameter within the constraints imposed by the partition configuration definition maximum. Certain partition definitions may not allow any variable processor capacity allocation. To change t! his value, echo the new capacity_weight into +.B /proc/ppc64/lparcfg +like this: +.br +.IP "" 7 +.B echo """capacity_weight=128"" > /proc/ppc64/lparcfg +.PP +.B capped +.br +The partition's virtual processor(s) are capped at their entitled processor capacity percentage if this is 1. If capped=0, the partition is uncapped, and can use processor capacity from the uncapped pool, if available and according to the weighted values. In the case of dedicated processors this bit is set. +.PP +.B unallocated_capacity +.br +Unallocated Processor Capacity Percentage. The amount of processor capacity that is currently available within the constraints of the partition's current environment for allocation to Entitled Processor Capacity Percentage. +.PP +.B purr +.br +The Processor Utilization of Resources Register. Summation of the PURR value for all of the partition's virtual processors. See the NOTES section below for more information on PURR and PIC. This value is typically not a metric used. +.PP +.B partition_active_processors +.br +The total number of virtual processors assigned to the partition. This does not include the potential SMT threads. For dedicated processor partitions, this is the number of physical processors assigned to the partition. Linux will define virtual CPUs for the possible SMT threads across all of the virtual processors defined here. +.PP +.B partition_potential_processors +.br +The maximum number of virtual processors that can be assigned to the partition. This does not include SMT threads. For dedicated processor partitions, this is the maximum number of physical processors that can be assigned to the partition. +.PP +.B shared_processor_mode +.br +This is set to 1 if the partition is running with shared processors. This is set to 0 for dedicated processor partitions. +.PP +.B lparcfg 1.7 additional fields +.PP +.B slb_size +.br +The total number of entries in the Segment Lookaside Buffer (SLB). This is an attribute of the underlying processor architecture and is provided for informational purposes. The Linux OS uses this when determining the ability to perform Live Partition Migration with differing processor families. +.PP +.B lparcfg 1.8 +.PP +.B entitled_memory +.br +The number of bytes of main storage that the partition is entitled to DMA map for virtual I/O devices. In the case of a dedicated memory partition this is the size of the partition's logical address space. To change this value, echo the new entitled_memory value into +.B /proc/ppc64/lparcfg +like this: +.br +.IP "" 7 +.B echo """entitled_memory=80740352"" > /proc/ppc64/lparcfg +.PP +.B mapped_entitled_memory +.br +The number of bytes of main storage that the partition has DMA mapped. In the case of a dedicated memory partition this is not displayed. +.PP +.B entitled_memory_group_number +.br +Entitled Memory Group Number +.PP +.B entitled_memory_pool_number +.br +Entitled memory pool number. In the case of a dedicated memory partition, this is 65535. +.PP +.B entitled_memory_weight +.br +The partition's shared memory weight. In the case of a dedicated memory partition this is 0. To change this value, echo the new entitled_memory_weight value into +.B /proc/ppc64/lparcfg +like this: +.br +.IP "" 7 +.B echo """entitled_memory_weight=128"" > /proc/ppc64/lparcfg +.PP +.B unallocated_entitled_memory_weight +.br +The unallocated shared memory weight for the calling partition's aggregation. In the case of a dedicated memory partition this is 0. +.PP +.B unallocated_io_mapping_entitlement +.br +The unallocated I/O mapping entitlement for the calling partition's aggregation divided by 4096. In the case of a dedicated memory partition this is 0. +.PP +.B entitled_memory_loan_request +.br +The signed difference between the number of bytes of logical storage that are currently on loan from the calling partition and the partition's overage allotment (a positive number indicates a request to the partition to loan the indicated number of bytes else they will be expropriated as needed). In the case of a dedicated memory partition this is 0. In the case of a shared memory partition, when running the Collaborative Memory Manager (cmm module), this will typically be 0, as the CMM will monitor and fulfill the hypervisor's loan requests. +.PP +.B backing_memory +.br +The number of bytes of main storage that is backing the partition logical address space. In the case of a dedicated memory partition this is the size of the partition's logical address space. +.PP +.B cmo_enabled +.br +If Active Memory Sharing is enabled for the partition, this is set to 1. For dedicated memory partitions, this is 0. +.PP +.B cmo_faults +.br +Displayed only for shared memory partitions. Indicates the total number of times the partition has accessed a page in memory which was paged out to disk by firmware, requiring it to be paged back in. If the Collaborative Memory Manager is disabled, this value may be large. If it is enabled (default setting for most Linux distributions), this number is typically small. If this value is large and is increasing, it may be an indication that the partition's shared memory pool has too high of an overcommit ratio, in which case you may need to assign additional physical memory to the shared memory pool. +.PP +.B cmo_fault_time_usec +.br +Displayed only for shared memory partitions. Indicates the total amount of time in microseconds the partition has had a virtual processor blocked in order for firmware to page in data. Directly related to cmo_faults. +.PP +.B cmo_primary_psp +.br +Displayed only for shared memory partitions. Partition ID of the primary paging VIOS. +.PP +.B cmo_secondary_psp +.br +Displayed only for shared memory partitions. Partition ID of the secondary paging VIOS. If there is no secondary paging VIOS, this will be set to 65535. +.PP +.B cmo_page_size +.br +Displayed only for shared memory partitions. Physical page size in bytes. +.PP +.B lparcfg 1.9 additional fields +.PP +.B physical_procs_allocated_to_virtualization +.br +The number of physical platform processors allocated to processor virtualization. This is a physical system attribute and has no bearing on the Linux partition. +.PP +.B max_proc_capacity_available +.br +The maximum processor capacity percentage that is available to the partition's shared processor pool. +.PP +.B entitled_proc_capacity_available +.br +The entitled processor capacity percentage available to the partition's pool. +.PP +.B dispatches +.br +Virtual Processor Dispatch Counter. Counter that is incremented each time a virtual processor is dispatched/preempted. +.PP +.B dispatch_dispersions +.br +Virtual Processor Dispatch Dispersion Accumulator. Incremented on each virtual processor dispatch if the physical processor differs from that of the last dispatch. +.SH NOTES +.PP +.B PURR/PIC +.br +These two statistics are counts in the same units as counted by the processor time base. Like the time base, the PUR and PIC are 64 bit values that are set to a numerically low value during system initialization. The difference between their values at the end and beginning of monitored operations provides data on virtual processor performance. The value of the PUR is a count of processor cycles used by the calling virtual processor. The PUR count is intended to provide an indication to the partition software of the computation load supported by the virtual processor. Shared processor virtual processors are created by dispatching the virtual processor's architectural state on one of the physical processors from a pool of physical processors. The value of the PIC is the summation of the physical processor pool idle cycles, that is the number of time base counts when the pool could not dispatch a virtual processor. The PIC count is intended to provide an indication to platform! management software of the pool capacity to perform more work. +.PP +.B Processors vs. SMT threads +.br +The Power processors support Simultaneous Multi-Threading (SMT). SMT is generally enabled by default on most Linux distributions that support Power. When enabled, a single Power 5 or Power 6 CPU will be seen as up to two logical CPUs in the Linux operating system. A single Power 7 CPU will be seen as four logical CPUs. SMT can be disabled with the +.B ppc64_cpu +utility, which is packaged in powerpc-utils. When SMT is disabled, the logical CPUs seen by Linux will not be contiguous. For example, a four core Power 7 partition with SMT disabled will show CPUs 0, 4, 8, and 12 in /proc/cpuinfo. A Power7 CPU/processor/core can also be set to SMT=2 mode. + +.SH VERSIONS +.PP +.B Linux Distribution Version Mapping +The following is a brief list of the mapping of some enterprise versions of Linux for Power to the version of the +.B lparcfg +file. +.br +SLES 9: lparcfg 1.6 +.br +SLES 10: lparcfg 1.7 +.br +SLES 11: lparcfg 1.8 +.br +SLES 11 SP1: lparcfg 1.9 +.br +RHEL 4: lparcfg 1.6 +.br +RHEL 5: lparcfg 1.7 +.br +RHEL 6: lparcfg 1.9 + +.SH FILES +.TP +.B /proc/ppc64/lparcfg + +.SH AUTHOR +Written by Brian King <br...@li...>. +.br +Comments and questions on this document should be posted on the +.B Linux for Power Architecture +forum: +.br +.B http://www.ibm.com/developerworks/forums/forum.jspa?forumID=375&start=0. + _ |
From: Jim K. <jke...@li...> - 2010-11-16 23:04:20
|
I've submitted a series of Linux kernel patches to capture the latest oops or panic report in NVRAM -- e.g., for perusal after reboot. In order to display this report, which is either compressed or uncompressed ASCII text, I've prototyped --ascii and --unzip options for the nvram command. kernel patches: http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-November/087032.html nvram command: http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-November/087038.html The nvram.c patch is also included here. I'm thinking I need to add an option like --print-oops, which automatically looks in ibm,rtas-log if ibm,oops-log doesn't exist, and looks at the event code in the partition's subheader to decide whether the text is compressed or not. I also need to arrange for nvram to be built with -lz. It's not clear what the final form of the kernel feature will be; it may be decided that compression is unnecessary, which would of course affect what we do to nvram.c Jim Keniston IBM LTC Beaverton, OR === Add nvram --unzip and --ascii options Add --unzip and --ascii options to nvram command, for examination of oops/panic reports captured in ibm,oops-log or ibm,rtas-log. Signed-off-by: Jim Keniston <jke...@us...> --- src/nvram.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 136 insertions(+), 0 deletions(-) diff --git a/src/nvram.c b/src/nvram.c index d25e073..e00ae12 100644 --- a/src/nvram.c +++ b/src/nvram.c @@ -43,6 +43,7 @@ #include <glob.h> #include <getopt.h> #include <inttypes.h> +#include <zlib.h> #include "nvram.h" @@ -62,6 +63,8 @@ static struct option long_options[] = { {"print-event-scan", no_argument, NULL, 'E'}, {"partitions", no_argument, NULL, 'P'}, {"dump", required_argument, NULL, 'd'}, + {"ascii", required_argument, NULL, 'a'}, + {"unzip", required_argument, NULL, 'z'}, {"nvram-file", required_argument, NULL, 'n'}, {"nvram-size", required_argument, NULL, 's'}, {"update-config", required_argument, NULL, 'u'}, @@ -99,6 +102,10 @@ help(void) " print NVRAM paritition header info\n" " --dump <name>\n" " raw dump of partition (use --partitions to see names)\n" + " --ascii <name>\n" + " print partition contents as ASCII text\n" + " --unzip <name>\n" + " decompress and print compressed data from partition\n" " --nvram-file <path>\n" " specify alternate nvram data file (default is /dev/nvram)\n" " --nvram-size\n" @@ -1189,6 +1196,121 @@ dump_raw_partition(struct nvram *nvram, char *name) } /** + * dump_ascii_partition + * @brief ASCII data dump of a partition, excluding header + * + * @param nvram nvram struct containing partition + * @param name name of partition to dump + * @return 0 on success, !0 otherwise + * + * Partition subheaders, if any, are dumped along with the rest of the data. + * We substitute periods for unprintable characters. + */ +int +dump_ascii_partition(struct nvram *nvram, char *name) +{ + struct partition_header *phead; + char *start, *end, *c; + + phead = nvram_find_partition(nvram, 0, name, NULL); + if (!phead) { + err_msg("there is no %s partition!\n", name); + return -1; + } + + start = (char*) phead; + end = start + phead->length * NVRAM_BLOCK_SIZE; + start += sizeof(*phead); /* Skip partition header. */ + for (c = start; c < end; c++) { + if (isprint(*c) || isspace(*c)) + putchar(*c); + else + putchar('.'); + } + /* Always end with a newline.*/ + putchar('\n'); + return 0; +} + +int +dump_zipped_text(char *zipped_text, unsigned int zipped_length) +{ + z_stream strm; + int result; + char unzipped_text[4096]; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = zipped_length; + strm.next_in = zipped_text; + result = inflateInit(&strm); + if (result != Z_OK) { + err_msg("can't decompress text: inflateInit() returned %d\n", result); + return -1; + } + + do { + strm.avail_out = 4096; + strm.next_out = unzipped_text; + result = inflate(&strm, Z_NO_FLUSH); + switch (result) { + case Z_STREAM_ERROR: + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + err_msg("can't decompress text: inflate() returned %d\n", result); + (void) inflateEnd(&strm); + return -1; + } + if (fwrite(unzipped_text, 4096 - strm.avail_out, 1, stdout) != 1) { + err_msg("can't decompress text: fwrite() failed\n"); + (void) inflateEnd(&strm); + return -1; + } + } while (strm.avail_out == 0); + + (void) inflateEnd(&strm); + return 0; +} + +/** + * unzip_partition + * @brief Uncompress and print compressed data from a partition. + * + * @param nvram nvram struct containing partition + * @param name name of partition to dump + * @return 0 on success, !0 otherwise + */ +int +unzip_partition(struct nvram *nvram, char *name) +{ + struct partition_header *phead; + char *start, *next; + unsigned short zipped_length; + + phead = nvram_find_partition(nvram, 0, name, NULL); + if (!phead) { + err_msg("there is no %s partition!\n", name); + return -1; + } + + start = (char*) phead; + next = start + sizeof(*phead); /* Skip partition header. */ + next += sizeof(struct err_log_info); /* Skip sub-header. */ + zipped_length = *((unsigned short*) next); + next += sizeof(unsigned short); /* Skip compressed length. */ + + if ((next-start) + zipped_length > phead->length * NVRAM_BLOCK_SIZE) { + err_msg("bogus size for compressed data in partition %s: %u\n", name, + zipped_length); + return -1; + } + + return dump_zipped_text(next, zipped_length); +} + +/** * print_of_config_part * @brief Print the name/value pairs of a partition * @@ -1476,6 +1598,8 @@ main (int argc, char *argv[]) int print_event_scan = 0; int print_config_var = 0; char *dump_name = NULL; + char *ascii_name = NULL; + char *zip_name = NULL; char *update_config_var = NULL; char *config_pname = "common"; @@ -1504,6 +1628,12 @@ main (int argc, char *argv[]) case 'd': /* dump */ dump_name = optarg; break; + case 'a': /* ASCII dump */ + ascii_name = optarg; + break; + case 'z': /* dump compressed data */ + zip_name = optarg; + break; case 'n': /* nvram-file */ nvram.filename = optarg; break; @@ -1641,6 +1771,12 @@ main (int argc, char *argv[]) if (dump_name) if (dump_raw_partition(&nvram, dump_name) != 0) ret = -1; + if (ascii_name) + if (dump_ascii_partition(&nvram, ascii_name) != 0) + ret = -1; + if (zip_name) + if (unzip_partition(&nvram, zip_name) != 0) + ret = -1; err_exit: if (nvram.data) |
From: Nathan F. <nf...@au...> - 2010-11-01 18:57:42
|
Trying to install the man pages causes a failure due to trying to install the man pages twice. This was introduced when the use of dist_man_MANS was added to the man/Makefile.am file. The autoconf tools merge the dist_man_MANS ans man_MANS list of files and tries to install all of them. The easy fix is to simply remove the man_MANS list from man/Makefile.am so that each man page is not listed twice. Signed-off-by: Nathan Fontenot <nf...@au...> --- man/Makefile.am | 6 ------ man/Makefile.in | 20 +++++++------------- 2 files changed, 7 insertions(+), 19 deletions(-) Index: powerpc-utils/man/Makefile.am =================================================================== --- powerpc-utils.orig/man/Makefile.am 2010-11-01 13:14:42.000000000 -0500 +++ powerpc-utils/man/Makefile.am 2010-11-01 13:15:38.000000000 -0500 @@ -1,9 +1,3 @@ -man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ - uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ - update_flash.8 nvram.8 set_poweron_time.8 \ - usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 - dist_man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ Index: powerpc-utils/man/Makefile.in =================================================================== --- powerpc-utils.orig/man/Makefile.in 2010-11-01 13:14:42.000000000 -0500 +++ powerpc-utils/man/Makefile.in 2010-11-01 13:17:27.000000000 -0500 @@ -74,7 +74,7 @@ am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" man8dir = $(mandir)/man8 NROFF = nroff -MANS = $(dist_man_MANS) $(man_MANS) +MANS = $(dist_man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -162,12 +162,6 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ - uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ - update_flash.8 nvram.8 set_poweron_time.8 \ - usysattn.8 bootlist.8 ofpathname.8 snap.8 usysident.8 \ - hvcsadmin.8 rtas_dump.8 sys_ident.8 vscsisadmin.8 - dist_man_MANS = activate_firmware.8 ibmvscsis.conf.8 rtas_ibm_get_vpd.8 \ uesensor.8 amsstat.1 ibmvscsis.sh.8 serv_config.8 \ update_flash.8 nvram.8 set_poweron_time.8 \ @@ -207,12 +201,12 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-man1: $(dist_man_MANS) $(man_MANS) +install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ @@ -238,19 +232,19 @@ @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } -install-man8: $(dist_man_MANS) $(man_MANS) +install-man8: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" @list=''; test -n "$(man8dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ @@ -276,7 +270,7 @@ @$(NORMAL_UNINSTALL) @list=''; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ |
From: Kamalesh B. <kam...@li...> - 2010-10-25 15:01:34
|
scripts: Fix usage() of ls-v{dev,eth,scsi} and lsdevinfo. - Prefix ':' to getops optstring to avoid complaining about invalid optional character. - Delete the long option(s) for help and version to reflect the options available in the man pages. - Remove :) case from cmdline parsing as option-argument with arugment is not passed. Signed-off-by: Kamalesh Babulal <kam...@li...> -- scripts/ls-vdev | 8 +++----- scripts/ls-veth | 10 ++++------ scripts/ls-vscsi | 7 ++++++- scripts/lsdevinfo | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/scripts/ls-vdev b/scripts/ls-vdev index 7bab966..95f458e 100644 --- a/scripts/ls-vdev +++ b/scripts/ls-vdev @@ -21,8 +21,8 @@ usage() echo "Provide information on Virtual SCSI adapters and devices" echo "" echo "Optional arguments." - echo " -V, --version Display version information and exit" - echo " -h, --help Display this help information and exit" + echo " -V Display version information and exit" + echo " -h Display this help information and exit" echo "" } @@ -33,7 +33,7 @@ show_version() } -while getopts "Vh" flag ; do +while getopts ":Vh" flag ; do case "$flag" in V) show_version exit 0 ;; @@ -42,8 +42,6 @@ while getopts "Vh" flag ; do exit 0 ;; \?) usage exit 1 ;; - :) echo "Option -$OPTARG requires an argument." - exit 1 ;; esac done diff --git a/scripts/ls-veth b/scripts/ls-veth index 01dce85..f4b9bc9 100644 --- a/scripts/ls-veth +++ b/scripts/ls-veth @@ -18,12 +18,12 @@ SED="/bin/sed" usage() { - echo "Usage: $LSVETH [-h]" + echo "Usage: $LSVETH " echo "Provide information on Virtual Ethernet devices" echo "" echo "Optional arguments." - echo " -V, --version Display version information and exit" - echo " -h, --help Display this help information and exit" + echo " -V Display version information and exit" + echo " -h Display this help information and exit" echo "" } @@ -34,7 +34,7 @@ show_version() } -while getopts "Vh" flag ; do +while getopts ":Vh" flag ; do case "$flag" in V) show_version exit 0 ;; @@ -43,8 +43,6 @@ while getopts "Vh" flag ; do exit 0 ;; \?) usage exit 1 ;; - :) echo "Option -$OPTARG requires an argument." - exit 1 ;; esac done diff --git a/scripts/ls-vscsi b/scripts/ls-vscsi index 85bd66e..efa3e71 100644 --- a/scripts/ls-vscsi +++ b/scripts/ls-vscsi @@ -19,6 +19,11 @@ usage() { echo "Usage: $LSVSCSI" echo "Provide information on Virtual devices" + echo "" + echo "Optional arguments." + echo " -V Display version information and exit" + echo " -h Display this help information and exit" + echo "" } show_version() @@ -28,7 +33,7 @@ show_version() } -while getopts "Vh" flag ; do +while getopts ":Vh" flag ; do case "$flag" in V) show_version diff --git a/scripts/lsdevinfo b/scripts/lsdevinfo index 5f7bb8e..642297a 100755 --- a/scripts/lsdevinfo +++ b/scripts/lsdevinfo @@ -35,8 +35,8 @@ usage() echo " -R Recursively display children of selected devices" echo " -c Display output as a comma separated list for" echo " each device." - echo " -V, --version Display version information and exit" - echo " -h, --help Display this help information and exit" + echo " -V Display version information and exit" + echo " -h Display this help information and exit" echo "" } Kamalesh |
From: Nathan F. <nf...@au...> - 2010-10-25 14:59:30
|
The nvram verbose option should be able to be specified as -v and --verbose as is specified in the help message for the command. The getopt_long parsing did not allow for -v though. This patch corrects that. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/nvram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: powerpc-utils/src/nvram.c =================================================================== --- powerpc-utils.orig/src/nvram.c 2010-10-25 08:26:15.000000000 -0500 +++ powerpc-utils/src/nvram.c 2010-10-25 08:27:15.000000000 -0500 @@ -1491,7 +1491,7 @@ main (int argc, char *argv[]) for (;;) { option_index = 0; - ret = getopt_long(argc, argv, "+p:V", long_options, &option_index); + ret = getopt_long(argc, argv, "+p:Vv::", long_options, &option_index); if (ret == -1) break; switch (ret) { |
From: Robert J. <rc...@li...> - 2010-10-08 21:16:57
|
Change drmgr to attempt to remove memory which may be held by a balloon driver. This change ignores the 'removable' flag if AMS and CMM are active. The memory balloon driver (CMM) for active memory sharing (AMS) makes use of a new 'memory isolate kernel notifier' along with the 'memory hotplug notifier' to free pages which are not migratable. To make use of this, drmgr must attempt to remove memory which would have not have the sysfs 'removable' flag set. Signed-off-by: Robert Jennings <rc...@li...> --- src/drmgr/common.c | 23 +++++++++++++++++++++++ src/drmgr/dr.h | 2 ++ src/drmgr/drslot_chrp_mem.c | 9 ++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/drmgr/common.c b/src/drmgr/common.c index 0a81198..6ffcdf0 100644 --- a/src/drmgr/common.c +++ b/src/drmgr/common.c @@ -1197,3 +1197,26 @@ print_dlpar_capabilities(void) (cpu_entitled ? "yes" : "no"), (mem_entitled ? "yes" : "no"), (slb_resize ? "yes" : "no"), (phib ? "yes" : "no")); } + +/** + * ams_balloon_active + * @brief Determines if AMS and memory ballooning is enabled + * + * @returns 1 if ballooning is active, 0 if AMS or ballooning is inactive + */ +int ams_balloon_active(void) +{ + /* CMM's loaned_kb file only appears when AMS is enabled */ + char *ams_enabled = "/sys/devices/system/cmm/cmm0/loaned_kb"; + char *cmm_param_path = "/sys/module/cmm/parameters"; + struct stat sbuf; + int is_inactive = 1; + + if (!stat(ams_enabled, &sbuf) && !stat(cmm_param_path, &sbuf)) { + get_int_attribute(cmm_param_path, "disable", + &is_inactive, sizeof(is_inactive)); + } + + dbg("AMS ballooning %s active\n", is_inactive?"is not":"is"); + return !is_inactive; +} diff --git a/src/drmgr/dr.h b/src/drmgr/dr.h index b9ee27e..7902598 100644 --- a/src/drmgr/dr.h +++ b/src/drmgr/dr.h @@ -181,4 +181,6 @@ int valid_pmig_options(struct options *); void pmig_usage(char **); void phib_usage(char **); +int ams_balloon_active(void); + #endif diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c index c886eb3..95cfab4 100644 --- a/src/drmgr/drslot_chrp_mem.c +++ b/src/drmgr/drslot_chrp_mem.c @@ -413,7 +413,7 @@ get_lmbs(void) * get_available_lmb * * Find the first lmb which does not correspond to a lmb - * already owned by the partition and is avaialble, or the lmb + * already owned by the partition and is available, or the lmb * matching the one specified by the user. * * @param lmb_list list of lmbs to be searched for available lmb @@ -423,6 +423,7 @@ static struct dr_node * get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) { struct dr_node *lmb; + int balloon_active = ams_balloon_active(); for (lmb = lmb_list->lmbs; lmb; lmb = lmb->next) { int rc; @@ -448,7 +449,9 @@ get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) break; case REMOVE: - if ((!lmb->is_removable) || (!lmb->is_owned)) + /* removable is ignored if AMS ballooning is active. */ + if ((!balloon_active && !lmb->is_removable) || + (!lmb->is_owned)) continue; break; } @@ -458,7 +461,7 @@ get_available_lmb(struct options *opts, struct lmb_list_head *lmb_list) } if (lmb) - dbg("Found avaialable lmb, %s, drc index 0x%x\n", + dbg("Found available lmb, %s, drc index 0x%x\n", lmb->drc_name, lmb->drc_index); else dbg("Could not find available lmb\n"); -- 1.7.0.4 |
From: Kamalesh B. <kam...@li...> - 2010-10-05 06:27:11
|
Hi, This patch fixes the typo in -V option of the ofpathname man page. Signed-off-by: Kamalesh Babulal <kam...@li...> -- man/ofpathname.8 | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/man/ofpathname.8 b/man/ofpathname.8 index 379e9b6..17f8db9 100644 --- a/man/ofpathname.8 +++ b/man/ofpathname.8 @@ -24,7 +24,7 @@ Find a matching Open Firmware device alias[es]. Do not report any failures, exit quietly. .TP \fB\--version \fR(\fB\-V\fR) -Displat version and exit +Display version information and exit. .TP \fB\--help \fR(\fB\-h\fR) print usage information. Kamalesh |
From: Murillo F. B. <ber...@br...> - 2010-09-02 16:49:46
|
cpu_freq[i] is initialized after setup_counters is called, therefore setup_counters will always fails if the system is in SMT 2 or SMT off. This patch makes setup_counters verify directly if the cpu is online or not. Signed-off-by: Murillo Fernandes Bernardes <ber...@br...> --- src/ppc64_cpu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/ppc64_cpu.c b/src/ppc64_cpu.c index 8f5484c..32fb01e 100644 --- a/src/ppc64_cpu.c +++ b/src/ppc64_cpu.c @@ -484,7 +484,7 @@ static int setup_counters(void) attr.size = sizeof(attr); for (i = 0; i < threads_in_system; i++) { - if (cpu_freq[i] == CPU_OFFLINE) + if (!cpu_online(i)) continue; counters[i] = syscall(__NR_perf_event_open, &attr, -1, -- 1.7.1 |
From: Nathan F. <nf...@au...> - 2010-08-25 03:14:01
|
Configure updates to not check for servicelog. Signed-off-by: Nathan Fontenot <nf...@au...> --- a/configure +++ b/configure @@ -3583,85 +3583,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -# Checks for libraries. - - -{ $as_echo "$as_me:$LINENO: checking for servicelog_open in -lservicelog" >&5 -$as_echo_n "checking for servicelog_open in -lservicelog... " >&6; } -if test "${ac_cv_lib_servicelog_servicelog_open+set}" = set; then - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lservicelog $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char servicelog_open (); -int -main () -{ -return servicelog_open (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - ac_cv_lib_servicelog_servicelog_open=yes -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_servicelog_servicelog_open=no -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_servicelog_servicelog_open" >&5 -$as_echo "$ac_cv_lib_servicelog_servicelog_open" >&6; } -if test "x$ac_cv_lib_servicelog_servicelog_open" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSERVICELOG 1 -_ACEOF - - LIBS="-lservicelog $LIBS" - -fi - - # Checks for header files. + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4298,8 +4221,7 @@ done - -for ac_header in fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h nl_types.h stdint.h stdlib.h string.h sys/ioctl.h syslog.h unistd.h servicelog-1/servicelog.h linux/perf_event.h +for ac_header in fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h nl_types.h stdint.h stdlib.h string.h sys/ioctl.h syslog.h unistd.h linux/perf_event.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then diff --git a/configure.ac b/configure.ac index 4a0ea65..4004805 100644 --- a/configure.ac +++ b/configure.ac @@ -13,11 +13,8 @@ AC_CONFIG_SRCDIR([src/rtas_ibm_get_vpd.c]) AC_PROG_CC AC_PROG_INSTALL -# Checks for libraries. -AC_CHECK_LIB([servicelog], [servicelog_open]) - # Checks for header files. -AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h nl_types.h stdint.h stdlib.h string.h sys/ioctl.h syslog.h unistd.h servicelog-1/servicelog.h linux/perf_event.h]) +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h nl_types.h stdint.h stdlib.h string.h sys/ioctl.h syslog.h unistd.h linux/perf_event.h]) AC_CHECK_HEADER(librtas.h,,AC_MSG_ERROR(Cannot find librtas.h)) # Checks for typedefs, structures, and compiler characteristics. |
From: Nathan F. <nf...@au...> - 2010-08-25 03:13:02
|
Remove the logging of migration/hibernation events. This is now done in the DynamicRM package. Signed-off-by: Nathan Fontenot <nf...@au...> --- a/src/drmgr/drmig_chrp_pmig.c +++ b/src/drmgr/drmig_chrp_pmig.c @@ -16,9 +16,6 @@ #include <dirent.h> #include <time.h> #include <librtas.h> -#ifdef HAVE_SERVICELOG -#include <servicelog-1/servicelog.h> -#endif #include "dr.h" #include "ofdt.h" #include "drpci.h" @@ -494,62 +491,6 @@ devtree_update(void) dbg("leaving\n"); } -#ifdef HAVE_SERVICELOG -/** - * servicelog_update - * @brief Logs a migration event in servicelog, if it is installed - * - * @param sys_src serial number of the source machine - */ -static void -servicelog_update(char *sys_src) -{ - struct servicelog *slog; - struct sl_event event; - char msg[128], refcode[64], sys_dest[20]; - int rc; - uint64_t event_id; - - /* Build the servicelog event */ - memset(&event, 0, sizeof(event)); - event.type = SL_TYPE_BASIC; - event.time_event = time(NULL); - event.severity = SL_SEV_INFO; - - if (action == MIGRATE) - snprintf(refcode, 9, "#MIGRATE"); - else /* hibernation */ - snprintf(refcode, 12, "#HIBERNATION"); - event.refcode = refcode; - - get_str_attribute(OFDT_BASE, "system-id", sys_dest, 20); - - if (action == MIGRATE) - snprintf(msg, 128, "Partition migration completed. Source: " - "%s Destination: %s", sys_src, sys_dest); - else /* hibernation */ - snprintf(msg, 128, "Partition hibernation completed. Source: " - "%s Destination: %s", sys_src, sys_dest); - - event.description = msg; - - rc = servicelog_open(&slog, 0); - if (rc) { - dbg("Couldn't open the servicelog database: %s\n", - servicelog_error(slog)); - return; - } - - rc = servicelog_event_log(slog, &event, &event_id); - if (rc) { - dbg("Couldn't log an event to the servicelog database: %s\n", - servicelog_error(slog)); - } - - servicelog_close(slog); -} -#endif - int valid_pmig_options(struct options *opts) { @@ -702,9 +643,5 @@ drmig_chrp_pmig(struct options *opts) dbg("Refreshing RMC via refrsrc\n"); system("/usr/sbin/rsct/bin/refrsrc IBM.ManagementServer"); -#ifdef HAVE_SERVICELOG - servicelog_update(sys_src); -#endif - return 0; } |
From: Nathan F. <nf...@au...> - 2010-08-16 14:48:03
|
Fixes issues with DLPAR on some p7 platforms. Signed-off-by: Brian King <br...@li...> --- src/drmgr/drslot_chrp_phb.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff -puN src/drmgr/drslot_chrp_phb.c~dlpar_hp src/drmgr/drslot_chrp_phb.c --- powerpc-utils/src/drmgr/drslot_chrp_phb.c~dlpar_hp 2010-08-10 16:00:35.000000000 -0500 +++ powerpc-utils-bjking1/src/drmgr/drslot_chrp_phb.c 2010-08-10 17:55:22.000000000 -0500 @@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <dirent.h> #include <librtas.h> #include <errno.h> #include "dr.h" @@ -87,6 +88,156 @@ release_phb(struct dr_node *phb) return rc; } +struct hpdev { + struct hpdev *next; + char path[256]; + char devspec[256]; +}; + +#define SYSFS_PCI_DEV_PATH "/sys/bus/pci/devices" + +static void free_hpdev_list(struct hpdev *hpdev_list) +{ + struct hpdev *hpdev; + + while (hpdev_list) { + hpdev = hpdev_list; + hpdev_list = hpdev_list->next; + free(hpdev); + } +} + +static int get_os_hp_devices(struct hpdev **hpdev_list) +{ + struct hpdev *hp_list = NULL; + struct hpdev *hpdev; + DIR *d; + struct dirent *de; + int rc = 0; + + d = opendir(SYSFS_PCI_DEV_PATH); + if (!d) { + err_msg("Failed to open %s\n", SYSFS_PCI_DEV_PATH); + return -1; + } + + while ((de = readdir(d)) != NULL) { + if (is_dot_dir(de->d_name)) + continue; + + hpdev = zalloc(sizeof(*hpdev)); + if (!hpdev) { + rc = -1; + break; + } + + rc = sprintf(hpdev->path, "%s/%s", SYSFS_PCI_DEV_PATH, + de->d_name); + if (rc < 0) + break; + + rc = get_str_attribute(hpdev->path, "devspec", hpdev->devspec, + 256); + if (rc) + break; + + dbg("HPDEV: %s\n %s\n", hpdev->path, hpdev->devspec); + hpdev->next = hp_list; + hp_list = hpdev; + } + + closedir(d); + + if (rc) { + free_hpdev_list(hp_list); + hp_list = NULL; + } + + *hpdev_list = hp_list; + return rc; +} + +static int hp_remove_os_device(struct hpdev *hpdev) +{ + FILE *file; + char path[256]; + int rc; + + sprintf(path, "%s/%s", hpdev->path, "remove"); + + file = fopen(path, "w"); + if (!file) + return -1; + + dbg("Removing %s\n", hpdev->path); + rc = fwrite("1", 1, 1, file); + if (rc == 1) + rc = 0; + + fclose(file); + sleep(5); + return rc; +} + +static int disable_os_hp_children_recurse(struct dr_node *phb, + struct hpdev *hpdev_list, char *ofpath) +{ + struct hpdev *hpdev; + DIR *d; + struct dirent *de; + int rc = 0; + + d = opendir(ofpath); + if (!d) + return -1; + + while ((de = readdir(d)) != NULL) { + char devspec[256]; + + if (is_dot_dir(de->d_name)) + continue; + + if (de->d_type == DT_DIR) { + char lpath[4096]; + sprintf(lpath, "%s/%s", ofpath, de->d_name); + rc = disable_os_hp_children_recurse(phb, hpdev_list, lpath); + } + + memset(devspec, 0, 256); + sprintf(devspec, "%s/%s", ofpath + strlen(OFDT_BASE), + de->d_name); + + for (hpdev = hpdev_list; hpdev; hpdev = hpdev->next) { + if (!strcmp(hpdev->devspec, devspec)) { + rc = hp_remove_os_device(hpdev); + break; + } + } + + if (rc) { + err_msg("Failed to hotplug remove %s\n", hpdev->path); + break; + } + } + + closedir(d); + return rc; +} + +static int disable_os_hp_children(struct dr_node *phb) +{ + struct hpdev *hpdev_list; + int rc = 0; + + rc = get_os_hp_devices(&hpdev_list); + if (rc) + return -1; + + rc = disable_os_hp_children_recurse(phb, hpdev_list, phb->ofdt_path); + free_hpdev_list(hpdev_list); + return rc; +} + /** * remove_phb * @@ -127,6 +278,19 @@ remove_phb(struct options *opts) } } + /* If there are any directories under the phb left at this point, + * they are OS hotplug devies. Note: this is different from DR + * hotplug devices. This really occurs on systems that do not + * support DR hotplug devices. The device tree does not get populated + * with drc information for these devices and such they do not appear + * on the list generated by the calls to get_node_* + * + * For these devices we simply hotplug remove them from the OS. + */ + rc = disable_os_hp_children(phb); + if (rc) + goto phb_remove_error; + rc = dlpar_io_kernel_op(dlpar_remove_slot, phb->drc_name); if (rc) { err_msg("kernel remove failed for %s, rc = %d\n", _ |
From: Nathan F. <nf...@au...> - 2010-08-04 19:07:11
|
A release of powerpc-utils-1.2.5 has been posted to the sourceforge website. The combined Changelog for the 1.2.4 and 1.2.5 releases is below. Thanks to all who contributed. -Nathan Combined Changelog for the 1.2.4 and 1.2.5 releases. ---------------------------------------------------- commit 3fe80c2f9b490a520fbb47d2166034dc4da83a79 Author: Nathan Fontenot <nf...@au...> Update to automake 1.11 try 2. commit 2d4e0443555f3d131479bff42d5e42fb959259a2 Author: Nathan Fontenot <nf...@au...> Initialize 'rc' variable so as to not use uninitialized. commit 5586e8faa2232f2c8ec76ea2610f841822f490c5 Author: Nathan Fontenot <nf...@au...> Update to use automake 1.11 along with defaulting to a silent build. This will create build output similar to the Linux kernel. commit 4b694eb0f283d2438fdba11014dc485697b8d72b Author: Brian King <br...@li...> Due to a recent change in the sysfs layout of memory sections for powerpc, the following change is needed to powerpc-utils to make memory hotplug work again. commit a1e308ce5e4248cae80bdc84b06950af2416bb00 Author: Brad Peters <bp...@li...> Patch updates lscfg path to /usr/sbin, which is where this has been installing to since lsvpd-1.0 was released back in 2007. Would be nice to auto-find the executable, but I'm not sure how we can do that (I'm open to suggestions). At the least, this patch fixes usysident for all modern versions of lsvpd, and it does not make things worse than they were. commit 88d51162d42aba82130db16cadc9a31fc70a0b7e Author: Nathan Fontenot <nf...@au...> Add --version option to ppc64_cpu. commit 2aa04a7e9b8bc3ace90f347a6d9eba001d88b9cc Author: Nathan Fontenot <nf...@au...> Add explicit check for librtas.h and have configure fail if not found. commit f83ec96bd8ff2ad608c3f725867956ed853ae894 Author: Nathan Fontenot <nf...@au...> Add check for linux/perf_event.h when building ppc64_cpu. commit d2b20d22d8f8434e343741e1374a1d78ad9791c1 Author: Kamalesh Babulal <kam...@li...> This patch fixes the typo in man ofpathname.8 commit a378927b9c670cc45ccd0ab0aec5b734b4711f80 Author: Nathan Fontenot <nf...@au...> Update version number to 1.2.4 commit f53c2a33800af8db646428242998b3837b2f31a3 Author: Freeman Rawson <fr...@us...> This patch provides a set of options to report the number of cores online on a system and allow the user to set the number of cores that are online. commit 41a1809de3175b70f10c4544bdf418f49a14d7f1 Author: Nathan Fontenot <nf...@au...> Add the capability to determine the cpu frequency on a system to the ppc64_cpu command. commit 5eed6ecc7f29e75c2e8a38d4cb393f39b0dcc871 Author: Nathan Fontenot <nf...@au...> Update the exisitng code base to use the new is_librtas_error() routine. commit a3d7e08918d5c46630801f3e25e572355e200905 Author: Nathan Fontenot <nf...@au...> Create a new is_librtas_error() routine that lets users know if the supplied error is a librtas specific return code. commit ac63fffe1e534299cfedd4c47ad0d1965fec6e7b Author: Nathan Fontenot <nf...@au...> This patch corrects the parameter handling of ppc64_cpu when setting the run-mode. The PAPR specifies that the rtas_[get|set]_system_parameter calls take a char buffer, but for the run mode it actually wants integer values in the buffer, not strings. This updates the handling of the values to be integers. commit d312aa1517b8a2003e22e4394a928193cc3f03e0 Author: Brad Peters <bp...@li...> Adding some of description of the update_flash related error events covered in LTC BZ 64797, which is an understandably confusing situation |
From: Nathan F. <nf...@au...> - 2010-08-03 21:04:21
|
Update to use automake 1.11 along with defaulting to a silent build. This will create build output similar to the Linux kernel. Attaching patch since its so big (and ugly) Signed-off-by: Nathan Fontenot <nf...@au...> |
From: Nathan F. <nf...@au...> - 2010-08-03 15:48:19
|
Due to a recent change in the sysfs layout of memory sections for powerpc, the following change is needed to powerpc-utils to make memory hotplug work again. Signed-off-by: Brian King <br...@li...> Acked-by: Nathan Fontenot <nf...@au...> --- src/drmgr/drslot_chrp_mem.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff -puN src/drmgr/drslot_chrp_mem.c~em_scns_fixed src/drmgr/drslot_chrp_mem.c --- powerpc-utils/src/drmgr/drslot_chrp_mem.c~em_scns_fixed 2010-07-22 08:55:57.000000000 -0500 +++ powerpc-utils-bjking1/src/drmgr/drslot_chrp_mem.c 2010-07-22 08:55:57.000000000 -0500 @@ -102,6 +102,7 @@ get_mem_scns(struct dr_node *lmb) while (lmb_sz > 0) { char *sysfs_path = "/sys/devices/system/memory/memory%d"; struct mem_scn *scn; + struct stat sbuf; scn = zalloc(sizeof(*scn)); if (scn == NULL) { @@ -112,10 +113,13 @@ get_mem_scns(struct dr_node *lmb) sprintf(scn->sysfs_path, sysfs_path, mem_scn); scn->phys_addr = phys_addr; - get_int_attribute(scn->sysfs_path, "removable", - &scn->removable, sizeof(scn->removable)); - if (! scn->removable) - lmb->is_removable = 0; + if (!stat(scn->sysfs_path, &sbuf)) { + get_int_attribute(scn->sysfs_path, "removable", + &scn->removable, + sizeof(scn->removable)); + if (!scn->removable) + lmb->is_removable = 0; + } scn->next = lmb->lmb_mem_scns; lmb->lmb_mem_scns = scn; @@ -768,6 +772,7 @@ set_lmb_state(struct dr_node *lmb, int s { struct mem_scn *scn; int rc = 0; + struct stat sbuf; dbg("Attempting to %s lmb.\n", state_strs[state]); @@ -778,6 +783,9 @@ set_lmb_state(struct dr_node *lmb, int s } for (scn = lmb->lmb_mem_scns; scn; scn = scn->next) { + if (stat(scn->sysfs_path, &sbuf)) + continue; + rc = set_mem_scn_state(scn, state); if (rc) break; @@ -790,6 +798,9 @@ set_lmb_state(struct dr_node *lmb, int s int new_state = (state == OFFLINE) ? ONLINE : OFFLINE; for (scn = lmb->lmb_mem_scns; scn; scn = scn->next) { + if (stat(scn->sysfs_path, &sbuf)) + continue; + if (get_mem_scn_state(scn) == state) set_mem_scn_state(scn, new_state); } |
From: Brad P. <bp...@li...> - 2010-07-31 00:13:17
|
Patch updates lscfg path to /usr/sbin, which is where this has been installing to since lsvpd-1.0 was released back in 2007. Would be nice to auto-find the executable, but I'm not sure how we can do that (I'm open to suggestions). At the least, this patch fixes usysident for all modern versions of lsvpd, and it does not make things worse than they were. -- Best regards, Brad Peters IBM Linux on System-P Platform Serviceability Team Lead 15350 SW Koll Parkway 503-578-3493 TL: 775-3493 bp...@li... bp...@us... AIM: bradpeters1000 Signed off by: Brad Peters diff -uNrp powerpc-utils/src/usysident.c powerpc-utils.mod/src/usysident.c --- powerpc-utils/src/usysident.c 2010-07-30 17:05:30.000000000 -0700 +++ powerpc-utils.mod/src/usysident.c 2010-07-30 17:06:57.000000000 -0700 @@ -765,7 +765,7 @@ add_scsi_drives(struct loc_code *l) /* Check for lscfg and sg_map, both required for this routine */ if (stat("/usr/bin/sg_map", &statbuf) < 0) return; - if (stat("/sbin/lscfg", &statbuf) < 0) + if (stat("/usr/sbin/lscfg", &statbuf) < 0) return; if (curr) @@ -870,7 +870,7 @@ add_scsi_drives(struct loc_code *l) curr->next = NULL; /* Add location code (from lscfg) */ - snprintf(cmd, 128, "/sbin/lscfg | grep %s", + snprintf(cmd, 128, "/usr/sbin/lscfg | grep %s", entry->d_name); if ((fp = popen(cmd, "r")) == NULL) { goto err_out; @@ -1161,14 +1161,14 @@ main (int argc, char **argv) if (dvalue) { /* Print/update indicator status for the specified device */ - if (stat("/sbin/lscfg", &statbuf) < 0) { + if (stat("/usr/sbin/lscfg", &statbuf) < 0) { fprintf(stderr, "lsvpd must be installed for the " "-d option to work\n"); return 2; } /* Add location code (from lscfg) */ - snprintf(cmd, 128, "/sbin/lscfg | grep %s", dvalue); + snprintf(cmd, 128, "/usr/sbin/lscfg | grep %s", dvalue); if ((fp = popen(cmd, "r")) == NULL) { fprintf(stderr, "Could not run lscfg to retrieve " "the location code\n"); |
From: Nathan F. <nf...@au...> - 2010-07-12 18:55:10
|
The latest version of powerpc-utils, version 1.2.4, has just been posted to the sourceforge website. https://sourceforge.net/projects/powerpc-utils/files/powerpc-utils/powerpc-utils-1.2.4.tar.gz/download -Nathan |
From: Nathan F. <nf...@au...> - 2010-07-09 15:52:35
|
This patch provides a set of options to report the number of cores online on a system and allow the user to set the number of cores that are online. Signed-off-by: Freeman Rawson <fr...@us...> Acked-by: Nathan Fontenot <nf...@au...> --- README | 3 - src/ppc64_cpu.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 5 deletions(-) Index: powerpc-utils/README =================================================================== --- powerpc-utils.orig/README 2010-06-25 09:00:41.000000000 -0500 +++ powerpc-utils/README 2010-07-09 09:24:53.000000000 -0500 @@ -80,7 +80,8 @@ ppc64_cpu: --------- This allows users to set the smt state, smt-snooze-delay and other settings -on ppc64 processors. +on ppc64 processors. It also allows users to control the number of processor +cores which are online (not in the sleep state). lsdevinfo: --------- Index: powerpc-utils/src/ppc64_cpu.c =================================================================== --- powerpc-utils.orig/src/ppc64_cpu.c 2010-07-09 09:09:08.000000000 -0500 +++ powerpc-utils/src/ppc64_cpu.c 2010-07-09 09:45:08.000000000 -0500 @@ -281,9 +281,11 @@ update_ssd = 0; for (i = 0; i < threads_in_system; i += threads_per_cpu) { - rc = set_one_smt_state(i, smt_state); - if (rc) - break; + if (cpu_online(i)) { + rc = set_one_smt_state(i, smt_state); + if (rc) + break; + } } if (update_ssd) @@ -627,11 +629,121 @@ return 0; } +int do_cores_present(char * state) +{ + printf("Number of cores present = %d\n", cpus_in_system); + return 0; +} + +int set_all_threads_off(int cpu, int smt_state) +{ + int i; + char path[SYSFS_PATH_MAX]; + int rc = 0; + + for (i = cpu + smt_state - 1; i >= cpu; i--) { + snprintf(path, SYSFS_PATH_MAX, SYSFS_CPUDIR"/%s", i, "online"); + rc = offline_thread(path); + if (rc == -1) + printf("Unable to take cpu%d offline", i); + } + + return rc; +} + +int set_one_core(int smt_state, int core, int state) +{ + int rc = 0; + int cpu = core * threads_per_cpu; + + if (state) { + rc = set_one_smt_state(cpu, smt_state); + if (rc == -1) + printf("Unable to bring core %d online\n", core); + } else { + rc = set_all_threads_off(cpu, smt_state); + if (rc == -1) + printf("Unable to take core %d offline\n", core); + } + + return rc; +} + +int do_cores_online(char *state) +{ + int smt_state; + int *core_state; + int cores_now_online = 0; + int i; + int number_to_have, number_to_change = 0, number_changed = 0; + int new_state; + + smt_state = get_smt_state(); + if (smt_state == -1) { + printf("Bad or inconsistent SMT state\n"); + return -1; + } + + core_state = malloc(sizeof(int) * cpus_in_system); + memset(core_state, 0, sizeof(int) * cpus_in_system); + for (i = 0; i < cpus_in_system ; i++) { + core_state[i] = cpu_online(i * threads_per_cpu); + if (core_state[i]) + cores_now_online++; + } + + if (!state) { + printf("Number of cores online = %d\n", cores_now_online); + return 0; + } + + number_to_have = strtol(state, NULL, 0); + if (number_to_have == cores_now_online) + return 0; + + if (number_to_have > cpus_in_system) + number_to_have = cpus_in_system; + + if (number_to_have > cores_now_online) { + number_to_change = number_to_have - cores_now_online; + new_state = 1; + } else { + number_to_change = cores_now_online - number_to_have; + new_state = 0; + } + + if (new_state) { + for (i = 0; i < cpus_in_system; i++) { + if (!core_state[i]) { + set_one_core(smt_state, i, new_state); + number_changed++; + if (number_changed >= number_to_change) + break; + } + } + } else { + for (i = cpus_in_system - 1; i > 0; i--) { + if (core_state[i]) { + set_one_core(smt_state, i, new_state); + number_changed++; + if (number_changed >= number_to_change) + break; + } + } + } + + return 0; +} + void usage(void) { printf("\tppc64_cpu --smt # Get current SMT state\n" "\tppc64_cpu --smt={on|off} # Turn SMT on/off\n" "\tppc64_cpu --smt=X # Set SMT state to X\n\n" + "\tppc64_cpu --cores-present # Get the number of cores installed\n" + "\tppc64_cpu --cores-on # Get the number of cores currently online\n" + "\tppc64_cpu --cores-on=X # Put exactly X cores online\n\n" + "\tppc64_cpu --dscr # Get current DSCR setting\n" "\tppc64_cpu --dscr=<val> # Change DSCR setting\n\n" "\tppc64_cpu --smt-snooze-delay # Get current smt-snooze-delay setting\n" @@ -647,6 +759,8 @@ {"smt-snooze-delay", optional_argument, NULL, 'S'}, {"run-mode", optional_argument, NULL, 'r'}, {"frequency", no_argument, NULL, 'f'}, + {"cores-present", no_argument, NULL, 'C'}, + {"cores-on", optional_argument, NULL, 'c'}, {0,0,0,0} }; @@ -668,7 +782,7 @@ } while (1) { - opt = getopt_long(argc, argv, "s::d::S::r::f", longopts, + opt = getopt_long(argc, argv, "s::d::S::r::fCc::", longopts, &option_index); if (opt == -1) break; @@ -694,6 +808,12 @@ rc = do_cpu_frequency(); break; + case 'C': + rc = do_cores_present(optarg); + break; + case 'c': + rc = do_cores_online(optarg); + break; default: usage(); break; |
From: Nathan F. <nf...@au...> - 2010-07-09 15:25:38
|
Add the capability to determine the cpu frequency on a system to the ppc64_cpu command. This updated patch adds the -lpthread flag to build ppc64_cpu, corrects the help message, and now checks to see if frequency determination is supported. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/Makefile.am | 2 src/Makefile.in | 2 src/ppc64_cpu.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 192 insertions(+), 7 deletions(-) Index: powerpc-utils/src/ppc64_cpu.c =================================================================== --- powerpc-utils.orig/src/ppc64_cpu.c 2010-06-25 09:14:19.000000000 -0500 +++ powerpc-utils/src/ppc64_cpu.c 2010-07-09 09:09:08.000000000 -0500 @@ -7,21 +7,37 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <string.h> #include <dirent.h> #include <librtas.h> #include <sys/stat.h> -#define _GNU_SOURCE #include <getopt.h> +#include <sched.h> +#include <assert.h> +#include <pthread.h> +#include <sys/ioctl.h> +#include <linux/perf_event.h> #include "librtas_error.h" +#include <errno.h> #define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d" #define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s" -#define SYSFS_PATH_MAX 128 +#define SYSFS_PATH_MAX 128 +#define MAX_NR_CPUS 1024 #define DIAGNOSTICS_RUN_MODE 42 +#define CPU_OFFLINE -1 + +static unsigned long long cpu_freq[MAX_NR_CPUS]; +static int counters[MAX_NR_CPUS]; + +#ifndef __NR_perf_event_open +#define __NR_perf_event_open 319 +#endif int threads_per_cpu = 0; int cpus_in_system = 0; @@ -448,17 +464,181 @@ return rc; } +static int setup_counters(void) +{ + int i; + struct perf_event_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_HARDWARE; + attr.config = PERF_COUNT_HW_CPU_CYCLES; + attr.disabled = 1; + attr.size = sizeof(attr); + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + counters[i] = syscall(__NR_perf_event_open, &attr, -1, + i, -1, 0); + + if (counters[i] < 0) { + if (errno == ENOSYS) + fprintf(stderr, "frequency determination " + "not supported with this kernel.\n"); + else + perror("Could not initialize performance " + "counters"); + return -1; + } + } + + return 0; +} + +static void start_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + ioctl(counters[i], PERF_EVENT_IOC_ENABLE); + } +} + +static void stop_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + ioctl(counters[i], PERF_EVENT_IOC_DISABLE); + } +} + +static void read_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + size_t res; + + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + res = read(counters[i], &cpu_freq[i], + sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + + close(counters[i]); + } +} + +static void *soak(void *arg) +{ + unsigned int cpu = (long)arg; + cpu_set_t cpumask; + + CPU_ZERO(&cpumask); + CPU_SET(cpu, &cpumask); + + if (sched_setaffinity(0, sizeof(cpumask), &cpumask)) { + perror("sched_setaffinity"); + exit(1); + } + + while (1) + ; /* Do Nothing */ +} + +int do_cpu_frequency(void) +{ + int i, rc; + unsigned long long min = -1ULL; + unsigned long min_cpu = -1UL; + unsigned long long max = 0; + unsigned long max_cpu = -1UL; + unsigned long long sum = 0; + unsigned long count = 0; + + memset(cpu_freq, 0, sizeof(cpu_freq)); + memset(counters, 0, sizeof(counters)); + + rc = setup_counters(); + if (rc) + return rc; + + /* Start a soak thread on each CPU */ + for (i = 0; i < threads_in_system; i++) { + pthread_t tid; + + if (!cpu_online(i)) { + cpu_freq[i] = CPU_OFFLINE; + continue; + } + + if (pthread_create(&tid, NULL, soak, (void *)(long)i)) { + perror("pthread_create"); + return -1; + } + } + + /* Wait for soak threads to start */ + usleep(1000000); + + start_counters(); + /* Count for 1 second */ + usleep(1000000); + stop_counters(); + + read_counters(); + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + /* No result - Couldn't schedule on that cpu */ + if (cpu_freq[i] == 0) { + printf("WARNING: couldn't run on cpu %d\n", i); + continue; + } + + if (cpu_freq[i] < min) { + min = cpu_freq[i]; + min_cpu = i; + } + if (cpu_freq[i] > max) { + max = cpu_freq[i]; + max_cpu = i; + } + sum += cpu_freq[i]; + count++; + } + + printf("min:\t%.2f GHz (cpu %ld)\n", 1.0 * min / 1000000000ULL, + min_cpu); + printf("max:\t%.2f GHz (cpu %ld)\n", 1.0 * max / 1000000000ULL, + max_cpu); + printf("avg:\t%.2f GHz\n\n", 1.0 * (sum / count) / 1000000000ULL); + return 0; +} + void usage(void) { printf("\tppc64_cpu --smt # Get current SMT state\n" - "\tppc64_cpu --smt={on|off} # Turn SMT on/off\n\n" + "\tppc64_cpu --smt={on|off} # Turn SMT on/off\n" "\tppc64_cpu --smt=X # Set SMT state to X\n\n" "\tppc64_cpu --dscr # Get current DSCR setting\n" "\tppc64_cpu --dscr=<val> # Change DSCR setting\n\n" "\tppc64_cpu --smt-snooze-delay # Get current smt-snooze-delay setting\n" "\tppc64_cpu --smt-snooze-delay=<val> # Change smt-snooze-delay setting\n\n" "\tppc64_cpu --run-mode # Get current diagnostics run mode\n" - "\tppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n"); + "\tppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n" + "\tppc64_cpu --frequency # Determine cpu frequency.\n\n"); } struct option longopts[] = { @@ -466,6 +646,7 @@ {"dscr", optional_argument, NULL, 'd'}, {"smt-snooze-delay", optional_argument, NULL, 'S'}, {"run-mode", optional_argument, NULL, 'r'}, + {"frequency", no_argument, NULL, 'f'}, {0,0,0,0} }; @@ -487,7 +668,7 @@ } while (1) { - opt = getopt_long(argc, argv, "s::d::S::r::", longopts, + opt = getopt_long(argc, argv, "s::d::S::r::f", longopts, &option_index); if (opt == -1) break; @@ -509,6 +690,10 @@ rc = do_run_mode(optarg); break; + case 'f': + rc = do_cpu_frequency(); + break; + default: usage(); break; Index: powerpc-utils/src/Makefile.am =================================================================== --- powerpc-utils.orig/src/Makefile.am 2010-06-25 09:10:59.000000000 -0500 +++ powerpc-utils/src/Makefile.am 2010-07-09 09:17:26.000000000 -0500 @@ -40,4 +40,4 @@ lsprop_SOURCES = lsprop.c ppc64_cpu_SOURCES = ppc64_cpu.c librtas_error.c librtas_error.h -ppc64_cpu_LDFLAGS = -lrtas +ppc64_cpu_LDFLAGS = -lrtas -lpthread Index: powerpc-utils/src/Makefile.in =================================================================== --- powerpc-utils.orig/src/Makefile.in 2010-06-25 09:13:43.000000000 -0500 +++ powerpc-utils/src/Makefile.in 2010-07-09 09:18:17.000000000 -0500 @@ -247,7 +247,7 @@ nvram_LDFLAGS = -ldl lsprop_SOURCES = lsprop.c ppc64_cpu_SOURCES = ppc64_cpu.c librtas_error.c librtas_error.h -ppc64_cpu_LDFLAGS = -lrtas +ppc64_cpu_LDFLAGS = -lrtas -lpthread all: all-recursive .SUFFIXES: |
From: Nathan F. <nf...@au...> - 2010-06-25 15:47:17
|
Add the capability to determine the cpu frequency on a system to the ppc64_cpu command. Signed-off-by: Nathan Fontenot <nf...@au...> --- src/ppc64_cpu.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 4 deletions(-) Index: powerpc-utils/src/ppc64_cpu.c =================================================================== --- powerpc-utils.orig/src/ppc64_cpu.c 2010-06-25 09:14:19.000000000 -0500 +++ powerpc-utils/src/ppc64_cpu.c 2010-06-25 09:28:55.000000000 -0500 @@ -7,21 +7,36 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <string.h> #include <dirent.h> #include <librtas.h> #include <sys/stat.h> -#define _GNU_SOURCE #include <getopt.h> +#include <sched.h> +#include <assert.h> +#include <pthread.h> +#include <sys/ioctl.h> +#include <linux/perf_event.h> #include "librtas_error.h" #define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d" #define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s" -#define SYSFS_PATH_MAX 128 +#define SYSFS_PATH_MAX 128 +#define MAX_NR_CPUS 1024 #define DIAGNOSTICS_RUN_MODE 42 +#define CPU_OFFLINE -1 + +static unsigned long long cpu_freq[MAX_NR_CPUS]; +static int counters[MAX_NR_CPUS]; + +#ifndef __NR_perf_event_open +#define __NR_perf_event_open 319 +#endif int threads_per_cpu = 0; int cpus_in_system = 0; @@ -448,6 +463,164 @@ return rc; } +static int setup_counters(void) +{ + int i; + struct perf_event_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_HARDWARE; + attr.config = PERF_COUNT_HW_CPU_CYCLES; + attr.disabled = 1; + attr.size = sizeof(attr); + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + counters[i] = syscall(__NR_perf_event_open, &attr, -1, + i, -1, 0); + + if (counters[i] < 0) { + perror("sys_perf_event_open"); + return -1; + } + } + + return 0; +} + +static void start_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + ioctl(counters[i], PERF_EVENT_IOC_ENABLE); + } +} + +static void stop_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + ioctl(counters[i], PERF_EVENT_IOC_DISABLE); + } +} + +static void read_counters(void) +{ + int i; + + for (i = 0; i < threads_in_system; i++) { + size_t res; + + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + res = read(counters[i], &cpu_freq[i], + sizeof(unsigned long long)); + assert(res == sizeof(unsigned long long)); + + close(counters[i]); + } +} + +static void *soak(void *arg) +{ + unsigned int cpu = (long)arg; + cpu_set_t cpumask; + + CPU_ZERO(&cpumask); + CPU_SET(cpu, &cpumask); + + if (sched_setaffinity(0, sizeof(cpumask), &cpumask)) { + perror("sched_setaffinity"); + exit(1); + } + + while (1) + ; /* Do Nothing */ +} + +int do_cpu_frequency(void) +{ + int i, rc; + unsigned long long min = -1ULL; + unsigned long min_cpu = -1UL; + unsigned long long max = 0; + unsigned long max_cpu = -1UL; + unsigned long long sum = 0; + unsigned long count = 0; + + memset(cpu_freq, 0, sizeof(cpu_freq)); + memset(counters, 0, sizeof(counters)); + + /* Start a soak thread on each CPU */ + for (i = 0; i < threads_in_system; i++) { + pthread_t tid; + + if (!cpu_online(i)) { + cpu_freq[i] = CPU_OFFLINE; + continue; + } + + if (pthread_create(&tid, NULL, soak, (void *)(long)i)) { + perror("pthread_create"); + return -1; + } + } + + rc = setup_counters(); + if (rc) + return rc; + + /* Wait for soak threads to start */ + usleep(1000000); + + start_counters(); + /* Count for 1 second */ + usleep(1000000); + stop_counters(); + + read_counters(); + + for (i = 0; i < threads_in_system; i++) { + if (cpu_freq[i] == CPU_OFFLINE) + continue; + + /* No result - Couldn't schedule on that cpu */ + if (cpu_freq[i] == 0) { + printf("WARNING: couldn't run on cpu %d\n", i); + continue; + } + + if (cpu_freq[i] < min) { + min = cpu_freq[i]; + min_cpu = i; + } + if (cpu_freq[i] > max) { + max = cpu_freq[i]; + max_cpu = i; + } + sum += cpu_freq[i]; + count++; + } + + printf("min:\t%.2f GHz (cpu %ld)\n", 1.0 * min / 1000000000ULL, + min_cpu); + printf("max:\t%.2f GHz (cpu %ld)\n", 1.0 * max / 1000000000ULL, + max_cpu); + printf("avg:\t%.2f GHz\n\n", 1.0 * (sum / count) / 1000000000ULL); + return 0; +} + void usage(void) { printf("\tppc64_cpu --smt # Get current SMT state\n" @@ -458,7 +631,12 @@ "\tppc64_cpu --smt-snooze-delay # Get current smt-snooze-delay setting\n" "\tppc64_cpu --smt-snooze-delay=<val> # Change smt-snooze-delay setting\n\n" "\tppc64_cpu --run-mode # Get current diagnostics run mode\n" - "\tppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n"); + "\tppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n" + "\tppc64_cpu --frequency=<val> # Determine cpu frequency, " + "<val>\n" + " sets the number of data " + "gathering\n" + " cycles to run\n\n"); } struct option longopts[] = { @@ -466,6 +644,7 @@ {"dscr", optional_argument, NULL, 'd'}, {"smt-snooze-delay", optional_argument, NULL, 'S'}, {"run-mode", optional_argument, NULL, 'r'}, + {"frequency", no_argument, NULL, 'f'}, {0,0,0,0} }; @@ -487,7 +666,7 @@ } while (1) { - opt = getopt_long(argc, argv, "s::d::S::r::", longopts, + opt = getopt_long(argc, argv, "s::d::S::r::f", longopts, &option_index); if (opt == -1) break; @@ -509,6 +688,10 @@ rc = do_run_mode(optarg); break; + case 'f': + rc = do_cpu_frequency(); + break; + default: usage(); break; |