Re: new cpu iteration code...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Thu, Oct 3, 2013 at 10:24 PM, David Miller <davem@xxxxxxxxxxxxx> wrote:
>
> Can people on powerpc/arm/etc. give this a spin?  This works on my
> T4-2 sparc64 box.

The code looks fine. I'll give it a spin on ARM. I'm assuming that
this can wait for v3.13 if I commit the fix to suppress the warning,
correct?

g.

>
> --------------------
> of: Make cpu node handling more portable.
>
> Use for_each_node_by_type() to iterate all cpu nodes in the
> system.
>
> Provide and overridable function arch_find_n_match_cpu_physical_id,
> which sees if the given device node matches 'cpu' and if so sets
> '*thread' when non-NULL to the cpu thread number within the core.
>
> The default implementation behaves the same as the existing code.
>
> Add a sparc64 implementation.
>
> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
>
> diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
> index d397d7f..6b39125 100644
> --- a/arch/sparc/kernel/prom_64.c
> +++ b/arch/sparc/kernel/prom_64.c
> @@ -373,6 +373,59 @@ static const char *get_mid_prop(void)
>         return (tlb_type == spitfire ? "upa-portid" : "portid");
>  }
>
> +bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
> +                                      int cpu, unsigned int *thread)
> +{
> +       const char *mid_prop = get_mid_prop();
> +       int this_cpu_id;
> +
> +       /* On hypervisor based platforms we interrogate the 'reg'
> +        * property.  On everything else we look for a 'upa-portis',
> +        * 'portid', or 'cpuid' property.
> +        */
> +
> +       if (tlb_type == hypervisor) {
> +               struct property *prop = of_find_property(cpun, "reg", NULL);
> +               u32 *regs;
> +
> +               if (!prop) {
> +                       pr_warn("CPU node missing reg property\n");
> +                       return false;
> +               }
> +               regs = prop->value;
> +               this_cpu_id = regs[0] & 0x0fffffff;
> +       } else {
> +               this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
> +
> +               if (this_cpu_id < 0) {
> +                       mid_prop = "cpuid";
> +                       this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
> +               }
> +               if (this_cpu_id < 0) {
> +                       pr_warn("CPU node missing cpu ID property\n");
> +                       return false;
> +               }
> +       }
> +       if (this_cpu_id == cpu) {
> +               if (thread) {
> +                       int proc_id = cpu_data(cpu).proc_id;
> +
> +                       /* On sparc64, the cpu thread information is obtained
> +                        * either from OBP or the machine description.  We've
> +                        * actually probed this information already long before
> +                        * this interface gets called so instead of interrogating
> +                        * both the OF node and the MDESC again, just use what
> +                        * we discovered already.
> +                        */
> +                       if (proc_id < 0)
> +                               proc_id = 0;
> +                       *thread = proc_id;
> +               }
> +               return true;
> +       }
> +       return false;
> +}
> +
>  static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
>  {
>         struct device_node *dp;
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 865d3f6..e4c9945 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -280,6 +280,31 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
>         return false;
>  }
>
> +/*
> + * arch_find_n_match_cpu_physical_id - See if the given device node is
> + * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
> + * else false.  If 'thread' is non-NULL, the local thread number within the
> + * core is returned in it.
> + */
> +bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
> +                                             int cpu, unsigned int *thread)
> +{
> +       /* Check for non-standard "ibm,ppc-interrupt-server#s" property
> +        * for thread ids on PowerPC. If it doesn't exist fallback to
> +        * standard "reg" property.
> +        */
> +       if (IS_ENABLED(CONFIG_PPC) &&
> +           __of_find_n_match_cpu_property(cpun,
> +                                          "ibm,ppc-interrupt-server#s",
> +                                          cpu, thread))
> +               return true;
> +
> +       if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> +               return true;
> +
> +       return false;
> +}
> +
>  /**
>   * of_get_cpu_node - Get device node associated with the given logical CPU
>   *
> @@ -300,26 +325,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
>   */
>  struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
>  {
> -       struct device_node *cpun, *cpus;
> -
> -       cpus = of_find_node_by_path("/cpus");
> -       if (!cpus) {
> -               pr_warn("Missing cpus node, bailing out\n");
> -               return NULL;
> -       }
> +       struct device_node *cpun;
>
> -       for_each_child_of_node(cpus, cpun) {
> -               if (of_node_cmp(cpun->type, "cpu"))
> -                       continue;
> -               /* Check for non-standard "ibm,ppc-interrupt-server#s" property
> -                * for thread ids on PowerPC. If it doesn't exist fallback to
> -                * standard "reg" property.
> -                */
> -               if (IS_ENABLED(CONFIG_PPC) &&
> -                       __of_find_n_match_cpu_property(cpun,
> -                               "ibm,ppc-interrupt-server#s", cpu, thread))
> -                       return cpun;
> -               if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
> +       for_each_node_by_type(cpun, "cpu") {
> +               if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
>                         return cpun;
>         }
>         return NULL;
> diff --git a/include/linux/cpu.h b/include/linux/cpu.h
> index 801ff9e..fbd25c3 100644
> --- a/include/linux/cpu.h
> +++ b/include/linux/cpu.h
> @@ -18,6 +18,7 @@
>  #include <linux/cpumask.h>
>
>  struct device;
> +struct device_node;
>
>  struct cpu {
>         int node_id;            /* The node which contains the CPU */
> @@ -29,6 +30,8 @@ extern int register_cpu(struct cpu *cpu, int num);
>  extern struct device *get_cpu_device(unsigned cpu);
>  extern bool cpu_is_hotpluggable(unsigned cpu);
>  extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
> +extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
> +                                             int cpu, unsigned int *thread);
>
>  extern int cpu_add_dev_attr(struct device_attribute *attr);
>  extern void cpu_remove_dev_attr(struct device_attribute *attr);
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux