On Mon, Mar 12, 2018 at 01:39:56PM -0700, Song Liu wrote: > +static void stack_map_get_build_id_offset(struct bpf_map *map, > + struct stack_map_bucket *bucket, > + u64 *ips, u32 trace_nr) > +{ > + int i; > + struct vm_area_struct *vma; > + struct bpf_stack_build_id *id_offs; > + > + bucket->nr = trace_nr; > + id_offs = (struct bpf_stack_build_id *)bucket->data; > + > + if (!current || !current->mm || > + down_read_trylock(¤t->mm->mmap_sem) == 0) {
You probably want an in_nmi() before the down_read_trylock(). Doing up_read() is an absolute no-no from NMI context. And IIUC its 'trivial' to use this stuff with hardware counters. > + /* cannot access current->mm, fall back to ips */ > + for (i = 0; i < trace_nr; i++) { > + id_offs[i].status = BPF_STACK_BUILD_ID_IP; > + id_offs[i].ip = ips[i]; > + } > + return; > + } > + > + for (i = 0; i < trace_nr; i++) { > + vma = find_vma(current->mm, ips[i]); > + if (!vma || stack_map_get_build_id(vma, id_offs[i].build_id)) { > + /* per entry fall back to ips */ > + id_offs[i].status = BPF_STACK_BUILD_ID_IP; > + id_offs[i].ip = ips[i]; > + continue; > + } > + id_offs[i].offset = (vma->vm_pgoff << PAGE_SHIFT) + ips[i] > + - vma->vm_start; > + id_offs[i].status = BPF_STACK_BUILD_ID_VALID; > + } > + up_read(¤t->mm->mmap_sem); > +}