From patchwork Tue May 22 16:37:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Bringmann X-Patchwork-Id: 918445 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40r1hQ6ZDwz9s01 for ; Wed, 23 May 2018 02:44:38 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40r1hQ5L40zDqsx for ; Wed, 23 May 2018 02:44:38 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=mwb@linux.vnet.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40r1YV0bL9zDqrM for ; Wed, 23 May 2018 02:38:37 +1000 (AEST) Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w4MGXiJk006093 for ; Tue, 22 May 2018 12:38:35 -0400 Received: from e31.co.us.ibm.com (e31.co.us.ibm.com [32.97.110.149]) by mx0a-001b2d01.pphosted.com with ESMTP id 2j4m00298p-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 22 May 2018 12:38:35 -0400 Received: from localhost by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 22 May 2018 10:38:34 -0600 Received: from b03cxnp07028.gho.boulder.ibm.com (9.17.130.15) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 22 May 2018 10:38:32 -0600 Received: from b03ledav003.gho.boulder.ibm.com (b03ledav003.gho.boulder.ibm.com [9.17.130.234]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w4MGbFfr2359732; Tue, 22 May 2018 09:37:15 -0700 Received: from b03ledav003.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7215B6A048; Tue, 22 May 2018 10:37:15 -0600 (MDT) Received: from oc5000245537.ibm.com (unknown [9.53.92.187]) by b03ledav003.gho.boulder.ibm.com (Postfix) with ESMTP id CC7076A042; Tue, 22 May 2018 10:37:14 -0600 (MDT) From: Michael Bringmann Subject: [RFC v4 3/4] hotplug/drcinfo: Fix hot-add CPU issues Openpgp: preference=signencrypt Autocrypt: addr=mwb@linux.vnet.ibm.com; prefer-encrypt=mutual; keydata= xsBNBFcY7GcBCADzw3en+yzo9ASFGCfldVkIg95SAMPK0myXp2XJYET3zT45uBsX/uj9/2nA lBmXXeOSXnPfJ9V3vtiwcfATnWIsVt3tL6n1kqikzH9nXNxZT7MU/7gqzWZngMAWh/GJ9qyg DTOZdjsvdUNUWxtiLvBo7y+reA4HjlQhwhYxxvCpXBeRoF0qDWfQ8DkneemqINzDZPwSQ7zY t4F5iyN1I9GC5RNK8Y6jiKmm6bDkrrbtXPOtzXKs0J0FqWEIab/u3BDrRP3STDVPdXqViHua AjEzthQbGZm0VCxI4a7XjMi99g614/qDcXZCs00GLZ/VYIE8hB9C5Q+l66S60PLjRrxnABEB AAHNLU1pY2hhZWwgVy4gQnJpbmdtYW5uIDxtd2JAbGludXgudm5ldC5pYm0uY29tPsLAeAQT AQIAIgUCVxjsZwIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQSEdag3dpuTI0NAf8 CKYTDKQLgOSjVrU2L5rM4lXaJRmQV6oidD3vIhKSnWRvPq9C29ifRG6ri20prTHAlc0vycgm 41HHg0y2vsGgNXGTWC2ObemoZBI7mySXe/7Tq5mD/semGzOp0YWZ7teqrkiSR8Bw0p+LdE7K QmT7tpjjvuhrtQ3RRojUYcuy1nWUsc4D+2cxsnZslsx84FUKxPbLagDgZmgBhUw/sUi40s6S AkdViVCVS0WANddLIpG0cfdsV0kCae/XdjK3mRK6drFKv1z+QFjvOhc8QIkkxFD0da9w3tJj oqnqHFV5gLcHO6/wizPx/NV90y6RngeBORkQiRFWxTXS4Oj9GVI/Us7ATQRXGOxnAQgAmJ5Y ikTWrMWPfiveUacETyEhWVl7u8UhZcx3yy2te8O0ay7t9fYcZgIEfQPPVVus89acIXlG3wYL DDPvb21OprLxi+ZJ2a0S5we+LcSWN1jByxJlbWBq+/LcMtGAOhNLpysY1gD0Y4UW/eKS+TFZ 562qKC3k1dBvnV9JXCgeS1taYFxRdVAn+2DwK3nuyG/DDq/XgJ5BtmyC3MMx8CiW3POj+O+l 6SedIeAfZlZ7/xhijx82g93h07VavUQRwMZgZFsqmuxBxVGiav2HB+dNvs3PFB087Pvc9OHe qhajPWOP/gNLMmvBvknn1NToM9a8/E8rzcIZXoYs4RggRRYh6wARAQABwsBfBBgBAgAJBQJX GOxnAhsMAAoJEEhHWoN3abky+RUH/jE08/r5QzaNKYeVhu0uVbgXu5fsxqr2cAxhf+KuwT3T efhEP2alarxzUZdEh4MsG6c+X2NYLbD3cryiXxVx/7kSAJEFQJfA5P06g8NLR25Qpq9BLsN7 ++dxQ+CLKzSEb1X24hYAJZpOhS8ev3ii+M/XIo+olDBKuTaTgB6elrg3CaxUsVgLBJ+jbRkW yQe2S5f/Ja1ThDpSSLLWLiLK/z7+gaqwhnwjQ8Z8Y9D2itJQcj4itHilwImsqwLG7SxzC0NX IQ5KaAFYdRcOgwR8VhhkOIVd70ObSZU+E4pTET1WDz4o65xZ89yfose1No0+r5ht/xWOOrh8 53/hcWvxHVs= Organization: IBM Linux Technology Center To: linuxppc-dev@lists.ozlabs.org In-Reply-To: <47581596-1d6e-a1a9-9490-5b5ff0f5304f@linux.vnet.ibm.com> Date: Tue, 22 May 2018 11:37:14 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 Content-Language: en-US X-TM-AS-GCONF: 00 x-cbid: 18052216-8235-0000-0000-00000D8C5E29 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009066; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000261; SDB=6.01036085; UDB=6.00529999; IPR=6.00815213; MB=3.00021242; MTD=3.00000008; XFM=3.00000015; UTC=2018-05-22 16:38:33 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18052216-8236-0000-0000-000041154E76 Message-Id: <6f2c522c-8c57-9416-3860-10a5270da059@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-05-22_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1805220183 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nathan Fontenot , Michael Bringmann , Thomas Falcon , Tyrel Datwyler , John Allen Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" This patch applies a common parse function for the ibm,drc-info property that can be modified by a callback function to the hot-add CPU code. Candidate code is replaced by a call to the parser including a pointer to a local context-specific functions, and local data. In addition, a bug in the release of the previous patch set may break things in some of the CPU DLPAR operations. For instance, when attempting to hot-add a new CPU or set of CPUs, the original patch failed to always properly calculate the available resources, and aborted the operation. Signed-off-by: Michael Bringmann Fixes: 3f38000eda48 ("powerpc/firmware: Add definitions for new drc-info firmwar e feature" -- end of patch series applied to powerpc next) --- Changes in V4: -- Update code to account for latest kernel checkins. -- Rebased to 4.17-rc5 kernel -- Compress some more code --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 118 +++++++++++++++++------ arch/powerpc/platforms/pseries/pseries_energy.c | 107 +++++++++++---------- 2 files changed, 141 insertions(+), 84 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6ef77ca..ceacad9 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -411,27 +411,63 @@ static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) return found; } -static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index) +static bool check_cpu_drc_index(struct device_node *parent, + int (*cb)(struct of_drc_info *drc, + void *data, void *not_used, + int *ret_code), + void *cdata) { bool found = false; - int rc, index; - index = 0; - while (!found) { - u32 drc; + if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { + if (drc_info_parser(parent, cb, "CPU", cdata)) + found = true; + } else { + int index = 0; - rc = of_property_read_u32_index(parent, "ibm,drc-indexes", - index++, &drc); - if (rc) - break; + while (!found) { + u32 drc; - if (drc == drc_index) - found = true; + if (of_property_read_u32_index(parent, + "ibm,drc-indexes", + index++, &drc)) + break; + if (cb(NULL, cdata, &drc, NULL)) + found = true; + } } return found; } +struct valid_drc_index_struct { + u32 targ_drc_index; +}; + +static int valid_drc_index_cb(struct of_drc_info *drc, void *idata, + void *drc_index, int *ret_code) +{ + struct valid_drc_index_struct *cdata = idata; + + if (drc) { + if (!((drc->drc_index_start <= cdata->targ_drc_index) && + (cdata->targ_drc_index <= drc->last_drc_index))) + return 0; + } else { + if (*((u32 *)drc_index) != cdata->targ_drc_index) + return 0; + } + (*ret_code) = 1; + return 1; +} + +static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index) +{ + struct valid_drc_index_struct cdata = { drc_index }; + + return check_cpu_drc_index(parent, valid_drc_index_cb, &cdata); +} + static ssize_t dlpar_cpu_add(u32 drc_index) { struct device_node *dn, *parent; @@ -721,11 +757,43 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove) return rc; } +struct cpus_to_add_struct { + struct device_node *parent; + u32 *cpu_drcs; + u32 cpus_to_add; + u32 cpus_found; +}; + +static int cpus_to_add_cb(struct of_drc_info *drc, void *idata, + void *drc_index, int *ret_code) +{ + struct cpus_to_add_struct *cdata = idata; + + if (drc) { + int k; + + for (k = 0; (k < drc->num_sequential_elems) && + (cdata->cpus_found < cdata->cpus_to_add); k++) { + u32 idrc = drc->drc_index_start + + (k * drc->sequential_inc); + + if (dlpar_cpu_exists(cdata->parent, idrc)) + continue; + cdata->cpu_drcs[cdata->cpus_found++] = idrc; + } + } else { + if (!dlpar_cpu_exists(cdata->parent, *((u32 *)drc_index))) + cdata->cpu_drcs[cdata->cpus_found++] = + *((u32 *)drc_index); + } + return 0; +} + static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add) { struct device_node *parent; - int cpus_found = 0; - int index, rc; + struct cpus_to_add_struct cdata = { + NULL, cpu_drcs, cpus_to_add, 0 }; parent = of_find_node_by_path("/cpus"); if (!parent) { @@ -734,28 +802,14 @@ static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add) return -1; } - /* Search the ibm,drc-indexes array for possible CPU drcs to - * add. Note that the format of the ibm,drc-indexes array is - * the number of entries in the array followed by the array - * of drc values so we start looking at index = 1. + /* Search the appropriate property for possible CPU drcs to + * add. */ - index = 1; - while (cpus_found < cpus_to_add) { - u32 drc; - - rc = of_property_read_u32_index(parent, "ibm,drc-indexes", - index++, &drc); - if (rc) - break; - - if (dlpar_cpu_exists(parent, drc)) - continue; - - cpu_drcs[cpus_found++] = drc; - } + cdata.parent = parent; + check_cpu_drc_index(parent, cpus_to_add_cb, &cdata); of_node_put(parent); - return cpus_found; + return cdata.cpus_found; } static int dlpar_cpu_add_by_count(u32 cpus_to_add) diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 5261975..d8d7750 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -36,6 +36,26 @@ /* Helper Routines to convert between drc_index to cpu numbers */ +struct cpu_to_drc_index_struct { + u32 thread_index; + u32 ret; +}; + +static int cpu_to_drc_index_cb(struct of_drc_info *drc, void *idata, + void *not_used, int *ret_code) +{ + struct cpu_to_drc_index_struct *cdata = idata; + int ret = 0; + + if (cdata->thread_index < drc->last_drc_index) { + cdata->ret = drc->drc_index_start + + (cdata->thread_index * drc->sequential_inc); + ret = 1; + } + (*ret_code) = ret; + return ret; +} + static u32 cpu_to_drc_index(int cpu) { struct device_node *dn = NULL; @@ -51,30 +71,14 @@ static u32 cpu_to_drc_index(int cpu) thread_index = cpu_core_index_of_thread(cpu); if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { - struct property *info = NULL; - struct of_drc_info drc; - int j; - u32 num_set_entries; - const __be32 *value; - - info = of_find_property(dn, "ibm,drc-info", NULL); - if (info == NULL) - goto err_of_node_put; + struct cpu_to_drc_index_struct cdata = { + thread_index, 0 }; - value = info->value; - num_set_entries = of_read_number(value++, 1); - - for (j = 0; j < num_set_entries; j++) { - - of_read_drc_info_cell(&info, &value, &drc); - if (strncmp(drc.drc_type, "CPU", 3)) - goto err; - - if (thread_index < drc.last_drc_index) - break; - } - - ret = drc.drc_index_start + (thread_index * drc.sequential_inc); + rc = drc_info_parser(dn, &cpu_to_drc_index_cb, + "CPU", &cdata); + if (rc < 0) + goto err_of_node_put; + ret = cdata.ret; } else { const __be32 *indexes; @@ -100,11 +104,33 @@ static u32 cpu_to_drc_index(int cpu) return ret; } +struct drc_index_to_cpu_struct { + u32 drc_index; + u32 thread_index; + u32 cpu; +}; + +static int drc_index_to_cpu_cb(struct of_drc_info *drc, + void *idata, void *not_used, int *ret_code) +{ + struct drc_index_to_cpu_struct *cdata = idata; + + if (cdata->drc_index > drc->last_drc_index) { + cdata->cpu += drc->num_sequential_elems; + } else { + cdata->cpu += ((cdata->drc_index - drc->drc_index_start) / + drc->sequential_inc); + cdata->thread_index = cpu_first_thread_of_core(cdata->cpu); + } + (*ret_code) = 0; + return 0; +} + static int drc_index_to_cpu(u32 drc_index) { struct device_node *dn = NULL; const int *indexes; - int thread_index = 0, cpu = 0; + int thread_index = 0; int rc = 1; dn = of_find_node_by_path("/cpus"); @@ -112,36 +138,13 @@ static int drc_index_to_cpu(u32 drc_index) goto err; if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { - struct property *info = NULL; - struct of_drc_info drc; - int j; - u32 num_set_entries; - const __be32 *value; - - info = of_find_property(dn, "ibm,drc-info", NULL); - if (info == NULL) - goto err_of_node_put; - - value = info->value; - num_set_entries = of_read_number(value++, 1); - - for (j = 0; j < num_set_entries; j++) { + struct drc_index_to_cpu_struct cdata = { + drc_index, 0, 0 }; - of_read_drc_info_cell(&info, &value, &drc); - if (strncmp(drc.drc_type, "CPU", 3)) - goto err; + rc = drc_info_parser(dn, &drc_index_to_cpu_cb, + "CPU", &cdata); + thread_index = cdata.thread_index; - if (drc_index > drc.last_drc_index) { - cpu += drc.num_sequential_elems; - continue; - } - cpu += ((drc_index - drc.drc_index_start) / - drc.sequential_inc); - - thread_index = cpu_first_thread_of_core(cpu); - rc = 0; - break; - } } else { unsigned long int i;