Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf/x86/intel/pt: Clean up the control flow in pt_pmu_hw_init()

Dan Carpenter pointed out that the control flow in pt_pmu_hw_init()
is a bit messy: for example the kfree(de_attrs) is entirely
superfluous.

Another problem is the inconsistent mixing of label based and
direct return error handling.

Add modern, label based error handling instead and clean up the code
a bit as well.

Note that we'll still do a kfree(NULL) in the normal case - this does
not matter as this is an init path and kfree() returns early if it
sees a NULL.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20150409090805.GG17605@mwanda
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+30 -23
+30 -23
arch/x86/kernel/cpu/perf_event_intel_pt.c
··· 119 119 struct dev_ext_attribute *de_attrs; 120 120 struct attribute **attrs; 121 121 size_t size; 122 + int ret; 122 123 long i; 123 124 124 - if (test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT)) { 125 - for (i = 0; i < PT_CPUID_LEAVES; i++) 126 - cpuid_count(20, i, 127 - &pt_pmu.caps[CR_EAX + i * 4], 128 - &pt_pmu.caps[CR_EBX + i * 4], 129 - &pt_pmu.caps[CR_ECX + i * 4], 130 - &pt_pmu.caps[CR_EDX + i * 4]); 131 - } else { 132 - return -ENODEV; 125 + attrs = NULL; 126 + ret = -ENODEV; 127 + if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_INTEL_PT)) 128 + goto fail; 129 + 130 + for (i = 0; i < PT_CPUID_LEAVES; i++) { 131 + cpuid_count(20, i, 132 + &pt_pmu.caps[CR_EAX + i*4], 133 + &pt_pmu.caps[CR_EBX + i*4], 134 + &pt_pmu.caps[CR_ECX + i*4], 135 + &pt_pmu.caps[CR_EDX + i*4]); 133 136 } 134 137 135 - size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps) + 1); 138 + ret = -ENOMEM; 139 + size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1); 136 140 attrs = kzalloc(size, GFP_KERNEL); 137 141 if (!attrs) 138 - goto err_attrs; 142 + goto fail; 139 143 140 - size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps) + 1); 144 + size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1); 141 145 de_attrs = kzalloc(size, GFP_KERNEL); 142 146 if (!de_attrs) 143 - goto err_de_attrs; 147 + goto fail; 144 148 145 149 for (i = 0; i < ARRAY_SIZE(pt_caps); i++) { 146 - de_attrs[i].attr.attr.name = pt_caps[i].name; 150 + struct dev_ext_attribute *de_attr = de_attrs + i; 147 151 148 - sysfs_attr_init(&de_attrs[i].attr.attr); 149 - de_attrs[i].attr.attr.mode = S_IRUGO; 150 - de_attrs[i].attr.show = pt_cap_show; 151 - de_attrs[i].var = (void *)i; 152 - attrs[i] = &de_attrs[i].attr.attr; 152 + de_attr->attr.attr.name = pt_caps[i].name; 153 + 154 + sysfs_attr_init(&de_attrs->attr.attr); 155 + 156 + de_attr->attr.attr.mode = S_IRUGO; 157 + de_attr->attr.show = pt_cap_show; 158 + de_attr->var = (void *)i; 159 + 160 + attrs[i] = &de_attr->attr.attr; 153 161 } 154 162 155 163 pt_cap_group.attrs = attrs; 164 + 156 165 return 0; 157 166 158 - err_de_attrs: 159 - kfree(de_attrs); 160 - err_attrs: 167 + fail: 161 168 kfree(attrs); 162 169 163 - return -ENOMEM; 170 + return ret; 164 171 } 165 172 166 173 #define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | RTIT_CTL_DISRETC)