<html><body><p><tt><font size="2">"Anju T Sudhakar" <anju@linux.vnet.ibm.com> wrote on 27/11/2019 12:50:35 PM:<br><br>> From: "Anju T Sudhakar" <anju@linux.vnet.ibm.com></font></tt><br><tt><font size="2">> To: mpe@ellerman.id.au</font></tt><br><tt><font size="2">> Cc: linuxppc-dev@lists.ozlabs.org, anju@linux.vnet.ibm.com, <br>> Nageswara R Sastry/India/IBM@IBMIN</font></tt><br><tt><font size="2">> Date: 27/11/2019 12:50 PM</font></tt><br><tt><font size="2">> Subject: [PATCH v3] platforms/powernv: Avoid re-registration of imc <br>> debugfs directory</font></tt><br><tt><font size="2">> <br>> export_imc_mode_and_cmd() function which creates the debugfs interface for<br>> imc-mode and imc-command, is invoked when each nest pmu units is<br>> registered.<br>> When the first nest pmu unit is registered, export_imc_mode_and_cmd()<br>> creates 'imc' directory under `/debug/powerpc/`. In the subsequent<br>> invocations debugfs_create_dir() function returns, since the directory<br>> already exists.<br>> <br>> The recent commit <c33d442328f55> (debugfs: make error message a bit more<br>> verbose), throws a warning if we try to invoke `debugfs_create_dir()`<br>> with an already existing directory name.<br>> <br>> Address this warning by making the debugfs directory registration<br>> in the opal_imc_counters_probe() function, i.e invoke<br>> export_imc_mode_and_cmd() function from the probe function.<br>> <br>> Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com><br>> ---<br>> Changes from v2 -> v3:<br>> <br>> * Invoke export_imc_mode_and_cmd(), which does the imc debugfs<br>>   directory registration and deletion, from the probe fucntion.<br>> * Change the return type of imc_pmu_create() to get the<br>>   control block address for nest units in the probe<br>>   function<br>> * Remove unnecessary comments<br></font></tt><br><tt><font size="2">Tested-by: Nageswara R Sastry <nasastry@in.ibm.com><br></font></tt><br><tt><font size="2">Not seeing any Kernel OOPs/warnings in dmesg<br></font></tt><tt><font size="2" color="#5F5F5F"># cat /sys/kernel/debug/powerpc/imc/*</font></tt><br><tt><font size="2" color="#5F5F5F">0x0000000000000000</font></tt><br><tt><font size="2" color="#5F5F5F">0x0000000000000000</font></tt><br><tt><font size="2" color="#5F5F5F">0x0000000000000000</font></tt><br><tt><font size="2" color="#5F5F5F">0x0000000000000000</font></tt><br><br><tt><font size="2"><br>> ---<br>>  arch/powerpc/platforms/powernv/opal-imc.c | 39 ++++++++++++<br>> +------------------<br>>  1 file changed, 16 insertions(+), 23 deletions(-)<br>> <br>> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/<br>> powerpc/platforms/powernv/opal-imc.c<br>> index e04b206..3b4518f 100644<br>> --- a/arch/powerpc/platforms/powernv/opal-imc.c<br>> +++ b/arch/powerpc/platforms/powernv/opal-imc.c<br>> @@ -59,10 +59,6 @@ static void export_imc_mode_and_cmd(struct <br>> device_node *node,<br>>  <br>>     imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);<br>>  <br>> -   /*<br>> -    * Return here, either because 'imc' directory already exists,<br>> -    * Or failed to create a new one.<br>> -    */<br>>     if (!imc_debugfs_parent)<br>>        return;<br>>  <br>> @@ -135,7 +131,6 @@ static int imc_get_mem_addr_nest(struct device_node *node,<br>>     }<br>>  <br>>     pmu_ptr->imc_counter_mmaped = true;<br>> -   export_imc_mode_and_cmd(node, pmu_ptr);<br>>     kfree(base_addr_arr);<br>>     kfree(chipid_arr);<br>>     return 0;<br>> @@ -151,7 +146,7 @@ static int imc_get_mem_addr_nest(struct device_node *node,<br>>   *          and domain as the inputs.<br>>   * Allocates memory for the struct imc_pmu, sets up its domain, <br>> size and offsets<br>>   */<br>> -static int imc_pmu_create(struct device_node *parent, int <br>> pmu_index, int domain)<br>> +static struct imc_pmu *imc_pmu_create(struct device_node *parent, <br>> int pmu_index, int domain)<br>>  {<br>>     int ret = 0;<br>>     struct imc_pmu *pmu_ptr;<br>> @@ -159,27 +154,23 @@ static int imc_pmu_create(struct device_node <br>> *parent, int pmu_index, int domain)<br>>  <br>>     /* Return for unknown domain */<br>>     if (domain < 0)<br>> -      return -EINVAL;<br>> +      return NULL;<br>>  <br>>     /* memory for pmu */<br>>     pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL);<br>>     if (!pmu_ptr)<br>> -      return -ENOMEM;<br>> +      return NULL;<br>>  <br>>     /* Set the domain */<br>>     pmu_ptr->domain = domain;<br>>  <br>>     ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size);<br>> -   if (ret) {<br>> -      ret = -EINVAL;<br>> +   if (ret)<br>>        goto free_pmu;<br>> -   }<br>>  <br>>     if (!of_property_read_u32(parent, "offset", &offset)) {<br>> -      if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) {<br>> -         ret = -EINVAL;<br>> +      if (imc_get_mem_addr_nest(parent, pmu_ptr, offset))<br>>           goto free_pmu;<br>> -      }<br>>     }<br>>  <br>>     /* Function to register IMC pmu */<br>> @@ -190,14 +181,14 @@ static int imc_pmu_create(struct device_node <br>> *parent, int pmu_index, int domain)<br>>        if (pmu_ptr->domain == IMC_DOMAIN_NEST)<br>>           kfree(pmu_ptr->mem_info);<br>>        kfree(pmu_ptr);<br>> -      return ret;<br>> +      return NULL;<br>>     }<br>>  <br>> -   return 0;<br>> +   return pmu_ptr;<br>>  <br>>  free_pmu:<br>>     kfree(pmu_ptr);<br>> -   return ret;<br>> +   return NULL;<br>>  }<br>>  <br>>  static void disable_nest_pmu_counters(void)<br>> @@ -254,6 +245,7 @@ int get_max_nest_dev(void)<br>>  static int opal_imc_counters_probe(struct platform_device *pdev)<br>>  {<br>>     struct device_node *imc_dev = pdev->dev.of_node;<br>> +   struct imc_pmu *pmu;<br>>     int pmu_count = 0, domain;<br>>     bool core_imc_reg = false, thread_imc_reg = false;<br>>     u32 type;<br>> @@ -269,6 +261,7 @@ static int opal_imc_counters_probe(struct <br>> platform_device *pdev)<br>>     }<br>>  <br>>     for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) {<br>> +      pmu = NULL;<br>>        if (of_property_read_u32(imc_dev, "type", &type)) {<br>>           pr_warn("IMC Device without type property\n");<br>>           continue;<br>> @@ -293,9 +286,13 @@ static int opal_imc_counters_probe(struct <br>> platform_device *pdev)<br>>           break;<br>>        }<br>>  <br>> -      if (!imc_pmu_create(imc_dev, pmu_count, domain)) {<br>> -         if (domain == IMC_DOMAIN_NEST)<br>> +      pmu = imc_pmu_create(imc_dev, pmu_count, domain);<br>> +      if (pmu != NULL) {<br>> +         if (domain == IMC_DOMAIN_NEST) {<br>> +            if (!imc_debugfs_parent)<br>> +               export_imc_mode_and_cmd(imc_dev, pmu);<br>>              pmu_count++;<br>> +         }<br>>           if (domain == IMC_DOMAIN_CORE)<br>>              core_imc_reg = true;<br>>           if (domain == IMC_DOMAIN_THREAD)<br>> @@ -303,10 +300,6 @@ static int opal_imc_counters_probe(struct <br>> platform_device *pdev)<br>>        }<br>>     }<br>>  <br>> -   /* If none of the nest units are registered, remove debugfs interface */<br>> -   if (pmu_count == 0)<br>> -      debugfs_remove_recursive(imc_debugfs_parent);<br>> -<br>>     /* If core imc is not registered, unregister thread-imc */<br>>     if (!core_imc_reg && thread_imc_reg)<br>>        unregister_thread_imc();<br>> -- <br>> 1.8.3.1<br>> <br></font></tt><BR>
</body></html>