From patchwork Fri Apr 22 04:51:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shilpasri G Bhat X-Patchwork-Id: 613379 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3qrjxv0QjWz9t3s; Fri, 22 Apr 2016 14:56:19 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1atT8Z-0007CC-R7; Fri, 22 Apr 2016 04:56:15 +0000 Received: from e28smtp05.in.ibm.com ([125.16.236.5]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1atT4B-0006cm-GR for fwts-devel@lists.ubuntu.com; Fri, 22 Apr 2016 04:51:43 +0000 Received: from localhost by e28smtp05.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 22 Apr 2016 10:21:41 +0530 Received: from d28relay05.in.ibm.com (9.184.220.62) by e28smtp05.in.ibm.com (192.168.1.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 22 Apr 2016 10:21:40 +0530 X-IBM-Helo: d28relay05.in.ibm.com X-IBM-MailFrom: shilpa.bhat@linux.vnet.ibm.com X-IBM-RcptTo: fwts-devel@lists.ubuntu.com Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay05.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u3M4pcV565929424 for ; Fri, 22 Apr 2016 10:21:39 +0530 Received: from d28av03.in.ibm.com (localhost [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u3M4pcaM024564 for ; Fri, 22 Apr 2016 10:21:38 +0530 Received: from localhost.in.ibm.com ([9.124.35.159]) by d28av03.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u3M4paDf024488; Fri, 22 Apr 2016 10:21:36 +0530 From: Shilpasri G Bhat To: fwts-devel@lists.ubuntu.com Subject: [PATCH] cpufreq: Add test cases to validate the frequency and pstate table Date: Fri, 22 Apr 2016 10:21:35 +0530 Message-Id: <1461300695-20159-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-Mailer: git-send-email 1.9.3 X-TM-AS-MML: disable x-cbid: 16042204-0017-0000-0000-00001E30535D X-Mailman-Approved-At: Fri, 22 Apr 2016 04:56:14 +0000 Cc: Shilpasri G Bhat X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: fwts-devel-bounces@lists.ubuntu.com Add test case to parse CPU frequency and pstate table to check for invalid entries that are beyond the specified minimum and maximum limits. Signed-off-by: Shilpasri G Bhat --- src/cpu/cpufreq/cpufreq.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/src/cpu/cpufreq/cpufreq.c b/src/cpu/cpufreq/cpufreq.c index 8ab5292..1a9c9fd 100644 --- a/src/cpu/cpufreq/cpufreq.c +++ b/src/cpu/cpufreq/cpufreq.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -393,6 +394,142 @@ static int cpufreq_test_cpu_performance(fwts_framework *fw) return FWTS_OK; } +static int cpufreq_test_frequency_limits(fwts_framework *fw) +{ + char path[PATH_MAX]; + int min, max, i; + bool ok = true; + + cpu_mkpath(path, sizeof(path), &cpus[0], "cpuinfo_min_freq"); + if (fwts_get_int(path, &min) != FWTS_OK) { + fwts_log_warning(fw, "Failed to read the minimum CPU frequency %s", + path); + return FWTS_ERROR; + } + + cpu_mkpath(path, sizeof(path), &cpus[0], "cpuinfo_max_freq"); + if (fwts_get_int(path, &max) != FWTS_OK) { + fwts_log_warning(fw, "Failed to read the maximum CPU frequency %s", + path); + return FWTS_ERROR; + } + + for (i = 0; i < cpus[0].n_freqs; i++) { + if (cpus[0].freqs[i].Hz > (uint64_t)max) { + fwts_log_warning(fw, "%s is greater than max frequency %s", + hz_to_human(cpus[0].freqs[i].Hz), + hz_to_human(max)); + ok = false; + } + if (cpus[0].freqs[i].Hz < (uint64_t)min) { + fwts_log_warning(fw, "%s is lesser than min frequency %s", + hz_to_human(cpus[0].freqs[i].Hz), + hz_to_human(min)); + ok = false; + } + } + if (ok) + fwts_passed(fw, "CPU frequencies are within the min and max limits"); + else + fwts_failed(fw, LOG_LEVEL_MEDIUM, "CPUFreqLimitsTest", + "Contains frequencies beyond max and min limits"); + return FWTS_OK; +} + +static int read_device_tree_file(const char *path, int *val) +{ + int fd; + + fd = open(path, O_RDONLY); + if (fd < 0) + return fd; + + if (read(fd, val, sizeof(*val)) < 0) + return FWTS_ERROR; + + *val = be32toh(*val); + close(fd); + return FWTS_OK; +} + +static int read_device_tree_array(const char *path, int *arr, int *len) +{ + int fd; + int i = 0; + + fd = open(path, O_RDONLY); + if (fd < 0) + return fd; + + while(1) { + if (read(fd, (arr + i), sizeof(arr[i])) <= 0) + break; + arr[i] = be32toh(arr[i]); + i++; + } + + *len = (!i) ? i : i - 1; + close(fd); + return FWTS_OK; +} + +static int cpufreq_test_pstate_limits(fwts_framework *fw) +{ + char *dev_tree_path = "/proc/device-tree/ibm,opal/power-mgt/"; + int pstate_min, pstate_max, pstates[MAX_FREQS], nr_pstates, len; + char path[PATH_MAX]; + bool ok = true; + int i; + +#if !defined(__PPC64__) + fwts_skipped(fw, "Test case applicable to PPC64 only"); + return FWTS_SKIP; +#endif + + snprintf(path, sizeof(path), "%sibm,pstate-max", dev_tree_path); + if (read_device_tree_file(path, &pstate_max) < 0) { + fwts_log_warning(fw, "Failed to read the max pstate %s\n", path); + return FWTS_ERROR; + } + + snprintf(path, sizeof(path), "%sibm,pstate-min", dev_tree_path); + if (read_device_tree_file(path, &pstate_min) < 0) { + fwts_log_warning(fw, "Failed to read the min pstate %s\n", path); + return FWTS_ERROR; + } + + snprintf(path, sizeof(path), "%sibm,pstate-ids", dev_tree_path); + if (read_device_tree_array(path, pstates, &len) < 0 || !len) { + fwts_log_warning(fw, "Failed to read the pstate-id array %s\n", path); + return FWTS_ERROR; + } + + nr_pstates = pstate_max - pstate_min; + if (len != nr_pstates) + fwts_log_warning(fw, "Wrong number of pstates. Expected %d pstates, but found %d pstates\n", + nr_pstates, len); + + for (i = 0; i < nr_pstates; i++) { + if (pstates[i] > pstate_max) { + fwts_log_warning(fw, "Invalid Pstate id %d greater than max pstate %d\n", + pstates[i], pstate_max); + ok = false; + } + if (pstates[i] < pstate_min) { + fwts_log_warning(fw, "Invalid Pstate id %d lesser than min pstate %d\n", + pstates[i], pstate_min); + ok = false; + } + } + + if (ok) + fwts_passed(fw, "CPU pstates are within the min and max limits"); + else + fwts_failed(fw, LOG_LEVEL_MEDIUM, "CPUPstateLimitsTest", + "Contains pstates beyond max and min limits"); + return FWTS_OK; +} + static int sw_tests_possible(fwts_framework *fw) { int i, online_cpus = 0; @@ -861,6 +998,8 @@ static fwts_framework_minor_test cpufreq_tests[] = { { cpufreq_test_sw_any, "CPU frequency SW_ANY control" }, { cpufreq_test_sw_all, "CPU frequency SW_ALL control" }, { cpufreq_test_cpu_performance, "CPU frequency performance tests." }, + { cpufreq_test_frequency_limits, "CPU frequency limits test" }, + { cpufreq_test_pstate_limits, "CPU Pstate limits test (device_tree)" }, { NULL, NULL } };