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.

perf: Split out the AUX buffer allocation

Move the AUX buffer allocation branch into its own function.

Originally-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Link: https://lore.kernel.org/r/20250812104019.494205648@infradead.org

+77 -67
+77 -67
kernel/events/core.c
··· 6970 6970 atomic64_add(extra, &vma->vm_mm->pinned_vm); 6971 6971 } 6972 6972 6973 + static int perf_mmap_aux(struct vm_area_struct *vma, struct perf_event *event, 6974 + unsigned long nr_pages) 6975 + { 6976 + long extra = 0, user_extra = nr_pages; 6977 + u64 aux_offset, aux_size; 6978 + struct perf_buffer *rb; 6979 + int ret, rb_flags = 0; 6980 + 6981 + rb = event->rb; 6982 + if (!rb) 6983 + return -EINVAL; 6984 + 6985 + guard(mutex)(&rb->aux_mutex); 6986 + 6987 + /* 6988 + * AUX area mapping: if rb->aux_nr_pages != 0, it's already 6989 + * mapped, all subsequent mappings should have the same size 6990 + * and offset. Must be above the normal perf buffer. 6991 + */ 6992 + aux_offset = READ_ONCE(rb->user_page->aux_offset); 6993 + aux_size = READ_ONCE(rb->user_page->aux_size); 6994 + 6995 + if (aux_offset < perf_data_size(rb) + PAGE_SIZE) 6996 + return -EINVAL; 6997 + 6998 + if (aux_offset != vma->vm_pgoff << PAGE_SHIFT) 6999 + return -EINVAL; 7000 + 7001 + /* already mapped with a different offset */ 7002 + if (rb_has_aux(rb) && rb->aux_pgoff != vma->vm_pgoff) 7003 + return -EINVAL; 7004 + 7005 + if (aux_size != nr_pages * PAGE_SIZE) 7006 + return -EINVAL; 7007 + 7008 + /* already mapped with a different size */ 7009 + if (rb_has_aux(rb) && rb->aux_nr_pages != nr_pages) 7010 + return -EINVAL; 7011 + 7012 + if (!is_power_of_2(nr_pages)) 7013 + return -EINVAL; 7014 + 7015 + if (!atomic_inc_not_zero(&rb->mmap_count)) 7016 + return -EINVAL; 7017 + 7018 + if (rb_has_aux(rb)) { 7019 + atomic_inc(&rb->aux_mmap_count); 7020 + 7021 + } else { 7022 + if (!perf_mmap_calc_limits(vma, &user_extra, &extra)) { 7023 + atomic_dec(&rb->mmap_count); 7024 + return -EPERM; 7025 + } 7026 + 7027 + WARN_ON(!rb && event->rb); 7028 + 7029 + if (vma->vm_flags & VM_WRITE) 7030 + rb_flags |= RING_BUFFER_WRITABLE; 7031 + 7032 + ret = rb_alloc_aux(rb, event, vma->vm_pgoff, nr_pages, 7033 + event->attr.aux_watermark, rb_flags); 7034 + if (ret) { 7035 + atomic_dec(&rb->mmap_count); 7036 + return ret; 7037 + } 7038 + 7039 + atomic_set(&rb->aux_mmap_count, 1); 7040 + rb->aux_mmap_locked = extra; 7041 + } 7042 + 7043 + perf_mmap_account(vma, user_extra, extra); 7044 + atomic_inc(&event->mmap_count); 7045 + 7046 + return 0; 7047 + } 7048 + 6973 7049 static int perf_mmap(struct file *file, struct vm_area_struct *vma) 6974 7050 { 6975 7051 struct perf_event *event = file->private_data; ··· 7164 7088 perf_mmap_account(vma, user_extra, extra); 7165 7089 atomic_inc(&event->mmap_count); 7166 7090 } else { 7167 - /* 7168 - * AUX area mapping: if rb->aux_nr_pages != 0, it's already 7169 - * mapped, all subsequent mappings should have the same size 7170 - * and offset. Must be above the normal perf buffer. 7171 - */ 7172 - u64 aux_offset, aux_size; 7173 - 7174 - rb = event->rb; 7175 - if (!rb) 7176 - goto unlock; 7177 - 7178 - guard(mutex)(&rb->aux_mutex); 7179 - 7180 - aux_offset = READ_ONCE(rb->user_page->aux_offset); 7181 - aux_size = READ_ONCE(rb->user_page->aux_size); 7182 - 7183 - if (aux_offset < perf_data_size(rb) + PAGE_SIZE) 7184 - goto unlock; 7185 - 7186 - if (aux_offset != vma->vm_pgoff << PAGE_SHIFT) 7187 - goto unlock; 7188 - 7189 - /* already mapped with a different offset */ 7190 - if (rb_has_aux(rb) && rb->aux_pgoff != vma->vm_pgoff) 7191 - goto unlock; 7192 - 7193 - if (aux_size != nr_pages * PAGE_SIZE) 7194 - goto unlock; 7195 - 7196 - /* already mapped with a different size */ 7197 - if (rb_has_aux(rb) && rb->aux_nr_pages != nr_pages) 7198 - goto unlock; 7199 - 7200 - if (!is_power_of_2(nr_pages)) 7201 - goto unlock; 7202 - 7203 - if (!atomic_inc_not_zero(&rb->mmap_count)) 7204 - goto unlock; 7205 - 7206 - if (rb_has_aux(rb)) { 7207 - atomic_inc(&rb->aux_mmap_count); 7208 - ret = 0; 7209 - 7210 - } else { 7211 - if (!perf_mmap_calc_limits(vma, &user_extra, &extra)) { 7212 - ret = -EPERM; 7213 - atomic_dec(&rb->mmap_count); 7214 - goto unlock; 7215 - } 7216 - 7217 - WARN_ON(!rb && event->rb); 7218 - 7219 - if (vma->vm_flags & VM_WRITE) 7220 - flags |= RING_BUFFER_WRITABLE; 7221 - 7222 - ret = rb_alloc_aux(rb, event, vma->vm_pgoff, nr_pages, 7223 - event->attr.aux_watermark, flags); 7224 - if (ret) { 7225 - atomic_dec(&rb->mmap_count); 7226 - goto unlock; 7227 - } 7228 - 7229 - atomic_set(&rb->aux_mmap_count, 1); 7230 - rb->aux_mmap_locked = extra; 7231 - } 7232 - perf_mmap_account(vma, user_extra, extra); 7233 - atomic_inc(&event->mmap_count); 7091 + ret = perf_mmap_aux(vma, event, nr_pages); 7234 7092 } 7235 7093 7236 7094 unlock: