In the pfm_pmu_register() routine, if the calls to pfm_pmu_config_init() and
pfm_arch_pmu_config_init() both succeed, but the call to pfm_sysfs_add_pmu()
fails, we should call pfm_arch_pmu_config_remove() so the arch-specific code
can undo whatever was done in pfm_arch_pmu_config_init().
This also rearranges the code in the spinlock'ed section to make it a little
easier to follow all the possible error paths.
Signed-off-by: Kevin Corry <[EMAIL PROTECTED]>
Index: linux-2.6.20-arnd3-perfmon2/perfmon/perfmon_pmu.c
===================================================================
--- linux-2.6.20-arnd3-perfmon2.orig/perfmon/perfmon_pmu.c
+++ linux-2.6.20-arnd3-perfmon2/perfmon/perfmon_pmu.c
@@ -184,7 +184,7 @@ PFM_LOG("pfm_pmu_conf=%p sz=%zu", &_pfm_
int pfm_pmu_register(struct pfm_pmu_config *cfg)
{
u16 i, nspec, nspec_ro, num_pmcs, num_pmds, num_wc = 0;
- int type, ret;
+ int type, ret = -EBUSY;
if (atomic_read(&perfmon_disabled)) {
PFM_INFO("perfmon disabled, cannot add PMU description");
@@ -310,19 +310,25 @@ int pfm_pmu_register(struct pfm_pmu_conf
spin_lock(&pfm_pmu_conf_lock);
- if (pfm_pmu_conf) {
- ret = -EBUSY;
- } else {
- ret = pfm_pmu_config_init(cfg);
- if (!ret)
- ret = pfm_arch_pmu_config_init(&_pfm_pmu_conf);
- }
- if (!ret) {
- pfm_pmu_conf = &_pfm_pmu_conf;
- ret = pfm_sysfs_add_pmu(pfm_pmu_conf);
- if (ret)
- pfm_pmu_conf = NULL;
+ if (pfm_pmu_conf)
+ goto unlock;
+
+ ret = pfm_pmu_config_init(cfg);
+ if (ret)
+ goto unlock;
+
+ ret = pfm_arch_pmu_config_init(&_pfm_pmu_conf);
+ if (ret)
+ goto unlock;
+
+ pfm_pmu_conf = &_pfm_pmu_conf;
+ ret = pfm_sysfs_add_pmu(pfm_pmu_conf);
+ if (ret) {
+ pfm_arch_pmu_config_remove();
+ pfm_pmu_conf = NULL;
}
+
+unlock:
spin_unlock(&pfm_pmu_conf_lock);
if (ret) {
_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/