diff -Nru powerpc-utils-1.3.1/Changelog powerpc-utils-1.3.2/Changelog --- powerpc-utils-1.3.1/Changelog 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/Changelog 2016-07-11 21:41:12.000000000 +0000 @@ -1,3 +1,281 @@ +powerpc-utils-1.3.2 +===================================================================== +commit 4e5b9dacf7bbddfb58269fc50de6586a9ac6fdfd +Author: Ulrich Weigand +Date: Mon Jul 11 17:13:17 2016 -0400 + + lparstat: Fix computation of time used in statistics + + The routine get_time computes bogus timestap values due to confusing + seconds and microseconds. This leads to incorrect return values from + elapsed_time and therefore incorrect values for the physc field. + + Fixed by converting the "time" sysentry field to microseconds (and + computing it correctly), and updating the user of elapsed_time. + + In addition, %entc is supposed to show the ratio of physc to the + number of entitled CPUs as *percentage*, so the ratio needs to be + multiplied by 100. + + Signed-off-by: Ulrich Weigand + Signed-off-by: Michael Bringmann + +commit a97c5664f53f9a18dd0b941a842d7884253cf8ed +Author: Nathan Fontenot +Date: Mon Jul 11 17:06:26 2016 -0400 + + drmgr: Disable use of in-kernel cpu hotplug + + After submitting the patch to update drmgr to use the in-kernel hotplug + capabilities for memory and cpu, commit (drmgr: Start using + in-kernel DLPAR functionality for cpu/memory), I realized there + are still distro kernels that do not have the in-kernel cpu hotplug + capabilities. Using the latest drmgr with this update breaks cpu dlpar + because the cpu dlpar code assumes that if the dlpar sysfs file exists + then in-kernel cpu dlpar is possible. this is wrong, the sysfs dlpar file + was added with in-kernel memory hotplug, its existence can only guarantee + memory hotplug capability. + + For now, disable using the in-kernel cpu capabilities by drmgr until + this can be resolved. + + Signed-off-by: Nathan Fontenot + +commit 2bb7599d702d4e1de1ff0f9cbe53329e59c4e120 +Author: Ian Neal +Date: Mon Jul 11 10:02:45 2016 -0400 + + lparstat: flush data to stdout + + The stdout stream is not being flushed after being written to. This + means that it doesn't behave properly in shell pipelines as the data + isn't visible until the program exits. The fix is to simply flush + after writes so the data is immediately available to other processes + in the pipeline. + + Signed-off-by: Ian Neal + +commit c3269d4e3d4882fd931d1df6aece0bec86fb6734 +Author: Vasant Hegde +Date: Thu Jun 30 10:26:58 2016 -0400 + + update_flash: Fix bashism issue in opp_display_current_fw_version() + + Ubuntu uses dash, not bash. We hit below warning on Ubuntu system. + + root@abc:/sys/firmware/devicetree/base/ibm,opal/sensors# update_flash -d + /usr/sbin/update_flash_nv: 595: [: x43: unexpected operator + Firmware version: + .... + .... + + == is a bashism. Replace it with =. + + Fixes: 767e3dd7 (update_flash: Add support for OpenPower system) + Signed-off-by: Vasant Hegde + +commit 386a07c4dc6c09d35116dc6064f7a83d76f4415b +Author: Nathan Fontenot +Date: Tue May 24 16:32:39 2016 -0400 + + errinjct: Correct read_file() error checking + + When reading files from syfs the file length returned from a stat() + call does not always match the actual length of the file. The read_file() + routine should be checking for an error return from the read() call + instead of checking that the amount read matches the file length returned + from a stat() call. + + Signed-off-by: Nathan Fontenot + +commit 42b83884bfb51c0c8b23bf2949157430f8468caa +Author: Nathan Fontenot +Date: Tue May 24 16:31:37 2016 -0400 + + errinjct: Recognize -5 return from rtas + + Update the errinjct command to recognize the rturn code of -5 from + rtas indicating that PCI error injection is not enabled. + + Signed-off-by: Nathan Fontenot + +commit ab848a8d5cc4c4b9f5faef1b31be3982fb7d4bf2 +Author: Nathan Fontenot +Date: Tue May 24 16:30:33 2016 -0400 + + errinjct: Correct config_addr parsing + + A recent patch (commit id: ccc9c72cec2a4) to move the errinjct function to + using a common read_file() routine did not correctly update the + get_config_addr_from_reg() function. This patch corrects this to return the + proper config address. + + Signed-off-by: Nathan Fontenot + +commit 9fc079cf39d999040483a00d3b41000ca3e43013 +Author: John Allen +Date: Tue May 24 16:28:27 2016 -0400 + + drmgr: Workaround for concurrent PRRN collisions + + Proposed workaround for issues with current PRRN event handling mechanism. + + Currently, the mechanism works by kicking off a script that calls a drmgr + remove followed by a drmgr add for each effected device. With this method, + problems can occur when multiple prrn events arrive in a short time span or + when other dlpar operations are happening while the script is running. What + can happen is that these other dlpar operations can jump in inbetween when + the script calls the remove and the add and take the drmgr lock. Then when + we try to add the memory back from the script, we are unable to take the + drmgr lock and the add fails. + + This patch fixes this issue by creating a new -P flag for drmgr which will + perform the necessary removes/adds from within the drmgr lock. The new + option will be invoked as follows: + + drmgr -P + + On the rtas_errd side, we will begin by creating a log file for the + PRRN event which will contain a list of the type and the drc index for + each effected device. Then instead of invoking the script, we will call + the above drmgr command with the path to the prrn log file. Then, on the + drmgr side, we parse the list and perform the necessary removes/adds and + then delete the prrn log file. + + Signed-off-by: John Allen + +commit bbc5fc07c54dd53f4ceac3552ea12717cc86cba2 +Author: Nathan Fontenot +Date: Wed May 11 13:16:19 2016 -0400 + + drmgr: Start using in-kernel DLPAR functionality for cpu/memory + + Now that the capability to do DLPAR of cpus and memory can be + done completely in the kernel, update the drmgr command to use + this functionality. + + The kernel updates provided a sysfs file (/sys/kernel/dlpar) + that will allow the drmgr command invoke DLPAR of cpus and memory + by writing to this file. + + There are some exisitng behaviors of drmgr on the PowerVM platforms + that require cpu and memory to be done slightly differently. For + memory drmgr only needs to report the number of LMBs that were + added or removed so drmgr can just pass all requests straight to + the kernel. This patch also makes a common routine for reporting + memory resources to ensure the format is kept constant. + + For cpu DLPAR the drmgr command has to report the drc name of each + cpu that is added/removed. To do this the command uses much of the + same device tree parsing that is currently used and make a request + to the kernel to remove a specific cpu (by drc index) where a + write to the sysfs probe file was previously done. + + Signed-off-by: Nathan Fontenot + +commit 4dafa57ec7c1498f94b324e671625b0794b92f2f +Author: Thomas Falcon +Date: Tue Apr 19 15:01:13 2016 -0400 + + ppc64_cpu: display error message after set_smt_state_one failure + + This avoids a silent error if threads are unable to be onlined or offlined. + + Signed-off-by: Thomas Falcon + +commit 96745e9e1cb560af6f900b1dac920e36db750ee5 +Author: John Allen +Date: Tue Apr 19 14:52:35 2016 -0400 + + lparstat: Check return value of fopen/popen before dereferencing + + Checks the return value of fopen and popen in several locations to make sure + it's not null. If we pass a null file descriptor to fgets, we will hit a + segfault. + + Signed-off-by: John Allen + Reviewed-by: Vasant Hegde + +commit 6855b92b3f9f3ed9c02065344cc98b965c3f03ef +Author: Michael Roth +Date: Tue Apr 19 14:49:43 2016 -0400 + + drmgr: avoid loading rpadlpar_io/rpaphp when -v flags is used + + The -v / opts->pci_virtio flag was added to provide an alternative way + to scan/remove PCI devices which doesn't rely on rpaphp. That was a + workaround for a bug induced by QEMU emulating PHBs with multiple + hotpluggable slots, which fails to register slots beyond the first due + to rpaphp no longer accounting for the possibility of there being more + than 1 slot per PHB. This leads to warnings of the form: + + kernel: rpaphp: pci_hp_register failed with error -16 + kernel: rpaphp: pci_hp_register failed with error -16 + ... + + For most guest distros this has resulted in the module not being + loaded by default to avoid the errors showing up. + + However, as of a9b4e4e, we now load automatically load the module as + needed, but we don't take opts->pci_virtio into account when + determining if it's needed, leading to PCI hotplug operations to + KVM guests now resulting into rpaphp being loaded and + generating the errors above when drmgr is invoked. + + Fix this by avoiding modprobe of rpadlpar_io/rpaphp when + opts->pci_virtio is set. + + Signed-off-by: Michael Roth + +commit efa87d93231eb0fe4f406bf58e7d5aa783ee4f13 +Author: Michael Bringmann +Date: Tue Apr 19 14:47:32 2016 -0400 + + lparstat: Correct presentation of some stats + + lparstat.c: Currently there are several problems with the presentation + of statistics by lparstat's default output mode. These issues include: + * Showing negative values for certain fields e.g. %user, %sys, %wait, + %lbusy. + * Showing zero values for certain fields e.g. physc, %entc + * Identifying systems with 'Shared' or 'Dedicated' Memory Mode + * Calculating the number if logical CPUs used by a system + This patch looks to correct these issues. It also changes the widths + of the physc, %entc fields which had too little precision available + to show the value change on some systems. + + Signed-off-by: Michael Bringmann + +commit a27c639aca69271aabe7cac287f998b29b82f333 +Author: Michael Roth +Date: Tue Apr 19 14:37:36 2016 -0400 + + drmgr: ensure PCI cleanup is done before offlining dev + + As part of 4f542616, functionality was added to support add/remove + PCI devices without relying on rpaphp hotplug module. The sysfs + write used in the remove path initiates an asynchronous removal of + PCI device from kernel PCI subsystem, and eventually from the sysfs + tree. Afterward, we set the corresponding DRC for the device to + ISOLATED state so host can complete device removal. + + To avoid the situation where the asychronous removal has not yet + completed by the time drmgr sets the state to ISOLATED, and simple + sleep of 3 seconds was added. This seems to have worked out okay + for virtio devices, but in the case of other devices, like PCI + passthrough of a Mellanox CX4 virtual function, the removal can take + up to 20 seconds. + + When this happens, we hit a situation where the host reclaims the + devices while the guest is still attempting to access it in it's + cleanup path, which leads to guest crashes. + + Fix this by polling the PCI devices sysfs path and not completing + the removal until the sysfs path is removed as part of device cleanup. + + Signed-off-by: Michael Roth + + powerpc-utils-1.3.1 ===================================================================== commit dccad2d1dc5c84571f31af3117095bd9ec6e34c4 diff -Nru powerpc-utils-1.3.1/configure.ac powerpc-utils-1.3.2/configure.ac --- powerpc-utils-1.3.1/configure.ac 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/configure.ac 2016-07-11 21:41:12.000000000 +0000 @@ -1,6 +1,6 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -m4_define([ppu_version], 1.3.1) +m4_define([ppu_version], 1.3.2) AC_PREREQ([2.63]) AC_INIT([powerpc-utils], ppu_version, [nfont@linux.vnet.ibm.com]) diff -Nru powerpc-utils-1.3.1/debian/changelog powerpc-utils-1.3.2/debian/changelog --- powerpc-utils-1.3.1/debian/changelog 2016-07-05 22:52:10.000000000 +0000 +++ powerpc-utils-1.3.2/debian/changelog 2016-07-22 23:26:12.000000000 +0000 @@ -1,15 +1,14 @@ -powerpc-utils (1.3.1-2ubuntu1) yakkety; urgency=medium +powerpc-utils (1.3.2-1) unstable; urgency=medium - * debian/patches/bashisms.patch: Fix bashism in update_flash_nv. - Closes LP: #1599191. + * New upstream release, including bashism fix (closes: #830089) - -- Steve Langasek Tue, 05 Jul 2016 15:52:05 -0700 + -- Adam Conrad Fri, 22 Jul 2016 17:18:12 -0600 powerpc-utils (1.3.1-2) unstable; urgency=medium * Don't ship /usr/sbin/snap, it's only used on RHEL and SLES installs. - -- Adam Conrad Sun, 17 Apr 2016 06:46:05 -0600 + -- Adam Conrad Sun, 17 Apr 2016 06:46:05 -0600 powerpc-utils (1.3.1-1) unstable; urgency=medium diff -Nru powerpc-utils-1.3.1/debian/control powerpc-utils-1.3.2/debian/control --- powerpc-utils-1.3.1/debian/control 2016-07-05 22:52:37.000000000 +0000 +++ powerpc-utils-1.3.2/debian/control 2016-04-11 06:24:17.000000000 +0000 @@ -1,8 +1,7 @@ Source: powerpc-utils Section: utils Priority: important -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Adam Conrad +Maintainer: Adam Conrad Uploaders: Frederic Bonnard Build-Depends: debhelper (>= 9), dh-autoreconf, librtas-dev, librtasevent-dev, zlib1g-dev Standards-Version: 3.9.7 diff -Nru powerpc-utils-1.3.1/debian/patches/bashisms.patch powerpc-utils-1.3.2/debian/patches/bashisms.patch --- powerpc-utils-1.3.1/debian/patches/bashisms.patch 2016-07-05 22:51:53.000000000 +0000 +++ powerpc-utils-1.3.2/debian/patches/bashisms.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Author: Steve Langasek -Description: Fix bashism in update_flash_nv - update_flash_nv uses a == operator, which is a bashism. Replace with =. -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1599191 - -Index: powerpc-utils-1.3.1/scripts/update_flash_nv -=================================================================== ---- powerpc-utils-1.3.1.orig/scripts/update_flash_nv -+++ powerpc-utils-1.3.1/scripts/update_flash_nv -@@ -592,7 +592,7 @@ - - echo - id=`ipmitool -I usb fru 2>/dev/null |grep "System Firmware" | cut -d " " -f8 | cut -d ")" -f1` -- if [ "x$id" == "x" ]; then -+ if [ "x$id" = "x" ]; then - error $E_IPMI "Failed to get firmware version." - fi - diff -Nru powerpc-utils-1.3.1/debian/patches/series powerpc-utils-1.3.2/debian/patches/series --- powerpc-utils-1.3.1/debian/patches/series 2016-07-05 22:50:34.000000000 +0000 +++ powerpc-utils-1.3.2/debian/patches/series 2016-04-11 06:22:12.000000000 +0000 @@ -1,3 +1,2 @@ 01_ipmitool_check.patch 02_systool_check.patch -bashisms.patch diff -Nru powerpc-utils-1.3.1/Makefile.am powerpc-utils-1.3.2/Makefile.am --- powerpc-utils-1.3.1/Makefile.am 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/Makefile.am 2016-07-11 21:41:12.000000000 +0000 @@ -147,6 +147,7 @@ src/drmgr/drslot_chrp_phb.c \ src/drmgr/drslot_chrp_slot.c \ src/drmgr/rtas_calls.c \ + src/drmgr/prrn.c \ $(pseries_platform_SOURCES) noinst_HEADERS += \ diff -Nru powerpc-utils-1.3.1/scripts/update_flash_nv powerpc-utils-1.3.2/scripts/update_flash_nv --- powerpc-utils-1.3.1/scripts/update_flash_nv 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/scripts/update_flash_nv 2016-07-11 21:41:12.000000000 +0000 @@ -592,7 +592,7 @@ echo id=`ipmitool -I usb fru 2>/dev/null |grep "System Firmware" | cut -d " " -f8 | cut -d ")" -f1` - if [ "x$id" == "x" ]; then + if [ "x$id" = "x" ]; then error $E_IPMI "Failed to get firmware version." fi diff -Nru powerpc-utils-1.3.1/src/drmgr/common.c powerpc-utils-1.3.2/src/drmgr/common.c --- powerpc-utils-1.3.1/src/drmgr/common.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/common.c 2016-07-11 21:41:12.000000000 +0000 @@ -43,6 +43,8 @@ #define LPARCFG_PATH "/proc/ppc64/lparcfg" +#define SYSFS_DLPAR_FILE "/sys/kernel/dlpar" + static int dr_lock_fd = 0; static long dr_timeout; @@ -115,6 +117,12 @@ && strcmp(opts->ctype, "phb") && strcmp(opts->ctype, "slot")) return 0; + /* We don't use rpadlar_io/rpaphp for PCI operations run with the + * -v / virtio flag, which relies on generic PCI rescan instead + */ + if (opts->ctype && !strcmp(opts->ctype, "pci") && opts->pci_virtio == 1) + return 0; + /* Before checking for dlpar capability, we need to ensure that * rpadlpar_io module is loaded or built into the kernel. This * does make the checking a bit redundant though. @@ -1424,3 +1432,52 @@ { return !strncmp(node->drc_type, "display", 7); } + +/** + * kernel_dlpar_exists + * @brief determine if the sysfs file to do in-kernel dlpar exists + * + * @returns 1 if in-kernel dlpar exists, 0 otherwise. + */ +int kernel_dlpar_exists(void) +{ + struct stat sbuf; + + if (!stat(SYSFS_DLPAR_FILE, &sbuf)) + return 1; + + return 0; +} + +/** + * do_kernel_dlpar + * @brief Use the in-kernel dlpar capabilities to perform the requested + * dlpar operation. + * + * @param cmd command string to write to sysfs + * @returns 0 on success, !0 otherwise + */ +int do_kernel_dlpar(const char *cmd, int cmdlen) +{ + int fd, rc; + + say(DEBUG, "Initiating kernel DLPAR \"%s\"\n", cmd); + + /* write to file */ + fd = open(SYSFS_DLPAR_FILE, O_WRONLY); + if (fd <= 0) { + say(ERROR, "Could not open %s to initiate DLPAR request\n", + SYSFS_DLPAR_FILE); + return -1; + } + + rc = write(fd, cmd, cmdlen); + close(fd); + if (rc <= 0) { + say(ERROR, "Failed: %s\n", strerror(errno)); + return rc; + } + + say(INFO, "Success\n"); + return 0; +} diff -Nru powerpc-utils-1.3.1/src/drmgr/common_cpu.c powerpc-utils-1.3.2/src/drmgr/common_cpu.c --- powerpc-utils-1.3.1/src/drmgr/common_cpu.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/common_cpu.c 2016-07-11 21:41:12.000000000 +0000 @@ -657,6 +657,32 @@ return 0; } +#ifdef NOT_YET +int do_cpu_kernel_dlpar(struct dr_node *cpu, int action) +{ + char cmdbuf[256]; + int offset; + + offset = sprintf(cmdbuf, "%s ", "cpu"); + + switch (action) { + case ADD: + offset += sprintf(cmdbuf + offset, "add "); + break; + case REMOVE: + offset += sprintf(cmdbuf + offset, "remove "); + break; + default: + say(ERROR, "Invalid DRC type specified\n"); + return -EINVAL; + } + + offset += sprintf(cmdbuf + offset, "index 0x%x", cpu->drc_index); + + return do_kernel_dlpar(cmdbuf, offset); +} +#endif + int probe_cpu(struct dr_node *cpu, struct dr_info *dr_info) { @@ -665,40 +691,49 @@ int write_len; int rc = 0; - probe_file = open(CPU_PROBE_FILE, O_WRONLY); - if (probe_file <= 0) { - /* Attempt to add cpu from user-space, this may be an older - * kernel without the infrastructure to handle dlpar. - */ - rc = acquire_cpu(cpu, dr_info); - if (rc) - return rc; - - rc = online_cpu(cpu, dr_info); - if (rc) { - /* Roll back the operation. Is this the correct - * behavior? - */ - say(ERROR, "Unable to online %s\n", cpu->drc_name); - offline_cpu(cpu); - release_cpu(cpu, dr_info); - cpu->unusable = 1; - } - +#ifdef NOT_YET + if (kernel_dlpar_exists()) { + rc = do_cpu_kernel_dlpar(cpu, ADD); } else { - memset(drc_index, 0, DR_STR_MAX); - write_len = sprintf(drc_index, "0x%x", cpu->drc_index); - - say(DEBUG, "Probing cpu 0x%x\n", cpu->drc_index); - rc = write(probe_file, drc_index, write_len); - if (rc != write_len) - say(ERROR, "Probe failed! rc = %x\n", rc); - else - /* reset rc to success */ - rc = 0; +#endif + probe_file = open(CPU_PROBE_FILE, O_WRONLY); + if (probe_file <= 0) { + /* Attempt to add cpu from user-space, this may be + * an older kernel without the infrastructure to + * handle dlpar. + */ + rc = acquire_cpu(cpu, dr_info); + if (rc) + return rc; + + rc = online_cpu(cpu, dr_info); + if (rc) { + /* Roll back the operation. Is this the + * correct behavior? + */ + say(ERROR, "Unable to online %s\n", + cpu->drc_name); + offline_cpu(cpu); + release_cpu(cpu, dr_info); + cpu->unusable = 1; + } + } else { + memset(drc_index, 0, DR_STR_MAX); + write_len = sprintf(drc_index, "0x%x", cpu->drc_index); + + say(DEBUG, "Probing cpu 0x%x\n", cpu->drc_index); + rc = write(probe_file, drc_index, write_len); + if (rc != write_len) + say(ERROR, "Probe failed! rc = %x\n", rc); + else + /* reset rc to success */ + rc = 0; - close(probe_file); + close(probe_file); + } +#ifdef NOT_YET } +#endif if (!rc) { update_cpu_node(cpu, NULL, dr_info); @@ -762,6 +797,11 @@ int release_file; int rc; +#ifdef NOT_YET + if (kernel_dlpar_exists()) + return do_cpu_kernel_dlpar(cpu, REMOVE); +#endif + release_file = open(CPU_RELEASE_FILE, O_WRONLY); if (release_file > 0) { /* DLPAR can be done in kernel */ diff -Nru powerpc-utils-1.3.1/src/drmgr/common_pci.c powerpc-utils-1.3.2/src/drmgr/common_pci.c --- powerpc-utils-1.3.1/src/drmgr/common_pci.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/common_pci.c 2016-07-11 21:41:12.000000000 +0000 @@ -32,6 +32,9 @@ #include "drpci.h" #include "ofdt.h" +/* maximum seconds to wait for pci device removal */ +#define PCI_REMOVE_TIMEOUT_MAX 60 + /** * alloc_node * @@ -1163,6 +1166,7 @@ int rc = 0; FILE *file; char path[DR_PATH_MAX]; + int wait_time = 0; sprintf(path, "%s/%s", node->sysfs_dev_path, "remove"); file = fopen(path, "w"); @@ -1176,6 +1180,34 @@ rc = -EACCES; fclose(file); + + if (rc == -EACCES) + return rc; + + do { + struct stat sb; + + rc = stat(node->sysfs_dev_path, &sb); + if (rc) { + rc = -errno; + } else { + say(DEBUG, + "waiting for PCI device driver to quiesce device at %s\n", + node->sysfs_dev_path); + sleep(1); + } + } while (rc == 0 && + (++wait_time < PCI_REMOVE_TIMEOUT_MAX && !drmgr_timed_out())); + + if (rc == 0) { + say(ERROR, "timeout while quiescing device at %s\n", + node->sysfs_dev_path); + rc = -EBUSY; + } else if (rc == -ENOENT) { + /* sysfs entries cleaned up as part of device removal */ + rc = 0; + } + return rc; } diff -Nru powerpc-utils-1.3.1/src/drmgr/dr.h powerpc-utils-1.3.2/src/drmgr/dr.h --- powerpc-utils-1.3.1/src/drmgr/dr.h 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/dr.h 2016-07-11 21:41:12.000000000 +0000 @@ -78,6 +78,7 @@ char *ctype; char *p_option; int pci_virtio; /* qemu virtio device (legacy guest workaround) */ + char *prrn_filename; }; enum say_level { ERROR = 1, WARN, INFO, DEBUG, EXTRA_DEBUG}; @@ -157,4 +158,10 @@ int ams_balloon_active(void); int is_display_adapter(struct dr_node *); + +#define PRRN_TIMEOUT 30 +int handle_prrn(char *filename); + +int kernel_dlpar_exists(void); +int do_kernel_dlpar(const char *, int); #endif diff -Nru powerpc-utils-1.3.1/src/drmgr/drmgr.c powerpc-utils-1.3.2/src/drmgr/drmgr.c --- powerpc-utils-1.3.1/src/drmgr/drmgr.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/drmgr.c 2016-07-11 21:41:12.000000000 +0000 @@ -29,7 +29,7 @@ #include "dr.h" #include "pseries_platform.h" -#define DRMGR_ARGS "ac:d:Iimnp:Qq:Rrs:w:t:hCV" +#define DRMGR_ARGS "ac:d:Iimnp:P:Qq:Rrs:w:t:hCV" int output_level = 1; /* default to lowest output level */ @@ -37,6 +37,7 @@ int action_cnt = 0; static int display_capabilities = 0; +static int handle_prrn_event = 0; static int display_usage = 0; typedef int (cmd_func_t)(struct options *); @@ -217,6 +218,10 @@ case 'p': opts->p_option = optarg; break; + case 'P': + opts->prrn_filename = optarg; + handle_prrn_event = 1; + break; case 'q': opts->quantity = strtoul(optarg, NULL, 0); break; @@ -334,8 +339,13 @@ parse_options(argc, argv, &opts); rc = dr_init(&opts); - if (rc) + if (rc) { + if (handle_prrn_event) { + say(ERROR, "Failed to handle PRRN event\n"); + unlink(opts.prrn_filename); + } return rc; + } if (display_capabilities) { print_dlpar_capabilities(); @@ -343,6 +353,15 @@ return 0; } + if (handle_prrn_event) { + rc = handle_prrn(opts.prrn_filename); + if (rc) + say(ERROR, "Failed to handle PRRN event\n"); + unlink(opts.prrn_filename); + dr_fini(); + return rc; + } + command = get_command(&opts); if (display_usage) { diff -Nru powerpc-utils-1.3.1/src/drmgr/drslot_chrp_mem.c powerpc-utils-1.3.2/src/drmgr/drslot_chrp_mem.c --- powerpc-utils-1.3.1/src/drmgr/drslot_chrp_mem.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/drslot_chrp_mem.c 2016-07-11 21:41:12.000000000 +0000 @@ -50,6 +50,21 @@ } /** + * report_resource_count + * @brief Report the number of LMBs that were added or removed. + * + * Note that the format of this message is what is expected by the HMC, + * or other agent communicating through the RMC framework, and should not + * be changed. + * + * @param count number of LMBs + */ +static void report_resource_count(int count) +{ + printf("DR_TOTAL_RESOURCES=%d\n", count); +} + +/** * get_phandle * * @param char * device tree node path @@ -1090,7 +1105,7 @@ say(DEBUG, "Added %d of %d requested LMB(s)\n", lmb_list->lmbs_modified, opts->quantity); - printf("DR_TOTAL_RESOURCES=%d\n", lmb_list->lmbs_modified); + report_resource_count(lmb_list->lmbs_modified); free_lmbs(lmb_list); return rc; @@ -1215,7 +1230,7 @@ if (lmb_list->lmbs_modified < requested) say(ERROR, "Unable to hotplug remove the remaining %d LMB(s)\n", requested - lmb_list->lmbs_modified); - printf("DR_TOTAL_RESOURCES=%d\n", lmb_list->lmbs_modified); + report_resource_count(lmb_list->lmbs_modified); free_lmbs(lmb_list); return rc; @@ -1311,6 +1326,45 @@ return 0; } +int do_mem_kernel_dlpar(struct options *opts) +{ + char cmdbuf[128]; + int rc, offset; + + offset = sprintf(cmdbuf, "%s ", "memory"); + + switch (opts->action) { + case ADD: + offset += sprintf(cmdbuf + offset, "add "); + break; + case REMOVE: + offset += sprintf(cmdbuf + offset, "remove "); + break; + default: + say(ERROR, "Invalid DRC type specified\n"); + return -EINVAL; + } + + if (opts->usr_drc_index) + offset += sprintf(cmdbuf + offset, "index 0x%x", + opts->usr_drc_index); + else + offset += sprintf(cmdbuf + offset, "count %d", opts->quantity); + + rc = do_kernel_dlpar(cmdbuf, offset); + + /* Memory DLPAR in the kernel is handled as an all-or-nothing + * request, we either add all the requested LMBs or add none + * of them. + */ + if (rc) + report_resource_count(0); + else + report_resource_count(opts->quantity); + + return rc; +} + int drslot_chrp_mem(struct options *opts) { @@ -1333,14 +1387,18 @@ if (opts->usr_drc_name) opts->quantity = 1; - switch (opts->action) { - case ADD: - rc = mem_add(opts); - break; + if (kernel_dlpar_exists()) { + rc = do_mem_kernel_dlpar(opts); + } else { + switch (opts->action) { + case ADD: + rc = mem_add(opts); + break; - case REMOVE: - rc = mem_remove(opts); - break; + case REMOVE: + rc = mem_remove(opts); + break; + } } return rc; diff -Nru powerpc-utils-1.3.1/src/drmgr/prrn.c powerpc-utils-1.3.2/src/drmgr/prrn.c --- powerpc-utils-1.3.1/src/drmgr/prrn.c 1970-01-01 00:00:00.000000000 +0000 +++ powerpc-utils-1.3.2/src/drmgr/prrn.c 2016-07-11 21:41:12.000000000 +0000 @@ -0,0 +1,59 @@ +#include +#include +#include +#include "dr.h" +#include "drmem.h" +#include "drcpu.h" + +int handle_prrn(char *filename) +{ + struct options opts; + char fmt_drc[11]; + char type[4]; + char drc[9]; + int rc = 0; + FILE *fd; + + fd = fopen(filename, "r"); + if (!fd) { + say(ERROR, "Failed to open the file %s\n", filename); + return -1; + } + + set_output_level(4); + + memset(&opts, 0, sizeof(opts)); + + while (fscanf(fd, "%3s %8s\n", type, drc) == 2) { + /* Set up options struct */ + opts.ctype = type; + sprintf(fmt_drc, "0x%s", drc); + opts.usr_drc_name = fmt_drc; + + set_timeout(PRRN_TIMEOUT); + + if (!strcmp(type, "mem")) { + opts.action = REMOVE; + rc = drslot_chrp_mem(&opts); + if (rc) + continue; + + opts.action = ADD; + drslot_chrp_mem(&opts); + } else if (!strcmp(type, "cpu")) { + opts.action = REMOVE; + rc = drslot_chrp_cpu(&opts); + if (rc) + continue; + + opts.action = ADD; + drslot_chrp_cpu(&opts); + } else { + say(ERROR, "Device type \"%s\" not recognized.\n", + type); + continue; + } + } + + return 0; +} diff -Nru powerpc-utils-1.3.1/src/errinjct/errinjct.c powerpc-utils-1.3.2/src/errinjct/errinjct.c --- powerpc-utils-1.3.1/src/errinjct/errinjct.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/errinjct/errinjct.c 2016-07-11 21:41:12.000000000 +0000 @@ -398,6 +398,10 @@ perr(0, "RTAS: %s: The error injection facility is not open\n" "or you are not the one that opened it", ei_func->name); break; + case -5: /* PCI injection not enabled */ + perr(0, "RTAS: %s: PCI Error Injection is not enabled (not " + "available)\n", ei_func->name); + break; case -1001: /* RTAS_KERNEL_INT */ perr(0, "librtas: No Kernel Interface to Firmware"); break; @@ -680,10 +684,8 @@ len = read(fd, buf, sbuf.st_size); close(fd); - if (len != sbuf.st_size) { - perr(errno, "Error reading data from file %s\n" - "expected to read %d but got %d\n", fname, - sbuf.st_size, len); + if (len <= 0) { + perr(errno, "Error reading data from file %s\n", fname); free(buf); return NULL; } diff -Nru powerpc-utils-1.3.1/src/errinjct/ioa_bus_error.c powerpc-utils-1.3.2/src/errinjct/ioa_bus_error.c --- powerpc-utils-1.3.1/src/errinjct/ioa_bus_error.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/errinjct/ioa_bus_error.c 2016-07-11 21:41:12.000000000 +0000 @@ -201,6 +201,7 @@ { char path[BUFSZ]; char *buf; + uint32_t *be_caddr; uint32_t caddr = 0; strncpy(path, devpath, BUFSZ-5); @@ -210,10 +211,11 @@ if (!buf) return 1; - caddr = be32toh((uint32_t)buf[0]); + be_caddr = (uint32_t *)buf; + caddr = be32toh(*be_caddr); free(buf); - return be32toh(caddr); + return caddr; } /** diff -Nru powerpc-utils-1.3.1/src/lparstat.c powerpc-utils-1.3.2/src/lparstat.c --- powerpc-utils-1.3.1/src/lparstat.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/lparstat.c 2016-07-11 21:41:12.000000000 +0000 @@ -78,7 +78,8 @@ gettimeofday(&t, 0); se = get_sysentry("time"); - sprintf(se->value, "%ld", t.tv_sec + t.tv_usec); + sprintf(se->value, "%lld", + (long long)t.tv_sec * 1000000LL + (long long)t.tv_usec); } long long elapsed_time() @@ -101,6 +102,11 @@ struct sysentry *se; f = fopen("/proc/cpuinfo", "r"); + if (!f) { + fprintf(stderr, "Could not open /proc/cpuinfo\n"); + return -1; + } + while ((fgets(buf, 80, f)) != NULL) { if (!strncmp(buf, "timebase", 8)) { tb = strchr(buf, ':') + 2; @@ -124,7 +130,7 @@ float new_purr, old_purr; float timebase, physc; - elapsed = elapsed_time(); + elapsed = elapsed_time() / 1000000.0; se = get_sysentry("timebase"); timebase = atoi(se->value); @@ -134,7 +140,7 @@ old_purr = strtoll(se->old_value, NULL, 0); physc = (new_purr - old_purr)/timebase/elapsed; - sprintf(buf, "%.2f", physc); + sprintf(buf, "%.6f", physc); } void get_per_entc(struct sysentry *unused_se, char *buf) @@ -146,7 +152,7 @@ get_sysdata("DesEntCap", &descr, entc); get_sysdata("physc", &descr, physc); - sprintf(buf, "%.2f", atof(physc) / atof(entc)); + sprintf(buf, "%.6f", atof(physc) / atof(entc) * 100.0); } int parse_lparcfg() @@ -203,6 +209,11 @@ long long int phint = 0; f = fopen("/proc/interrupts", "r"); + if (!f) { + fprintf(stderr, "Could not open /proc/interrupts\n"); + return -1; + } + while (fgets(line, 512, f) != NULL) { /* we just need the SPU line */ if (line[0] != 'S' || line[1] != 'P' || line[2] != 'U') @@ -237,6 +248,11 @@ /* we just need the first line */ f = fopen("/proc/stat", "r"); + if (!f) { + fprintf(stderr, "Could not open /proc/stat\n"); + return -1; + } + first_line = fgets(line, 128, f); fclose(f); @@ -318,16 +334,21 @@ { struct sysentry *tmp; - tmp = get_sysentry("pool_capacity"); - sprintf(buf, "%d", atoi(tmp->value)/100); + tmp = get_sysentry("physical_procs_allocated_to_virtualization"); + if (tmp) { + sprintf(buf, "%d", atoi(tmp->value)); + } else { + 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') + tmp = get_sysentry("entitled_memory_pool_number"); + if (atoi(tmp->value) == 65535) sprintf(buf, "Dedicated"); else sprintf(buf, "Shared"); @@ -376,6 +397,11 @@ char *mem, *nl, *first_line; f = fopen("/proc/meminfo", "r"); + if (!f) { + fprintf(stderr, "Could not open /proc/meminfo\n"); + return; + } + first_line = fgets(line, 128, f); fclose(f); @@ -403,6 +429,11 @@ char *first_line; f = popen(cmd, "r"); + if (!f) { + fprintf(stderr, "Failed to execute %s\n", cmd); + return; + } + first_line = fgets(line, 128, f); pclose(f); @@ -485,7 +516,7 @@ void print_default_output(int interval, int count) { - char *fmt = "%5s %5s %5s %5s %5s %5s %5s %5s %5s\n"; + char *fmt = "%5s %5s %5s %8s %8s %5s %5s %5s %5s\n"; char *descr; char buf[128]; int offset; @@ -534,6 +565,7 @@ fprintf(stdout, fmt, user, sys, wait, idle, physc, entc, lbusy, vcsw, phint); + fflush(stdout); } while (--count > 0); } diff -Nru powerpc-utils-1.3.1/src/ppc64_cpu.c powerpc-utils-1.3.2/src/ppc64_cpu.c --- powerpc-utils-1.3.1/src/ppc64_cpu.c 2016-03-28 16:01:28.000000000 +0000 +++ powerpc-utils-1.3.2/src/ppc64_cpu.c 2016-07-11 21:41:12.000000000 +0000 @@ -482,8 +482,10 @@ if (update_ssd) set_smt_snooze_delay(ssd); - if (error) + if (error) { + fprintf(stderr, "One or more cpus could not be on/offlined\n"); return -1; + } return rc; }