Hi Deepanshu,

kernel test robot noticed the following build errors:

[auto build test ERROR on perf-tools-next/perf-tools-next]
[also build test ERROR on tip/perf/core perf-tools/perf-tools linus/master v7.2 
next-20260821]
[cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    
https://github.com/intel-lab-lkp/linux/commits/Deepanshu-Kartikey/perf-bpf-Fix-lockless-access-to-parent_event-prog-in-perf_event_alloc/20260821-071210
base:   
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git 
perf-tools-next
patch link:    
https://lore.kernel.org/r/20260821014210.18681-1-kartikey406%40gmail.com
patch subject: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in 
perf_event_alloc()
config: sparc-randconfig-002-20260825 
(https://download.01.org/0day-ci/archive/20260825/[email protected]/config)
compiler: sparc64-linux-gcc (GCC) 12.5.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20260825/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: 
https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

   sparc64-linux-ld: kernel/events/core.o: in function `perf_event_alloc':
>> kernel/events/core.c:13438:(.text+0x9be0): undefined reference to 
>> `bpf_event_mutex'
>> sparc64-linux-ld: kernel/events/core.c:13438:(.text+0x9bec): undefined 
>> reference to `bpf_event_mutex'
   sparc64-linux-ld: kernel/events/core.c:13444:(.text+0x9c14): undefined 
reference to `bpf_event_mutex'


vim +13438 kernel/events/core.c

 13340  
 13341  /*
 13342   * Allocate and initialize an event structure
 13343   */
 13344  static struct perf_event *
 13345  perf_event_alloc(struct perf_event_attr *attr, int cpu,
 13346                   struct task_struct *task,
 13347                   struct perf_event *group_leader,
 13348                   struct perf_event *parent_event,
 13349                   perf_overflow_handler_t overflow_handler,
 13350                   void *context, int cgroup_fd)
 13351  {
 13352          struct pmu *pmu;
 13353          struct hw_perf_event *hwc;
 13354          long err = -EINVAL;
 13355          int node;
 13356  
 13357          if ((unsigned)cpu >= nr_cpu_ids) {
 13358                  if (!task || cpu != -1)
 13359                          return ERR_PTR(-EINVAL);
 13360          }
 13361          if (attr->sigtrap && !task) {
 13362                  /* Requires a task: avoid signalling random tasks. */
 13363                  return ERR_PTR(-EINVAL);
 13364          }
 13365  
 13366          node = (cpu >= 0) ? cpu_to_node(cpu) : -1;
 13367          struct perf_event *event __free(__free_event) =
 13368                  kmem_cache_alloc_node(perf_event_cache, GFP_KERNEL | 
__GFP_ZERO, node);
 13369          if (!event)
 13370                  return ERR_PTR(-ENOMEM);
 13371  
 13372          /*
 13373           * Single events are their own group leaders, with an
 13374           * empty sibling list:
 13375           */
 13376          if (!group_leader)
 13377                  group_leader = event;
 13378  
 13379          mutex_init(&event->child_mutex);
 13380          INIT_LIST_HEAD(&event->child_list);
 13381  
 13382          INIT_LIST_HEAD(&event->event_entry);
 13383          INIT_LIST_HEAD(&event->sibling_list);
 13384          INIT_LIST_HEAD(&event->active_list);
 13385          init_event_group(event);
 13386          INIT_LIST_HEAD(&event->rb_entry);
 13387          INIT_LIST_HEAD(&event->active_entry);
 13388          INIT_LIST_HEAD(&event->addr_filters.list);
 13389          INIT_HLIST_NODE(&event->hlist_entry);
 13390          INIT_LIST_HEAD(&event->pmu_list);
 13391  
 13392  
 13393          init_waitqueue_head(&event->waitq);
 13394          init_irq_work(&event->pending_irq, perf_pending_irq);
 13395          event->pending_disable_irq = 
IRQ_WORK_INIT_HARD(perf_pending_disable);
 13396          init_task_work(&event->pending_task, perf_pending_task);
 13397  
 13398          mutex_init(&event->mmap_mutex);
 13399          raw_spin_lock_init(&event->addr_filters.lock);
 13400  
 13401          atomic_long_set(&event->refcount, 1);
 13402          event->cpu              = cpu;
 13403          event->attr             = *attr;
 13404          event->group_leader     = group_leader;
 13405          event->pmu              = NULL;
 13406          event->oncpu            = -1;
 13407  
 13408          event->parent           = parent_event;
 13409  
 13410          event->ns               = 
get_pid_ns(task_active_pid_ns(current));
 13411          event->id               = atomic64_inc_return(&perf_event_id);
 13412  
 13413          event->state            = PERF_EVENT_STATE_INACTIVE;
 13414  
 13415          if (parent_event)
 13416                  event->event_caps = parent_event->event_caps;
 13417  
 13418          if (task) {
 13419                  event->attach_state = PERF_ATTACH_TASK;
 13420                  /*
 13421                   * XXX pmu::event_init needs to know what task to 
account to
 13422                   * and we cannot use the ctx information because we 
need the
 13423                   * pmu before we get a ctx.
 13424                   */
 13425                  event->hw.target = get_task_struct(task);
 13426          }
 13427  
 13428          event->clock = &local_clock;
 13429          if (parent_event)
 13430                  event->clock = parent_event->clock;
 13431  
 13432          if (!overflow_handler && parent_event) {
 13433                  overflow_handler = parent_event->overflow_handler;
 13434                  context = parent_event->overflow_handler_context;
 13435  #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_EVENT_TRACING)
 13436                  struct bpf_prog *prog;
 13437  
 13438                  mutex_lock(&bpf_event_mutex);
 13439                  prog = parent_event->prog;
 13440                  if (prog) {
 13441                          bpf_prog_inc(prog);
 13442                          event->prog = prog;
 13443                  }
 13444                  mutex_unlock(&bpf_event_mutex);
 13445  #endif
 13446          }
 13447  
 13448          if (overflow_handler) {
 13449                  event->overflow_handler = overflow_handler;
 13450                  event->overflow_handler_context = context;
 13451          } else if (is_write_backward(event)){
 13452                  event->overflow_handler = perf_event_output_backward;
 13453                  event->overflow_handler_context = NULL;
 13454          } else {
 13455                  event->overflow_handler = perf_event_output_forward;
 13456                  event->overflow_handler_context = NULL;
 13457          }
 13458  
 13459          perf_event__state_init(event);
 13460  
 13461          pmu = NULL;
 13462  
 13463          hwc = &event->hw;
 13464          hwc->sample_period = attr->sample_period;
 13465          if (is_event_in_freq_mode(event))
 13466                  hwc->sample_period = 1;
 13467          hwc->last_period = hwc->sample_period;
 13468  
 13469          local64_set(&hwc->period_left, hwc->sample_period);
 13470  
 13471          /*
 13472           * We do not support PERF_SAMPLE_READ on inherited events unless
 13473           * PERF_SAMPLE_TID is also selected, which allows inherited 
events to
 13474           * collect per-thread samples.
 13475           * See perf_output_read().
 13476           */
 13477          if (has_inherit_and_sample_read(attr) && !(attr->sample_type & 
PERF_SAMPLE_TID))
 13478                  return ERR_PTR(-EINVAL);
 13479  
 13480          if (!has_branch_stack(event))
 13481                  event->attr.branch_sample_type = 0;
 13482  
 13483          pmu = perf_init_event(event);
 13484          if (IS_ERR(pmu))
 13485                  return (void*)pmu;
 13486  
 13487          /*
 13488           * The PERF_ATTACH_TASK_DATA is set in the 
event_init()->hw_config().
 13489           * The attach should be right after the perf_init_event().
 13490           * Otherwise, the __free_event() would mistakenly detach the 
non-exist
 13491           * perf_ctx_data because of the other errors between them.
 13492           */
 13493          if (event->attach_state & PERF_ATTACH_TASK_DATA) {
 13494                  err = attach_perf_ctx_data(event);
 13495                  if (err)
 13496                          return ERR_PTR(err);
 13497          }
 13498  
 13499          /*
 13500           * Disallow uncore-task events. Similarly, disallow 
uncore-cgroup
 13501           * events (they don't make sense as the cgroup will be different
 13502           * on other CPUs in the uncore mask).
 13503           */
 13504          if (pmu->task_ctx_nr == perf_invalid_context && (task || 
cgroup_fd != -1))
 13505                  return ERR_PTR(-EINVAL);
 13506  
 13507          if (event->attr.aux_output &&
 13508              (!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT) ||
 13509               event->attr.aux_pause || event->attr.aux_resume))
 13510                  return ERR_PTR(-EOPNOTSUPP);
 13511  
 13512          if (event->attr.aux_pause && event->attr.aux_resume)
 13513                  return ERR_PTR(-EINVAL);
 13514  
 13515          if (event->attr.aux_start_paused) {
 13516                  if (!(pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE))
 13517                          return ERR_PTR(-EOPNOTSUPP);
 13518                  event->hw.aux_paused = 1;
 13519          }
 13520  
 13521          if (cgroup_fd != -1) {
 13522                  err = perf_cgroup_connect(cgroup_fd, event, attr, 
group_leader);
 13523                  if (err)
 13524                          return ERR_PTR(err);
 13525          }
 13526  
 13527          err = exclusive_event_init(event);
 13528          if (err)
 13529                  return ERR_PTR(err);
 13530  
 13531          if (has_addr_filter(event)) {
 13532                  event->addr_filter_ranges = 
kcalloc(pmu->nr_addr_filters,
 13533                                                      sizeof(struct 
perf_addr_filter_range),
 13534                                                      GFP_KERNEL);
 13535                  if (!event->addr_filter_ranges)
 13536                          return ERR_PTR(-ENOMEM);
 13537  
 13538                  /*
 13539                   * Clone the parent's vma offsets: they are valid until 
exec()
 13540                   * even if the mm is not shared with the parent.
 13541                   */
 13542                  if (event->parent) {
 13543                          struct perf_addr_filters_head *ifh = 
perf_event_addr_filters(event);
 13544  
 13545                          raw_spin_lock_irq(&ifh->lock);
 13546                          memcpy(event->addr_filter_ranges,
 13547                                 event->parent->addr_filter_ranges,
 13548                                 pmu->nr_addr_filters * sizeof(struct 
perf_addr_filter_range));
 13549                          raw_spin_unlock_irq(&ifh->lock);
 13550                  }
 13551  
 13552                  /* force hw sync on the address filters */
 13553                  event->addr_filters_gen = 1;
 13554          }
 13555  
 13556          if (!event->parent) {
 13557                  if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
 13558                          err = 
get_callchain_buffers(attr->sample_max_stack);
 13559                          if (err)
 13560                                  return ERR_PTR(err);
 13561                          event->attach_state |= PERF_ATTACH_CALLCHAIN;
 13562                  }
 13563          }
 13564  
 13565          err = security_perf_event_alloc(event);
 13566          if (err)
 13567                  return ERR_PTR(err);
 13568  
 13569          err = mediated_pmu_account_event(event);
 13570          if (err)
 13571                  return ERR_PTR(err);
 13572  
 13573          /* symmetric to unaccount_event() in _free_event() */
 13574          account_event(event);
 13575  
 13576          /*
 13577           * Event creation should be under SRCU, see 
perf_pmu_unregister().
 13578           */
 13579          lockdep_assert_held(&pmus_srcu);
 13580          scoped_guard (spinlock, &pmu->events_lock)
 13581                  list_add(&event->pmu_list, &pmu->events);
 13582  
 13583          return_ptr(event);
 13584  }
 13585  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

Reply via email to