Received: by 10.223.176.46 with SMTP id f43csp2624480wra; Mon, 22 Jan 2018 00:18:42 -0800 (PST) X-Google-Smtp-Source: AH8x225GKh+PCup0ZiSn4jjLtg68BI/rdHp8cz8xciQ7wVKLGCXVTGp3aZ1hEDLE6JDu1cyRqYeq X-Received: by 2002:a17:902:8a8a:: with SMTP id p10-v6mr2903357plo.261.1516609122284; Mon, 22 Jan 2018 00:18:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516609122; cv=none; d=google.com; s=arc-20160816; b=Kq8qipO7YJOB7P0iSbc5+3EXua+bJHmW6BjL1aYPH/pMCdQi1cQp+SZKDQZWzq2n8p aPwaxrbGKkmjw+Uklz2irpQ/5q0Z5PScB4O7BSv+L7Orv2NA2UjAmaoZKApm9QSJ9Y78 FqNGNVWilRAw+bK7Qh+z6YXONXVmwHy6JH10qb0ybh/ZsYOtlJvSQrIEolRPN4nbczit 6ZY6QSfmA16MaV9Kk7qBPfAr1fdd8yCyoz2kWBWz2nCny+36QDcjXHroF/DzppeKKUAN h5q6nGyfqTD3rM6SXd4E+iFw+bQr20zoWqHtW14rFvtW+HbY8DS5hV7wS+zNHKwVoosC rOzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=R9BNCQPGaukaqIu3GWc+/1ENu/Q8scBbVZLwv1/SQy0=; b=i1dDEIZXmqqv9j9JL9AzcXHjJDmBajJTiN/J9YW4zUWSAmd/B1Dw9USZTrDb+V3NUY H0iVWEZB7nV1L1y78E7qOu0SZEvZwSbTvg0r88Y9BTI7b77QF+QUrc1xl7YcflMuORcK Sv1dXTd4YxyXobVUVboGPDliwUS0mSVREMDkh+2tQZdFM4m0FruRGf0g5qxhkC057gie DVRXtdiIoj2o4KORgJL/YNq9IEuFO/72egh1hIxy7L79UhTpPoPsPC0rjEjx/rG57OtC yCUX3JjDJA59rxtBP8/BLdevi7cBlD4A2ePSPkccc3el/dPvfzt9fmgV7Y7w0OIu+9VM iTIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i2si15155369pfi.190.2018.01.22.00.18.26; Mon, 22 Jan 2018 00:18:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751140AbeAVIRs (ORCPT + 99 others); Mon, 22 Jan 2018 03:17:48 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:55904 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751037AbeAVIRp (ORCPT ); Mon, 22 Jan 2018 03:17:45 -0500 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0M8EooX074722 for ; Mon, 22 Jan 2018 03:17:44 -0500 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0b-001b2d01.pphosted.com with ESMTP id 2fn8ja7qbf-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 22 Jan 2018 03:17:44 -0500 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Jan 2018 08:17:42 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 22 Jan 2018 08:17:39 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w0M8Hcah46530632; Mon, 22 Jan 2018 08:17:38 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D405A11C064; Mon, 22 Jan 2018 08:11:17 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 570F511C04A; Mon, 22 Jan 2018 08:11:16 +0000 (GMT) Received: from oc0383214508.ibm.com (unknown [9.124.35.222]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 22 Jan 2018 08:11:16 +0000 (GMT) From: Abhishek Goel To: viresh.kumar@linaro.org, benh@kernel.crashing.org, paulus@samba.org, rjw@rjwysocki.net, mpe@ellerman.id.au, linux-pm@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Cc: Abhishek Goel Subject: [PATCH v3] cpufreq: powernv: Add support of frequency domain Date: Mon, 22 Jan 2018 13:47:34 +0530 X-Mailer: git-send-email 1.8.3.1 X-TM-AS-GCONF: 00 x-cbid: 18012208-0040-0000-0000-0000042764D4 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18012208-0041-0000-0000-000020CAE202 Message-Id: <1516609054-13244-1-git-send-email-huntbag@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-01-22_03:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801220122 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Frequency-domain indicates group of CPUs that would share same frequency. It is detected using device-tree node "frequency-domain-indicator". frequency-domain-indicator is a bitmask which will have different value depending upon the generation of the processor. CPUs of the same chip for which the result of a bitwise AND between their PIR and the frequency-domain-indicator is the same share the same frequency. In this patch, we define hash-table indexed by the aforementioned bitwise ANDed value to store the cpumask of the CPUs sharing the same frequency domain. Further, the cpufreq policy will be created per frequency-domain So for POWER9, a cpufreq policy is created per quad while for POWER8 it is created per core. Governor decides frequency for each policy but multiple cores may come under same policy. In such case frequency needs to be set on each core sharing that policy. Signed-off-by: Abhishek Goel --- Skiboot patch required for the corresponding device-tree changes have been posted here : http://patchwork.ozlabs.org/patch/862256/ drivers/cpufreq/powernv-cpufreq.c | 104 ++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index b6d7c4c..aab23a4 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -37,6 +37,7 @@ #include /* Required for cpu_sibling_mask() in UP configs */ #include #include +#include #define POWERNV_MAX_PSTATES 256 #define PMSR_PSAFE_ENABLE (1UL << 30) @@ -130,6 +131,9 @@ enum throttle_reason_type { static int nr_chips; static DEFINE_PER_CPU(struct chip *, chip_info); +static u32 freq_domain_indicator; +static bool p9_occ_quirk; + /* * Note: * The set of pstates consists of contiguous integers. @@ -194,6 +198,38 @@ static inline void reset_gpstates(struct cpufreq_policy *policy) gpstates->last_gpstate_idx = 0; } +#define SIZE NR_CPUS +#define ORDER_FREQ_MAP ilog2(SIZE) + +static DEFINE_HASHTABLE(freq_domain_map, ORDER_FREQ_MAP); + +struct hashmap { + cpumask_t mask; + int chip_id; + u32 pir_key; + struct hlist_node hash_node; +}; + +static void insert(u32 key, int cpu) +{ + struct hashmap *data; + + hash_for_each_possible(freq_domain_map, data, hash_node, key%SIZE) { + if (data->chip_id == cpu_to_chip_id(cpu) && + data->pir_key == key) { + cpumask_set_cpu(cpu, &data->mask); + return; + } + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + hash_add(freq_domain_map, &data->hash_node, key%SIZE); + cpumask_set_cpu(cpu, &data->mask); + data->chip_id = cpu_to_chip_id(cpu); + data->pir_key = key; + +} + /* * Initialize the freq table based on data obtained * from the firmware passed via device-tree @@ -206,6 +242,7 @@ static int init_powernv_pstates(void) u32 len_ids, len_freqs; u32 pstate_min, pstate_max, pstate_nominal; u32 pstate_turbo, pstate_ultra_turbo; + u32 key; power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); if (!power_mgt) { @@ -246,9 +283,18 @@ static int init_powernv_pstates(void) else powernv_pstate_info.wof_enabled = true; + if (of_device_is_compatible(power_mgt, "freq-domain-v1") && + of_property_read_u32(power_mgt, "ibm,freq-domain-indicator", + &freq_domain_indicator)) + pr_warn("ibm,freq-domain-indicator not found\n"); + + if (of_device_is_compatible(power_mgt, "p9-occ-quirk")) + p9_occ_quirk = true; + next: pr_info("cpufreq pstate min %d nominal %d max %d\n", pstate_min, pstate_nominal, pstate_max); + pr_info("frequency domain indicator %d", freq_domain_indicator); pr_info("Workload Optimized Frequency is %s in the platform\n", (powernv_pstate_info.wof_enabled) ? "enabled" : "disabled"); @@ -276,6 +322,15 @@ static int init_powernv_pstates(void) return -ENODEV; } + if (freq_domain_indicator) { + hash_init(freq_domain_map); + for_each_possible_cpu(i) { + key = ((u32) get_hard_smp_processor_id(i) & + freq_domain_indicator); + insert(key, i); + } + } + powernv_pstate_info.nr_pstates = nr_pstates; pr_debug("NR PStates %d\n", nr_pstates); for (i = 0; i < nr_pstates; i++) { @@ -760,25 +815,56 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy, spin_unlock(&gpstates->gpstate_lock); - /* - * Use smp_call_function to send IPI and execute the - * mtspr on target CPU. We could do that without IPI - * if current CPU is within policy->cpus (core) + /* The current DVFS implementation in firmware requires that to set a + * frequency in a quad, all cores of the quad need to set frequency in + * their respective PMCR's. Ideally setting frequency on any of the + * core of that quad should change frequency for the quad. */ - smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); + if (p9_occ_quirk) { + cpumask_t temp; + u32 cpu; + + cpumask_copy(&temp, policy->cpus); + while (!cpumask_empty(&temp)) { + cpu = cpumask_first(&temp); + smp_call_function_any(cpu_sibling_mask(cpu), + set_pstate, &freq_data, 1); + cpumask_andnot(&temp, &temp, cpu_sibling_mask(cpu)); + } + } else { + smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); + } + return 0; } static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) { - int base, i, ret; + int ret; struct kernfs_node *kn; struct global_pstate_info *gpstates; - base = cpu_first_thread_sibling(policy->cpu); + if (!freq_domain_indicator) { + int base, i; - for (i = 0; i < threads_per_core; i++) - cpumask_set_cpu(base + i, policy->cpus); + base = cpu_first_thread_sibling(policy->cpu); + for (i = 0; i < threads_per_core; i++) + cpumask_set_cpu(base + i, policy->cpus); + } else { + u32 key; + struct hashmap *data; + + key = ((u32) get_hard_smp_processor_id(policy->cpu) & + freq_domain_indicator); + hash_for_each_possible(freq_domain_map, data, hash_node, + key%SIZE) { + if (data->chip_id == cpu_to_chip_id(policy->cpu) && + data->pir_key == key) { + cpumask_copy(policy->cpus, &data->mask); + break; + } + } + } kn = kernfs_find_and_get(policy->kobj.sd, throttle_attr_grp.name); if (!kn) { -- 1.8.3.1