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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"This tree includes various fixes"

Ingo really needs to improve on the whole "explain git pull" part.
"Various fixes" indeed.

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/hwpb: Invoke __perf_event_disable() if interrupts are already disabled
perf/x86: Enable Intel Cedarview Atom suppport
perf_event: Switch to internal refcount, fix race with close()
oprofile, s390: Fix uninitialized memory access when writing to oprofilefs
perf/x86: Fix microcode revision check for SNB-PEBS

+58 -38
+5 -5
arch/s390/oprofile/init.c
··· 169 169 if (*offset) 170 170 return -EINVAL; 171 171 retval = oprofilefs_ulong_from_user(&val, buf, count); 172 - if (retval) 172 + if (retval <= 0) 173 173 return retval; 174 174 if (val < oprofile_min_interval) 175 175 oprofile_hw_interval = oprofile_min_interval; ··· 212 212 return -EINVAL; 213 213 214 214 retval = oprofilefs_ulong_from_user(&val, buf, count); 215 - if (retval) 215 + if (retval <= 0) 216 216 return retval; 217 217 if (val != 0) 218 218 return -EINVAL; ··· 243 243 return -EINVAL; 244 244 245 245 retval = oprofilefs_ulong_from_user(&val, buf, count); 246 - if (retval) 246 + if (retval <= 0) 247 247 return retval; 248 248 249 249 if (val != 0 && val != 1) ··· 278 278 return -EINVAL; 279 279 280 280 retval = oprofilefs_ulong_from_user(&val, buf, count); 281 - if (retval) 281 + if (retval <= 0) 282 282 return retval; 283 283 284 284 if (val != 0 && val != 1) ··· 317 317 return -EINVAL; 318 318 319 319 retval = oprofilefs_ulong_from_user(&val, buf, count); 320 - if (retval) 320 + if (retval <= 0) 321 321 return retval; 322 322 323 323 if (val != 0 && val != 1)
+1
arch/x86/kernel/cpu/perf_event_intel.c
··· 2008 2008 break; 2009 2009 2010 2010 case 28: /* Atom */ 2011 + case 54: /* Cedariew */ 2011 2012 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, 2012 2013 sizeof(hw_cache_event_ids)); 2013 2014
+2 -1
arch/x86/kernel/cpu/perf_event_intel_lbr.c
··· 686 686 * to have an operational LBR which can freeze 687 687 * on PMU interrupt 688 688 */ 689 - if (boot_cpu_data.x86_mask < 10) { 689 + if (boot_cpu_data.x86_model == 28 690 + && boot_cpu_data.x86_mask < 10) { 690 691 pr_cont("LBR disabled due to erratum"); 691 692 return; 692 693 }
+3
arch/x86/kernel/microcode_core.c
··· 225 225 if (do_microcode_update(buf, len) == 0) 226 226 ret = (ssize_t)len; 227 227 228 + if (ret > 0) 229 + perf_check_microcode(); 230 + 228 231 mutex_unlock(&microcode_mutex); 229 232 put_online_cpus(); 230 233
+3 -1
include/linux/perf_event.h
··· 926 926 struct hw_perf_event hw; 927 927 928 928 struct perf_event_context *ctx; 929 - struct file *filp; 929 + atomic_long_t refcount; 930 930 931 931 /* 932 932 * These accumulate total time (in nanoseconds) that children ··· 1296 1296 extern void perf_swevent_put_recursion_context(int rctx); 1297 1297 extern void perf_event_enable(struct perf_event *event); 1298 1298 extern void perf_event_disable(struct perf_event *event); 1299 + extern int __perf_event_disable(void *info); 1299 1300 extern void perf_event_task_tick(void); 1300 1301 #else 1301 1302 static inline void ··· 1335 1334 static inline void perf_swevent_put_recursion_context(int rctx) { } 1336 1335 static inline void perf_event_enable(struct perf_event *event) { } 1337 1336 static inline void perf_event_disable(struct perf_event *event) { } 1337 + static inline int __perf_event_disable(void *info) { return -1; } 1338 1338 static inline void perf_event_task_tick(void) { } 1339 1339 #endif 1340 1340
+34 -30
kernel/events/core.c
··· 1253 1253 /* 1254 1254 * Cross CPU call to disable a performance event 1255 1255 */ 1256 - static int __perf_event_disable(void *info) 1256 + int __perf_event_disable(void *info) 1257 1257 { 1258 1258 struct perf_event *event = info; 1259 1259 struct perf_event_context *ctx = event->ctx; ··· 2935 2935 /* 2936 2936 * Called when the last reference to the file is gone. 2937 2937 */ 2938 - static int perf_release(struct inode *inode, struct file *file) 2938 + static void put_event(struct perf_event *event) 2939 2939 { 2940 - struct perf_event *event = file->private_data; 2941 2940 struct task_struct *owner; 2942 2941 2943 - file->private_data = NULL; 2942 + if (!atomic_long_dec_and_test(&event->refcount)) 2943 + return; 2944 2944 2945 2945 rcu_read_lock(); 2946 2946 owner = ACCESS_ONCE(event->owner); ··· 2975 2975 put_task_struct(owner); 2976 2976 } 2977 2977 2978 - return perf_event_release_kernel(event); 2978 + perf_event_release_kernel(event); 2979 + } 2980 + 2981 + static int perf_release(struct inode *inode, struct file *file) 2982 + { 2983 + put_event(file->private_data); 2984 + return 0; 2979 2985 } 2980 2986 2981 2987 u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) ··· 3233 3227 3234 3228 static const struct file_operations perf_fops; 3235 3229 3236 - static struct perf_event *perf_fget_light(int fd, int *fput_needed) 3230 + static struct file *perf_fget_light(int fd, int *fput_needed) 3237 3231 { 3238 3232 struct file *file; 3239 3233 ··· 3247 3241 return ERR_PTR(-EBADF); 3248 3242 } 3249 3243 3250 - return file->private_data; 3244 + return file; 3251 3245 } 3252 3246 3253 3247 static int perf_event_set_output(struct perf_event *event, ··· 3279 3273 3280 3274 case PERF_EVENT_IOC_SET_OUTPUT: 3281 3275 { 3276 + struct file *output_file = NULL; 3282 3277 struct perf_event *output_event = NULL; 3283 3278 int fput_needed = 0; 3284 3279 int ret; 3285 3280 3286 3281 if (arg != -1) { 3287 - output_event = perf_fget_light(arg, &fput_needed); 3288 - if (IS_ERR(output_event)) 3289 - return PTR_ERR(output_event); 3282 + output_file = perf_fget_light(arg, &fput_needed); 3283 + if (IS_ERR(output_file)) 3284 + return PTR_ERR(output_file); 3285 + output_event = output_file->private_data; 3290 3286 } 3291 3287 3292 3288 ret = perf_event_set_output(event, output_event); 3293 3289 if (output_event) 3294 - fput_light(output_event->filp, fput_needed); 3290 + fput_light(output_file, fput_needed); 3295 3291 3296 3292 return ret; 3297 3293 } ··· 5958 5950 5959 5951 mutex_init(&event->mmap_mutex); 5960 5952 5953 + atomic_long_set(&event->refcount, 1); 5961 5954 event->cpu = cpu; 5962 5955 event->attr = *attr; 5963 5956 event->group_leader = group_leader; ··· 6269 6260 return event_fd; 6270 6261 6271 6262 if (group_fd != -1) { 6272 - group_leader = perf_fget_light(group_fd, &fput_needed); 6273 - if (IS_ERR(group_leader)) { 6274 - err = PTR_ERR(group_leader); 6263 + group_file = perf_fget_light(group_fd, &fput_needed); 6264 + if (IS_ERR(group_file)) { 6265 + err = PTR_ERR(group_file); 6275 6266 goto err_fd; 6276 6267 } 6277 - group_file = group_leader->filp; 6268 + group_leader = group_file->private_data; 6278 6269 if (flags & PERF_FLAG_FD_OUTPUT) 6279 6270 output_event = group_leader; 6280 6271 if (flags & PERF_FLAG_FD_NO_GROUP) ··· 6411 6402 put_ctx(gctx); 6412 6403 } 6413 6404 6414 - event->filp = event_file; 6415 6405 WARN_ON_ONCE(ctx->parent_ctx); 6416 6406 mutex_lock(&ctx->mutex); 6417 6407 ··· 6504 6496 goto err_free; 6505 6497 } 6506 6498 6507 - event->filp = NULL; 6508 6499 WARN_ON_ONCE(ctx->parent_ctx); 6509 6500 mutex_lock(&ctx->mutex); 6510 6501 perf_install_in_context(ctx, event, cpu); ··· 6585 6578 * Release the parent event, if this was the last 6586 6579 * reference to it. 6587 6580 */ 6588 - fput(parent_event->filp); 6581 + put_event(parent_event); 6589 6582 } 6590 6583 6591 6584 static void ··· 6661 6654 * 6662 6655 * __perf_event_exit_task() 6663 6656 * sync_child_event() 6664 - * fput(parent_event->filp) 6665 - * perf_release() 6666 - * mutex_lock(&ctx->mutex) 6657 + * put_event() 6658 + * mutex_lock(&ctx->mutex) 6667 6659 * 6668 6660 * But since its the parent context it won't be the same instance. 6669 6661 */ ··· 6730 6724 list_del_init(&event->child_list); 6731 6725 mutex_unlock(&parent->child_mutex); 6732 6726 6733 - fput(parent->filp); 6727 + put_event(parent); 6734 6728 6735 6729 perf_group_detach(event); 6736 6730 list_del_event(event, ctx); ··· 6810 6804 NULL, NULL); 6811 6805 if (IS_ERR(child_event)) 6812 6806 return child_event; 6807 + 6808 + if (!atomic_long_inc_not_zero(&parent_event->refcount)) { 6809 + free_event(child_event); 6810 + return NULL; 6811 + } 6812 + 6813 6813 get_ctx(child_ctx); 6814 6814 6815 6815 /* ··· 6855 6843 raw_spin_lock_irqsave(&child_ctx->lock, flags); 6856 6844 add_event_to_ctx(child_event, child_ctx); 6857 6845 raw_spin_unlock_irqrestore(&child_ctx->lock, flags); 6858 - 6859 - /* 6860 - * Get a reference to the parent filp - we will fput it 6861 - * when the child event exits. This is safe to do because 6862 - * we are in the parent and we know that the filp still 6863 - * exists and has a nonzero count: 6864 - */ 6865 - atomic_long_inc(&parent_event->filp->f_count); 6866 6846 6867 6847 /* 6868 6848 * Link this into the parent event's child list
+10 -1
kernel/events/hw_breakpoint.c
··· 453 453 int old_type = bp->attr.bp_type; 454 454 int err = 0; 455 455 456 - perf_event_disable(bp); 456 + /* 457 + * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it 458 + * will not be possible to raise IPIs that invoke __perf_event_disable. 459 + * So call the function directly after making sure we are targeting the 460 + * current task. 461 + */ 462 + if (irqs_disabled() && bp->ctx && bp->ctx->task == current) 463 + __perf_event_disable(bp); 464 + else 465 + perf_event_disable(bp); 457 466 458 467 bp->attr.bp_addr = attr->bp_addr; 459 468 bp->attr.bp_type = attr->bp_type;