From: Nathan F. <nf...@au...> - 2009-09-15 19:04:14
|
This patch updates the drmgr command to do CPU DLPAR on kernels that have been enabled to do the DLPAR work in the kernel. Previously the work of acquiring the cpu from firmware vi a rtas calls and updating the device tree was done by drmgr. On newer kernels this is now done in the kernel by writing to the sysfs cpu 'probe' file. Note: this patch is entirely dependent on the patch set to enable kernel dlpar capabilities that has been submitted to the mailing lists. Signed-off-by: Nathan Fontenot <nf...@au...> --- Index: powerpc-utils/src/drmgr/common_cpu.c =================================================================== --- powerpc-utils.orig/src/drmgr/common_cpu.c 2009-09-15 10:15:17.000000000 -0500 +++ powerpc-utils/src/drmgr/common_cpu.c 2009-09-15 11:21:51.000000000 -0500 @@ -604,7 +604,7 @@ * @param drc_index * @returns pointer to cpu_info on success, NULL otherwise */ -int +static int acquire_cpu(struct dr_node *cpu, struct dr_info *dr_info) { struct of_node *of_nodes; @@ -637,6 +637,43 @@ return 0; } +int +probe_cpu(struct dr_node *cpu, struct dr_info *dr_info) +{ + char drc_index[DR_STR_MAX]; + int probe_file; + int write_len; + int rc = 0; + + probe_file = open(CPU_PROBE_FILE, O_WRONLY); + if (probe_file <= 0) { + /* Attempt to add cpu from user-space, this may be an older + * kernel without the infrastructure to handle dlpar. + */ + rc = acquire_cpu(cpu, dr_info); + } else { + memset(drc_index, 0, DR_STR_MAX); + write_len = sprintf(drc_index, "0x%x", cpu->drc_index); + + dbg("Probing cpu 0x%x\n", cpu->drc_index); + rc = write(probe_file, drc_index, write_len); + if (rc != write_len) + dbg("Probe failed! rc = %x\n", rc); + else + /* reset rc to success */ + rc = 0; + + close(probe_file); + } + + if (!rc) { + update_cpu_node(cpu, NULL, dr_info); + refresh_cache_info(dr_info); + } + + return rc; +} + /** * release_caches * Remove any unused cache info. Failure to remove the cache, while not @@ -688,39 +725,60 @@ int release_cpu(struct dr_node *cpu, struct dr_info *dr_info) { + int release_file; int rc; - /* Should we check to make sure all threads of the cpu are offline? */ - - rc = release_drc(cpu->drc_index, CPU_DEV); - if (rc) { - dbg("Could not release drc resources for %s\n", cpu->name); - return rc; - } + release_file = open(CPU_RELEASE_FILE, O_WRONLY); + if (release_file > 0) { + /* DLPAR can be done in kernel */ + char *path = cpu->ofdt_path + strlen(OFDT_BASE); + int write_len = strlen(path); + + dbg("Releasing cpu \"%s\"\n", path); + rc = write(release_file, path, write_len); + if (rc != write_len) + dbg("Release failed! rc = %d\n", rc); + else + /* set rc to success */ + rc = 0; + + close(release_file); + } else { + /* Must do DLPAR from user-space */ + rc = release_drc(cpu->drc_index, CPU_DEV); + if (rc) { + dbg("Could not release drc resources for %s\n", + cpu->name); + return rc; + } - rc = remove_device_tree_nodes(cpu->ofdt_path); - if (rc) { - struct of_node *of_nodes; + rc = remove_device_tree_nodes(cpu->ofdt_path); + if (rc) { + struct of_node *of_nodes; - dbg("Could not remove device tree nodes %s\n", cpu->name); + dbg("Could not remove device tree nodes %s\n", + cpu->name); - of_nodes = configure_connector(cpu->drc_index); - if (of_nodes == NULL) { - err_msg("Call to configure_connector failed for %s. " - "The device tree\nmay contain invalid data " - "for this cpu and a re-activation of the " - "partition is needed to correct it.\n", - cpu->name); - } else { - rc = add_device_tree_nodes(CPU_OFDT_BASE, of_nodes); - free_of_node(of_nodes); + of_nodes = configure_connector(cpu->drc_index); + if (of_nodes == NULL) { + err_msg("Call to configure_connector failed " + "for %s. The device tree\nmay contain " + "invalid data for this cpu and a " + "re-activation of the partition is " + "needed to correct it.\n", cpu->name); + } else { + rc = add_device_tree_nodes(CPU_OFDT_BASE, + of_nodes); + free_of_node(of_nodes); + } + + acquire_drc(cpu->drc_index); + return rc; } - acquire_drc(cpu->drc_index); - return rc; + release_caches(cpu, dr_info); } - release_caches(cpu, dr_info); return rc; } Index: powerpc-utils/src/drmgr/drcpu.h =================================================================== --- powerpc-utils.orig/src/drmgr/drcpu.h 2009-09-15 10:15:17.000000000 -0500 +++ powerpc-utils/src/drmgr/drcpu.h 2009-09-15 10:46:08.000000000 -0500 @@ -9,6 +9,9 @@ #include "dr.h" +#define CPU_PROBE_FILE "/sys/devices/system/cpu/probe" +#define CPU_RELEASE_FILE "/sys/devices/system/cpu/release" + struct cache_info { char name[DR_BUF_SZ]; /* node name */ char path[DR_BUF_SZ]; /* node path */ @@ -45,7 +48,7 @@ struct cache_info * cache_get_dependent_cache(struct cache_info *, struct dr_info *); int release_cpu(struct dr_node *, struct dr_info *); -int acquire_cpu(struct dr_node *, struct dr_info *); +int probe_cpu(struct dr_node *, struct dr_info *); struct dr_node *get_available_cpu(struct options *, struct dr_info *); #endif /* _H_DRCPU */ Index: powerpc-utils/src/drmgr/drslot_chrp_cpu.c =================================================================== --- powerpc-utils.orig/src/drmgr/drslot_chrp_cpu.c 2009-09-15 10:15:17.000000000 -0500 +++ powerpc-utils/src/drmgr/drslot_chrp_cpu.c 2009-09-15 10:33:21.000000000 -0500 @@ -138,7 +138,7 @@ if (!cpu) break; - rc = acquire_cpu(cpu, dr_info); + rc = probe_cpu(cpu, dr_info); if (rc) { dbg("Unable to acquire CPU with drc index %x\n", cpu->drc_index); |