···433433 dr6_p = (unsigned long *)ERR_PTR(args->err);434434 dr6 = *dr6_p;435435436436+ /* If it's a single step, TRAP bits are random */437437+ if (dr6 & DR_STEP)438438+ return NOTIFY_DONE;439439+436440 /* Do an early return if no trap bits are set in DR6 */437441 if ((dr6 & DR_TRAP_BITS) == 0)438442 return NOTIFY_DONE;
···620620 .read = hw_breakpoint_pmu_read,621621};622622623623-static int __init init_hw_breakpoint(void)623623+int __init init_hw_breakpoint(void)624624{625625 unsigned int **task_bp_pinned;626626 int cpu, err_cpu;···655655656656 return -ENOMEM;657657}658658-core_initcall(init_hw_breakpoint);659658660659
+3-1
kernel/irq_work.c
···145145 * Clear the BUSY bit and return to the free state if146146 * no-one else claimed it meanwhile.147147 */148148- cmpxchg(&entry->next, next_flags(NULL, IRQ_WORK_BUSY), NULL);148148+ (void)cmpxchg(&entry->next,149149+ next_flags(NULL, IRQ_WORK_BUSY),150150+ NULL);149151 }150152}151153EXPORT_SYMBOL_GPL(irq_work_run);
+77-16
kernel/perf_event.c
···3131#include <linux/kernel_stat.h>3232#include <linux/perf_event.h>3333#include <linux/ftrace_event.h>3434+#include <linux/hw_breakpoint.h>34353536#include <asm/irq_regs.h>3637···12871286{12881287 int ctxn;1289128812901290- perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);12911291-12921289 for_each_task_context_nr(ctxn)12931290 perf_event_context_sched_out(task, ctxn, next);12941291}···16201621{16211622 raw_spin_lock(&ctx->lock);1622162316231623- /* Rotate the first entry last of non-pinned groups */16241624- list_rotate_left(&ctx->flexible_groups);16241624+ /*16251625+ * Rotate the first entry last of non-pinned groups. Rotation might be16261626+ * disabled by the inheritance code.16271627+ */16281628+ if (!ctx->rotate_disable)16291629+ list_rotate_left(&ctx->flexible_groups);1625163016261631 raw_spin_unlock(&ctx->lock);16271632}···22372234 raw_spin_unlock_irq(&ctx->lock);22382235 mutex_unlock(&ctx->mutex);2239223622402240- mutex_lock(&event->owner->perf_event_mutex);22412241- list_del_init(&event->owner_entry);22422242- mutex_unlock(&event->owner->perf_event_mutex);22432243- put_task_struct(event->owner);22442244-22452237 free_event(event);2246223822472239 return 0;···22492251static int perf_release(struct inode *inode, struct file *file)22502252{22512253 struct perf_event *event = file->private_data;22542254+ struct task_struct *owner;2252225522532256 file->private_data = NULL;22572257+22582258+ rcu_read_lock();22592259+ owner = ACCESS_ONCE(event->owner);22602260+ /*22612261+ * Matches the smp_wmb() in perf_event_exit_task(). If we observe22622262+ * !owner it means the list deletion is complete and we can indeed22632263+ * free this event, otherwise we need to serialize on22642264+ * owner->perf_event_mutex.22652265+ */22662266+ smp_read_barrier_depends();22672267+ if (owner) {22682268+ /*22692269+ * Since delayed_put_task_struct() also drops the last22702270+ * task reference we can safely take a new reference22712271+ * while holding the rcu_read_lock().22722272+ */22732273+ get_task_struct(owner);22742274+ }22752275+ rcu_read_unlock();22762276+22772277+ if (owner) {22782278+ mutex_lock(&owner->perf_event_mutex);22792279+ /*22802280+ * We have to re-check the event->owner field, if it is cleared22812281+ * we raced with perf_event_exit_task(), acquiring the mutex22822282+ * ensured they're done, and we can proceed with freeing the22832283+ * event.22842284+ */22852285+ if (event->owner)22862286+ list_del_init(&event->owner_entry);22872287+ mutex_unlock(&owner->perf_event_mutex);22882288+ put_task_struct(owner);22892289+ }2254229022552291 return perf_event_release_kernel(event);22562292}···57005668 mutex_unlock(&ctx->mutex);5701566957025670 event->owner = current;57035703- get_task_struct(current);56715671+57045672 mutex_lock(¤t->perf_event_mutex);57055673 list_add_tail(&event->owner_entry, ¤t->perf_event_list);57065674 mutex_unlock(¤t->perf_event_mutex);···57675735 perf_install_in_context(ctx, event, cpu);57685736 ++ctx->generation;57695737 mutex_unlock(&ctx->mutex);57705770-57715771- event->owner = current;57725772- get_task_struct(current);57735773- mutex_lock(¤t->perf_event_mutex);57745774- list_add_tail(&event->owner_entry, ¤t->perf_event_list);57755775- mutex_unlock(¤t->perf_event_mutex);5776573857775739 return event;57785740···59185892 */59195893void perf_event_exit_task(struct task_struct *child)59205894{58955895+ struct perf_event *event, *tmp;59215896 int ctxn;58975897+58985898+ mutex_lock(&child->perf_event_mutex);58995899+ list_for_each_entry_safe(event, tmp, &child->perf_event_list,59005900+ owner_entry) {59015901+ list_del_init(&event->owner_entry);59025902+59035903+ /*59045904+ * Ensure the list deletion is visible before we clear59055905+ * the owner, closes a race against perf_release() where59065906+ * we need to serialize on the owner->perf_event_mutex.59075907+ */59085908+ smp_wmb();59095909+ event->owner = NULL;59105910+ }59115911+ mutex_unlock(&child->perf_event_mutex);5922591259235913 for_each_task_context_nr(ctxn)59245914 perf_event_exit_task_context(child, ctxn);···61556113 struct perf_event *event;61566114 struct task_struct *parent = current;61576115 int inherited_all = 1;61166116+ unsigned long flags;61586117 int ret = 0;6159611861606119 child->perf_event_ctxp[ctxn] = NULL;···61966153 break;61976154 }6198615561566156+ /*61576157+ * We can't hold ctx->lock when iterating the ->flexible_group list due61586158+ * to allocations, but we need to prevent rotation because61596159+ * rotate_ctx() will change the list from interrupt context.61606160+ */61616161+ raw_spin_lock_irqsave(&parent_ctx->lock, flags);61626162+ parent_ctx->rotate_disable = 1;61636163+ raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);61646164+61996165 list_for_each_entry(event, &parent_ctx->flexible_groups, group_entry) {62006166 ret = inherit_task_group(event, parent, parent_ctx,62016167 child, ctxn, &inherited_all);62026168 if (ret)62036169 break;62046170 }61716171+61726172+ raw_spin_lock_irqsave(&parent_ctx->lock, flags);61736173+ parent_ctx->rotate_disable = 0;61746174+ raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);6205617562066176 child_ctx = child->perf_event_ctxp[ctxn];62076177···6368631263696313void __init perf_event_init(void)63706314{63156315+ int ret;63166316+63716317 perf_event_init_all_cpus();63726318 init_srcu_struct(&pmus_srcu);63736319 perf_pmu_register(&perf_swevent);···63776319 perf_pmu_register(&perf_task_clock);63786320 perf_tp_register();63796321 perf_cpu_notifier(perf_cpu_notify);63226322+63236323+ ret = init_hw_breakpoint();63246324+ WARN(ret, "hw_breakpoint initialization failed with: %d", ret);63806325}
+9-8
tools/perf/builtin-record.c
···697697 if (err < 0)698698 err = event__synthesize_kernel_mmap(process_synthesized_event,699699 session, machine, "_stext");700700- if (err < 0) {701701- pr_err("Couldn't record kernel reference relocation symbol.\n");702702- return err;703703- }700700+ if (err < 0)701701+ pr_err("Couldn't record kernel reference relocation symbol\n"702702+ "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"703703+ "Check /proc/kallsyms permission or run as root.\n");704704705705 err = event__synthesize_modules(process_synthesized_event,706706 session, machine);707707- if (err < 0) {708708- pr_err("Couldn't record kernel reference relocation symbol.\n");709709- return err;710710- }707707+ if (err < 0)708708+ pr_err("Couldn't record kernel module information.\n"709709+ "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"710710+ "Check /proc/modules permission or run as root.\n");711711+711712 if (perf_guest)712713 perf_session__process_machines(session, event__synthesize_guest_os);713714