root/arch/powerpc/platforms/pseries/hotplug-cpu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_cede_offline
  2. get_cpu_current_state
  3. set_cpu_current_state
  4. get_preferred_offline_state
  5. set_preferred_offline_state
  6. set_default_offline_state
  7. rtas_stop_self
  8. pseries_mach_cpu_die
  9. pseries_cpu_disable
  10. pseries_cpu_die
  11. pseries_add_processor
  12. pseries_remove_processor
  13. dlpar_online_cpu
  14. dlpar_cpu_exists
  15. valid_cpu_drc_index
  16. dlpar_cpu_add
  17. dlpar_offline_cpu
  18. dlpar_cpu_remove
  19. cpu_drc_index_to_dn
  20. dlpar_cpu_remove_by_index
  21. find_dlpar_cpus_to_remove
  22. dlpar_cpu_remove_by_count
  23. find_dlpar_cpus_to_add
  24. dlpar_cpu_add_by_count
  25. dlpar_cpu_readd
  26. dlpar_cpu
  27. dlpar_cpu_probe
  28. dlpar_cpu_release
  29. pseries_smp_notifier
  30. parse_cede_parameters
  31. pseries_cpu_hotplug_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * pseries CPU Hotplug infrastructure.
   4  *
   5  * Split out from arch/powerpc/platforms/pseries/setup.c
   6  *  arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c
   7  *
   8  * Peter Bergner, IBM   March 2001.
   9  * Copyright (C) 2001 IBM.
  10  * Dave Engebretsen, Peter Bergner, and
  11  * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
  12  * Plus various changes from other IBM teams...
  13  *
  14  * Copyright (C) 2006 Michael Ellerman, IBM Corporation
  15  */
  16 
  17 #define pr_fmt(fmt)     "pseries-hotplug-cpu: " fmt
  18 
  19 #include <linux/kernel.h>
  20 #include <linux/interrupt.h>
  21 #include <linux/delay.h>
  22 #include <linux/sched.h>        /* for idle_task_exit */
  23 #include <linux/sched/hotplug.h>
  24 #include <linux/cpu.h>
  25 #include <linux/of.h>
  26 #include <linux/slab.h>
  27 #include <asm/prom.h>
  28 #include <asm/rtas.h>
  29 #include <asm/firmware.h>
  30 #include <asm/machdep.h>
  31 #include <asm/vdso_datapage.h>
  32 #include <asm/xics.h>
  33 #include <asm/xive.h>
  34 #include <asm/plpar_wrappers.h>
  35 #include <asm/topology.h>
  36 
  37 #include "pseries.h"
  38 #include "offline_states.h"
  39 
  40 /* This version can't take the spinlock, because it never returns */
  41 static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
  42 
  43 static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =
  44                                                         CPU_STATE_OFFLINE;
  45 static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE;
  46 
  47 static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
  48 
  49 static bool cede_offline_enabled __read_mostly = true;
  50 
  51 /*
  52  * Enable/disable cede_offline when available.
  53  */
  54 static int __init setup_cede_offline(char *str)
  55 {
  56         return (kstrtobool(str, &cede_offline_enabled) == 0);
  57 }
  58 
  59 __setup("cede_offline=", setup_cede_offline);
  60 
  61 enum cpu_state_vals get_cpu_current_state(int cpu)
  62 {
  63         return per_cpu(current_state, cpu);
  64 }
  65 
  66 void set_cpu_current_state(int cpu, enum cpu_state_vals state)
  67 {
  68         per_cpu(current_state, cpu) = state;
  69 }
  70 
  71 enum cpu_state_vals get_preferred_offline_state(int cpu)
  72 {
  73         return per_cpu(preferred_offline_state, cpu);
  74 }
  75 
  76 void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
  77 {
  78         per_cpu(preferred_offline_state, cpu) = state;
  79 }
  80 
  81 void set_default_offline_state(int cpu)
  82 {
  83         per_cpu(preferred_offline_state, cpu) = default_offline_state;
  84 }
  85 
  86 static void rtas_stop_self(void)
  87 {
  88         static struct rtas_args args;
  89 
  90         local_irq_disable();
  91 
  92         BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
  93 
  94         printk("cpu %u (hwid %u) Ready to die...\n",
  95                smp_processor_id(), hard_smp_processor_id());
  96 
  97         rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL);
  98 
  99         panic("Alas, I survived.\n");
 100 }
 101 
 102 static void pseries_mach_cpu_die(void)
 103 {
 104         unsigned int cpu = smp_processor_id();
 105         unsigned int hwcpu = hard_smp_processor_id();
 106         u8 cede_latency_hint = 0;
 107 
 108         local_irq_disable();
 109         idle_task_exit();
 110         if (xive_enabled())
 111                 xive_teardown_cpu();
 112         else
 113                 xics_teardown_cpu();
 114 
 115         if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 116                 set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
 117                 if (ppc_md.suspend_disable_cpu)
 118                         ppc_md.suspend_disable_cpu();
 119 
 120                 cede_latency_hint = 2;
 121 
 122                 get_lppaca()->idle = 1;
 123                 if (!lppaca_shared_proc(get_lppaca()))
 124                         get_lppaca()->donate_dedicated_cpu = 1;
 125 
 126                 while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 127                         while (!prep_irq_for_idle()) {
 128                                 local_irq_enable();
 129                                 local_irq_disable();
 130                         }
 131 
 132                         extended_cede_processor(cede_latency_hint);
 133                 }
 134 
 135                 local_irq_disable();
 136 
 137                 if (!lppaca_shared_proc(get_lppaca()))
 138                         get_lppaca()->donate_dedicated_cpu = 0;
 139                 get_lppaca()->idle = 0;
 140 
 141                 if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
 142                         unregister_slb_shadow(hwcpu);
 143 
 144                         hard_irq_disable();
 145                         /*
 146                          * Call to start_secondary_resume() will not return.
 147                          * Kernel stack will be reset and start_secondary()
 148                          * will be called to continue the online operation.
 149                          */
 150                         start_secondary_resume();
 151                 }
 152         }
 153 
 154         /* Requested state is CPU_STATE_OFFLINE at this point */
 155         WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
 156 
 157         set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
 158         unregister_slb_shadow(hwcpu);
 159         rtas_stop_self();
 160 
 161         /* Should never get here... */
 162         BUG();
 163         for(;;);
 164 }
 165 
 166 static int pseries_cpu_disable(void)
 167 {
 168         int cpu = smp_processor_id();
 169 
 170         set_cpu_online(cpu, false);
 171         vdso_data->processorCount--;
 172 
 173         /*fix boot_cpuid here*/
 174         if (cpu == boot_cpuid)
 175                 boot_cpuid = cpumask_any(cpu_online_mask);
 176 
 177         /* FIXME: abstract this to not be platform specific later on */
 178         if (xive_enabled())
 179                 xive_smp_disable_cpu();
 180         else
 181                 xics_migrate_irqs_away();
 182         return 0;
 183 }
 184 
 185 /*
 186  * pseries_cpu_die: Wait for the cpu to die.
 187  * @cpu: logical processor id of the CPU whose death we're awaiting.
 188  *
 189  * This function is called from the context of the thread which is performing
 190  * the cpu-offline. Here we wait for long enough to allow the cpu in question
 191  * to self-destroy so that the cpu-offline thread can send the CPU_DEAD
 192  * notifications.
 193  *
 194  * OTOH, pseries_mach_cpu_die() is called by the @cpu when it wants to
 195  * self-destruct.
 196  */
 197 static void pseries_cpu_die(unsigned int cpu)
 198 {
 199         int tries;
 200         int cpu_status = 1;
 201         unsigned int pcpu = get_hard_smp_processor_id(cpu);
 202 
 203         if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 204                 cpu_status = 1;
 205                 for (tries = 0; tries < 5000; tries++) {
 206                         if (get_cpu_current_state(cpu) == CPU_STATE_INACTIVE) {
 207                                 cpu_status = 0;
 208                                 break;
 209                         }
 210                         msleep(1);
 211                 }
 212         } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
 213 
 214                 for (tries = 0; tries < 25; tries++) {
 215                         cpu_status = smp_query_cpu_stopped(pcpu);
 216                         if (cpu_status == QCSS_STOPPED ||
 217                             cpu_status == QCSS_HARDWARE_ERROR)
 218                                 break;
 219                         cpu_relax();
 220                 }
 221         }
 222 
 223         if (cpu_status != 0) {
 224                 printk("Querying DEAD? cpu %i (%i) shows %i\n",
 225                        cpu, pcpu, cpu_status);
 226         }
 227 
 228         /* Isolation and deallocation are definitely done by
 229          * drslot_chrp_cpu.  If they were not they would be
 230          * done here.  Change isolate state to Isolate and
 231          * change allocation-state to Unusable.
 232          */
 233         paca_ptrs[cpu]->cpu_start = 0;
 234 }
 235 
 236 /*
 237  * Update cpu_present_mask and paca(s) for a new cpu node.  The wrinkle
 238  * here is that a cpu device node may represent up to two logical cpus
 239  * in the SMT case.  We must honor the assumption in other code that
 240  * the logical ids for sibling SMT threads x and y are adjacent, such
 241  * that x^1 == y and y^1 == x.
 242  */
 243 static int pseries_add_processor(struct device_node *np)
 244 {
 245         unsigned int cpu;
 246         cpumask_var_t candidate_mask, tmp;
 247         int err = -ENOSPC, len, nthreads, i;
 248         const __be32 *intserv;
 249 
 250         intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
 251         if (!intserv)
 252                 return 0;
 253 
 254         zalloc_cpumask_var(&candidate_mask, GFP_KERNEL);
 255         zalloc_cpumask_var(&tmp, GFP_KERNEL);
 256 
 257         nthreads = len / sizeof(u32);
 258         for (i = 0; i < nthreads; i++)
 259                 cpumask_set_cpu(i, tmp);
 260 
 261         cpu_maps_update_begin();
 262 
 263         BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask));
 264 
 265         /* Get a bitmap of unoccupied slots. */
 266         cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask);
 267         if (cpumask_empty(candidate_mask)) {
 268                 /* If we get here, it most likely means that NR_CPUS is
 269                  * less than the partition's max processors setting.
 270                  */
 271                 printk(KERN_ERR "Cannot add cpu %pOF; this system configuration"
 272                        " supports %d logical cpus.\n", np,
 273                        num_possible_cpus());
 274                 goto out_unlock;
 275         }
 276 
 277         while (!cpumask_empty(tmp))
 278                 if (cpumask_subset(tmp, candidate_mask))
 279                         /* Found a range where we can insert the new cpu(s) */
 280                         break;
 281                 else
 282                         cpumask_shift_left(tmp, tmp, nthreads);
 283 
 284         if (cpumask_empty(tmp)) {
 285                 printk(KERN_ERR "Unable to find space in cpu_present_mask for"
 286                        " processor %pOFn with %d thread(s)\n", np,
 287                        nthreads);
 288                 goto out_unlock;
 289         }
 290 
 291         for_each_cpu(cpu, tmp) {
 292                 BUG_ON(cpu_present(cpu));
 293                 set_cpu_present(cpu, true);
 294                 set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++));
 295         }
 296         err = 0;
 297 out_unlock:
 298         cpu_maps_update_done();
 299         free_cpumask_var(candidate_mask);
 300         free_cpumask_var(tmp);
 301         return err;
 302 }
 303 
 304 /*
 305  * Update the present map for a cpu node which is going away, and set
 306  * the hard id in the paca(s) to -1 to be consistent with boot time
 307  * convention for non-present cpus.
 308  */
 309 static void pseries_remove_processor(struct device_node *np)
 310 {
 311         unsigned int cpu;
 312         int len, nthreads, i;
 313         const __be32 *intserv;
 314         u32 thread;
 315 
 316         intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
 317         if (!intserv)
 318                 return;
 319 
 320         nthreads = len / sizeof(u32);
 321 
 322         cpu_maps_update_begin();
 323         for (i = 0; i < nthreads; i++) {
 324                 thread = be32_to_cpu(intserv[i]);
 325                 for_each_present_cpu(cpu) {
 326                         if (get_hard_smp_processor_id(cpu) != thread)
 327                                 continue;
 328                         BUG_ON(cpu_online(cpu));
 329                         set_cpu_present(cpu, false);
 330                         set_hard_smp_processor_id(cpu, -1);
 331                         update_numa_cpu_lookup_table(cpu, -1);
 332                         break;
 333                 }
 334                 if (cpu >= nr_cpu_ids)
 335                         printk(KERN_WARNING "Could not find cpu to remove "
 336                                "with physical id 0x%x\n", thread);
 337         }
 338         cpu_maps_update_done();
 339 }
 340 
 341 static int dlpar_online_cpu(struct device_node *dn)
 342 {
 343         int rc = 0;
 344         unsigned int cpu;
 345         int len, nthreads, i;
 346         const __be32 *intserv;
 347         u32 thread;
 348 
 349         intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
 350         if (!intserv)
 351                 return -EINVAL;
 352 
 353         nthreads = len / sizeof(u32);
 354 
 355         cpu_maps_update_begin();
 356         for (i = 0; i < nthreads; i++) {
 357                 thread = be32_to_cpu(intserv[i]);
 358                 for_each_present_cpu(cpu) {
 359                         if (get_hard_smp_processor_id(cpu) != thread)
 360                                 continue;
 361                         BUG_ON(get_cpu_current_state(cpu)
 362                                         != CPU_STATE_OFFLINE);
 363                         cpu_maps_update_done();
 364                         timed_topology_update(1);
 365                         find_and_online_cpu_nid(cpu);
 366                         rc = device_online(get_cpu_device(cpu));
 367                         if (rc)
 368                                 goto out;
 369                         cpu_maps_update_begin();
 370 
 371                         break;
 372                 }
 373                 if (cpu == num_possible_cpus())
 374                         printk(KERN_WARNING "Could not find cpu to online "
 375                                "with physical id 0x%x\n", thread);
 376         }
 377         cpu_maps_update_done();
 378 
 379 out:
 380         return rc;
 381 
 382 }
 383 
 384 static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index)
 385 {
 386         struct device_node *child = NULL;
 387         u32 my_drc_index;
 388         bool found;
 389         int rc;
 390 
 391         /* Assume cpu doesn't exist */
 392         found = false;
 393 
 394         for_each_child_of_node(parent, child) {
 395                 rc = of_property_read_u32(child, "ibm,my-drc-index",
 396                                           &my_drc_index);
 397                 if (rc)
 398                         continue;
 399 
 400                 if (my_drc_index == drc_index) {
 401                         of_node_put(child);
 402                         found = true;
 403                         break;
 404                 }
 405         }
 406 
 407         return found;
 408 }
 409 
 410 static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
 411 {
 412         bool found = false;
 413         int rc, index;
 414 
 415         index = 0;
 416         while (!found) {
 417                 u32 drc;
 418 
 419                 rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
 420                                                 index++, &drc);
 421                 if (rc)
 422                         break;
 423 
 424                 if (drc == drc_index)
 425                         found = true;
 426         }
 427 
 428         return found;
 429 }
 430 
 431 static ssize_t dlpar_cpu_add(u32 drc_index)
 432 {
 433         struct device_node *dn, *parent;
 434         int rc, saved_rc;
 435 
 436         pr_debug("Attempting to add CPU, drc index: %x\n", drc_index);
 437 
 438         parent = of_find_node_by_path("/cpus");
 439         if (!parent) {
 440                 pr_warn("Failed to find CPU root node \"/cpus\"\n");
 441                 return -ENODEV;
 442         }
 443 
 444         if (dlpar_cpu_exists(parent, drc_index)) {
 445                 of_node_put(parent);
 446                 pr_warn("CPU with drc index %x already exists\n", drc_index);
 447                 return -EINVAL;
 448         }
 449 
 450         if (!valid_cpu_drc_index(parent, drc_index)) {
 451                 of_node_put(parent);
 452                 pr_warn("Cannot find CPU (drc index %x) to add.\n", drc_index);
 453                 return -EINVAL;
 454         }
 455 
 456         rc = dlpar_acquire_drc(drc_index);
 457         if (rc) {
 458                 pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
 459                         rc, drc_index);
 460                 of_node_put(parent);
 461                 return -EINVAL;
 462         }
 463 
 464         dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
 465         if (!dn) {
 466                 pr_warn("Failed call to configure-connector, drc index: %x\n",
 467                         drc_index);
 468                 dlpar_release_drc(drc_index);
 469                 of_node_put(parent);
 470                 return -EINVAL;
 471         }
 472 
 473         rc = dlpar_attach_node(dn, parent);
 474 
 475         /* Regardless we are done with parent now */
 476         of_node_put(parent);
 477 
 478         if (rc) {
 479                 saved_rc = rc;
 480                 pr_warn("Failed to attach node %pOFn, rc: %d, drc index: %x\n",
 481                         dn, rc, drc_index);
 482 
 483                 rc = dlpar_release_drc(drc_index);
 484                 if (!rc)
 485                         dlpar_free_cc_nodes(dn);
 486 
 487                 return saved_rc;
 488         }
 489 
 490         rc = dlpar_online_cpu(dn);
 491         if (rc) {
 492                 saved_rc = rc;
 493                 pr_warn("Failed to online cpu %pOFn, rc: %d, drc index: %x\n",
 494                         dn, rc, drc_index);
 495 
 496                 rc = dlpar_detach_node(dn);
 497                 if (!rc)
 498                         dlpar_release_drc(drc_index);
 499 
 500                 return saved_rc;
 501         }
 502 
 503         pr_debug("Successfully added CPU %pOFn, drc index: %x\n", dn,
 504                  drc_index);
 505         return rc;
 506 }
 507 
 508 static int dlpar_offline_cpu(struct device_node *dn)
 509 {
 510         int rc = 0;
 511         unsigned int cpu;
 512         int len, nthreads, i;
 513         const __be32 *intserv;
 514         u32 thread;
 515 
 516         intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
 517         if (!intserv)
 518                 return -EINVAL;
 519 
 520         nthreads = len / sizeof(u32);
 521 
 522         cpu_maps_update_begin();
 523         for (i = 0; i < nthreads; i++) {
 524                 thread = be32_to_cpu(intserv[i]);
 525                 for_each_present_cpu(cpu) {
 526                         if (get_hard_smp_processor_id(cpu) != thread)
 527                                 continue;
 528 
 529                         if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
 530                                 break;
 531 
 532                         if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
 533                                 set_preferred_offline_state(cpu,
 534                                                             CPU_STATE_OFFLINE);
 535                                 cpu_maps_update_done();
 536                                 timed_topology_update(1);
 537                                 rc = device_offline(get_cpu_device(cpu));
 538                                 if (rc)
 539                                         goto out;
 540                                 cpu_maps_update_begin();
 541                                 break;
 542 
 543                         }
 544 
 545                         /*
 546                          * The cpu is in CPU_STATE_INACTIVE.
 547                          * Upgrade it's state to CPU_STATE_OFFLINE.
 548                          */
 549                         set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
 550                         BUG_ON(plpar_hcall_norets(H_PROD, thread)
 551                                                                 != H_SUCCESS);
 552                         __cpu_die(cpu);
 553                         break;
 554                 }
 555                 if (cpu == num_possible_cpus())
 556                         printk(KERN_WARNING "Could not find cpu to offline with physical id 0x%x\n", thread);
 557         }
 558         cpu_maps_update_done();
 559 
 560 out:
 561         return rc;
 562 
 563 }
 564 
 565 static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
 566 {
 567         int rc;
 568 
 569         pr_debug("Attempting to remove CPU %pOFn, drc index: %x\n",
 570                  dn, drc_index);
 571 
 572         rc = dlpar_offline_cpu(dn);
 573         if (rc) {
 574                 pr_warn("Failed to offline CPU %pOFn, rc: %d\n", dn, rc);
 575                 return -EINVAL;
 576         }
 577 
 578         rc = dlpar_release_drc(drc_index);
 579         if (rc) {
 580                 pr_warn("Failed to release drc (%x) for CPU %pOFn, rc: %d\n",
 581                         drc_index, dn, rc);
 582                 dlpar_online_cpu(dn);
 583                 return rc;
 584         }
 585 
 586         rc = dlpar_detach_node(dn);
 587         if (rc) {
 588                 int saved_rc = rc;
 589 
 590                 pr_warn("Failed to detach CPU %pOFn, rc: %d", dn, rc);
 591 
 592                 rc = dlpar_acquire_drc(drc_index);
 593                 if (!rc)
 594                         dlpar_online_cpu(dn);
 595 
 596                 return saved_rc;
 597         }
 598 
 599         pr_debug("Successfully removed CPU, drc index: %x\n", drc_index);
 600         return 0;
 601 }
 602 
 603 static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
 604 {
 605         struct device_node *dn;
 606         u32 my_index;
 607         int rc;
 608 
 609         for_each_node_by_type(dn, "cpu") {
 610                 rc = of_property_read_u32(dn, "ibm,my-drc-index", &my_index);
 611                 if (rc)
 612                         continue;
 613 
 614                 if (my_index == drc_index)
 615                         break;
 616         }
 617 
 618         return dn;
 619 }
 620 
 621 static int dlpar_cpu_remove_by_index(u32 drc_index)
 622 {
 623         struct device_node *dn;
 624         int rc;
 625 
 626         dn = cpu_drc_index_to_dn(drc_index);
 627         if (!dn) {
 628                 pr_warn("Cannot find CPU (drc index %x) to remove\n",
 629                         drc_index);
 630                 return -ENODEV;
 631         }
 632 
 633         rc = dlpar_cpu_remove(dn, drc_index);
 634         of_node_put(dn);
 635         return rc;
 636 }
 637 
 638 static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
 639 {
 640         struct device_node *dn;
 641         int cpus_found = 0;
 642         int rc;
 643 
 644         /* We want to find cpus_to_remove + 1 CPUs to ensure we do not
 645          * remove the last CPU.
 646          */
 647         for_each_node_by_type(dn, "cpu") {
 648                 cpus_found++;
 649 
 650                 if (cpus_found > cpus_to_remove) {
 651                         of_node_put(dn);
 652                         break;
 653                 }
 654 
 655                 /* Note that cpus_found is always 1 ahead of the index
 656                  * into the cpu_drcs array, so we use cpus_found - 1
 657                  */
 658                 rc = of_property_read_u32(dn, "ibm,my-drc-index",
 659                                           &cpu_drcs[cpus_found - 1]);
 660                 if (rc) {
 661                         pr_warn("Error occurred getting drc-index for %pOFn\n",
 662                                 dn);
 663                         of_node_put(dn);
 664                         return -1;
 665                 }
 666         }
 667 
 668         if (cpus_found < cpus_to_remove) {
 669                 pr_warn("Failed to find enough CPUs (%d of %d) to remove\n",
 670                         cpus_found, cpus_to_remove);
 671         } else if (cpus_found == cpus_to_remove) {
 672                 pr_warn("Cannot remove all CPUs\n");
 673         }
 674 
 675         return cpus_found;
 676 }
 677 
 678 static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
 679 {
 680         u32 *cpu_drcs;
 681         int cpus_found;
 682         int cpus_removed = 0;
 683         int i, rc;
 684 
 685         pr_debug("Attempting to hot-remove %d CPUs\n", cpus_to_remove);
 686 
 687         cpu_drcs = kcalloc(cpus_to_remove, sizeof(*cpu_drcs), GFP_KERNEL);
 688         if (!cpu_drcs)
 689                 return -EINVAL;
 690 
 691         cpus_found = find_dlpar_cpus_to_remove(cpu_drcs, cpus_to_remove);
 692         if (cpus_found <= cpus_to_remove) {
 693                 kfree(cpu_drcs);
 694                 return -EINVAL;
 695         }
 696 
 697         for (i = 0; i < cpus_to_remove; i++) {
 698                 rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
 699                 if (rc)
 700                         break;
 701 
 702                 cpus_removed++;
 703         }
 704 
 705         if (cpus_removed != cpus_to_remove) {
 706                 pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
 707 
 708                 for (i = 0; i < cpus_removed; i++)
 709                         dlpar_cpu_add(cpu_drcs[i]);
 710 
 711                 rc = -EINVAL;
 712         } else {
 713                 rc = 0;
 714         }
 715 
 716         kfree(cpu_drcs);
 717         return rc;
 718 }
 719 
 720 static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add)
 721 {
 722         struct device_node *parent;
 723         int cpus_found = 0;
 724         int index, rc;
 725 
 726         parent = of_find_node_by_path("/cpus");
 727         if (!parent) {
 728                 pr_warn("Could not find CPU root node in device tree\n");
 729                 kfree(cpu_drcs);
 730                 return -1;
 731         }
 732 
 733         /* Search the ibm,drc-indexes array for possible CPU drcs to
 734          * add. Note that the format of the ibm,drc-indexes array is
 735          * the number of entries in the array followed by the array
 736          * of drc values so we start looking at index = 1.
 737          */
 738         index = 1;
 739         while (cpus_found < cpus_to_add) {
 740                 u32 drc;
 741 
 742                 rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
 743                                                 index++, &drc);
 744                 if (rc)
 745                         break;
 746 
 747                 if (dlpar_cpu_exists(parent, drc))
 748                         continue;
 749 
 750                 cpu_drcs[cpus_found++] = drc;
 751         }
 752 
 753         of_node_put(parent);
 754         return cpus_found;
 755 }
 756 
 757 static int dlpar_cpu_add_by_count(u32 cpus_to_add)
 758 {
 759         u32 *cpu_drcs;
 760         int cpus_added = 0;
 761         int cpus_found;
 762         int i, rc;
 763 
 764         pr_debug("Attempting to hot-add %d CPUs\n", cpus_to_add);
 765 
 766         cpu_drcs = kcalloc(cpus_to_add, sizeof(*cpu_drcs), GFP_KERNEL);
 767         if (!cpu_drcs)
 768                 return -EINVAL;
 769 
 770         cpus_found = find_dlpar_cpus_to_add(cpu_drcs, cpus_to_add);
 771         if (cpus_found < cpus_to_add) {
 772                 pr_warn("Failed to find enough CPUs (%d of %d) to add\n",
 773                         cpus_found, cpus_to_add);
 774                 kfree(cpu_drcs);
 775                 return -EINVAL;
 776         }
 777 
 778         for (i = 0; i < cpus_to_add; i++) {
 779                 rc = dlpar_cpu_add(cpu_drcs[i]);
 780                 if (rc)
 781                         break;
 782 
 783                 cpus_added++;
 784         }
 785 
 786         if (cpus_added < cpus_to_add) {
 787                 pr_warn("CPU hot-add failed, removing any added CPUs\n");
 788 
 789                 for (i = 0; i < cpus_added; i++)
 790                         dlpar_cpu_remove_by_index(cpu_drcs[i]);
 791 
 792                 rc = -EINVAL;
 793         } else {
 794                 rc = 0;
 795         }
 796 
 797         kfree(cpu_drcs);
 798         return rc;
 799 }
 800 
 801 int dlpar_cpu_readd(int cpu)
 802 {
 803         struct device_node *dn;
 804         struct device *dev;
 805         u32 drc_index;
 806         int rc;
 807 
 808         dev = get_cpu_device(cpu);
 809         dn = dev->of_node;
 810 
 811         rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
 812 
 813         rc = dlpar_cpu_remove_by_index(drc_index);
 814         if (!rc)
 815                 rc = dlpar_cpu_add(drc_index);
 816 
 817         return rc;
 818 }
 819 
 820 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
 821 {
 822         u32 count, drc_index;
 823         int rc;
 824 
 825         count = hp_elog->_drc_u.drc_count;
 826         drc_index = hp_elog->_drc_u.drc_index;
 827 
 828         lock_device_hotplug();
 829 
 830         switch (hp_elog->action) {
 831         case PSERIES_HP_ELOG_ACTION_REMOVE:
 832                 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
 833                         rc = dlpar_cpu_remove_by_count(count);
 834                 else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
 835                         rc = dlpar_cpu_remove_by_index(drc_index);
 836                 else
 837                         rc = -EINVAL;
 838                 break;
 839         case PSERIES_HP_ELOG_ACTION_ADD:
 840                 if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
 841                         rc = dlpar_cpu_add_by_count(count);
 842                 else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
 843                         rc = dlpar_cpu_add(drc_index);
 844                 else
 845                         rc = -EINVAL;
 846                 break;
 847         default:
 848                 pr_err("Invalid action (%d) specified\n", hp_elog->action);
 849                 rc = -EINVAL;
 850                 break;
 851         }
 852 
 853         unlock_device_hotplug();
 854         return rc;
 855 }
 856 
 857 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 858 
 859 static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
 860 {
 861         u32 drc_index;
 862         int rc;
 863 
 864         rc = kstrtou32(buf, 0, &drc_index);
 865         if (rc)
 866                 return -EINVAL;
 867 
 868         rc = dlpar_cpu_add(drc_index);
 869 
 870         return rc ? rc : count;
 871 }
 872 
 873 static ssize_t dlpar_cpu_release(const char *buf, size_t count)
 874 {
 875         struct device_node *dn;
 876         u32 drc_index;
 877         int rc;
 878 
 879         dn = of_find_node_by_path(buf);
 880         if (!dn)
 881                 return -EINVAL;
 882 
 883         rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
 884         if (rc) {
 885                 of_node_put(dn);
 886                 return -EINVAL;
 887         }
 888 
 889         rc = dlpar_cpu_remove(dn, drc_index);
 890         of_node_put(dn);
 891 
 892         return rc ? rc : count;
 893 }
 894 
 895 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 896 
 897 static int pseries_smp_notifier(struct notifier_block *nb,
 898                                 unsigned long action, void *data)
 899 {
 900         struct of_reconfig_data *rd = data;
 901         int err = 0;
 902 
 903         switch (action) {
 904         case OF_RECONFIG_ATTACH_NODE:
 905                 err = pseries_add_processor(rd->dn);
 906                 break;
 907         case OF_RECONFIG_DETACH_NODE:
 908                 pseries_remove_processor(rd->dn);
 909                 break;
 910         }
 911         return notifier_from_errno(err);
 912 }
 913 
 914 static struct notifier_block pseries_smp_nb = {
 915         .notifier_call = pseries_smp_notifier,
 916 };
 917 
 918 #define MAX_CEDE_LATENCY_LEVELS         4
 919 #define CEDE_LATENCY_PARAM_LENGTH       10
 920 #define CEDE_LATENCY_PARAM_MAX_LENGTH   \
 921         (MAX_CEDE_LATENCY_LEVELS * CEDE_LATENCY_PARAM_LENGTH * sizeof(char))
 922 #define CEDE_LATENCY_TOKEN              45
 923 
 924 static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH];
 925 
 926 static int parse_cede_parameters(void)
 927 {
 928         memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
 929         return rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
 930                          NULL,
 931                          CEDE_LATENCY_TOKEN,
 932                          __pa(cede_parameters),
 933                          CEDE_LATENCY_PARAM_MAX_LENGTH);
 934 }
 935 
 936 static int __init pseries_cpu_hotplug_init(void)
 937 {
 938         int cpu;
 939         int qcss_tok;
 940 
 941 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 942         ppc_md.cpu_probe = dlpar_cpu_probe;
 943         ppc_md.cpu_release = dlpar_cpu_release;
 944 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 945 
 946         rtas_stop_self_token = rtas_token("stop-self");
 947         qcss_tok = rtas_token("query-cpu-stopped-state");
 948 
 949         if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE ||
 950                         qcss_tok == RTAS_UNKNOWN_SERVICE) {
 951                 printk(KERN_INFO "CPU Hotplug not supported by firmware "
 952                                 "- disabling.\n");
 953                 return 0;
 954         }
 955 
 956         ppc_md.cpu_die = pseries_mach_cpu_die;
 957         smp_ops->cpu_disable = pseries_cpu_disable;
 958         smp_ops->cpu_die = pseries_cpu_die;
 959 
 960         /* Processors can be added/removed only on LPAR */
 961         if (firmware_has_feature(FW_FEATURE_LPAR)) {
 962                 of_reconfig_notifier_register(&pseries_smp_nb);
 963                 cpu_maps_update_begin();
 964                 if (cede_offline_enabled && parse_cede_parameters() == 0) {
 965                         default_offline_state = CPU_STATE_INACTIVE;
 966                         for_each_online_cpu(cpu)
 967                                 set_default_offline_state(cpu);
 968                 }
 969                 cpu_maps_update_done();
 970         }
 971 
 972         return 0;
 973 }
 974 machine_arch_initcall(pseries, pseries_cpu_hotplug_init);

/* [<][>][^][v][top][bottom][index][help] */