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 RB allocation

Move the RB 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.722214699@infradead.org

+73 -72
+73 -72
kernel/events/core.c
··· 6970 6970 atomic64_add(extra, &vma->vm_mm->pinned_vm); 6971 6971 } 6972 6972 6973 + static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event, 6974 + unsigned long nr_pages) 6975 + { 6976 + long extra = 0, user_extra = nr_pages; 6977 + struct perf_buffer *rb; 6978 + int rb_flags = 0; 6979 + 6980 + nr_pages -= 1; 6981 + 6982 + /* 6983 + * If we have rb pages ensure they're a power-of-two number, so we 6984 + * can do bitmasks instead of modulo. 6985 + */ 6986 + if (nr_pages != 0 && !is_power_of_2(nr_pages)) 6987 + return -EINVAL; 6988 + 6989 + WARN_ON_ONCE(event->ctx->parent_ctx); 6990 + 6991 + if (event->rb) { 6992 + if (data_page_nr(event->rb) != nr_pages) 6993 + return -EINVAL; 6994 + 6995 + if (atomic_inc_not_zero(&event->rb->mmap_count)) { 6996 + /* 6997 + * Success -- managed to mmap() the same buffer 6998 + * multiple times. 6999 + */ 7000 + perf_mmap_account(vma, user_extra, extra); 7001 + atomic_inc(&event->mmap_count); 7002 + return 0; 7003 + } 7004 + 7005 + /* 7006 + * Raced against perf_mmap_close()'s 7007 + * atomic_dec_and_mutex_lock() remove the 7008 + * event and continue as if !event->rb 7009 + */ 7010 + ring_buffer_attach(event, NULL); 7011 + } 7012 + 7013 + if (!perf_mmap_calc_limits(vma, &user_extra, &extra)) 7014 + return -EPERM; 7015 + 7016 + if (vma->vm_flags & VM_WRITE) 7017 + rb_flags |= RING_BUFFER_WRITABLE; 7018 + 7019 + rb = rb_alloc(nr_pages, 7020 + event->attr.watermark ? event->attr.wakeup_watermark : 0, 7021 + event->cpu, rb_flags); 7022 + 7023 + if (!rb) 7024 + return -ENOMEM; 7025 + 7026 + atomic_set(&rb->mmap_count, 1); 7027 + rb->mmap_user = get_current_user(); 7028 + rb->mmap_locked = extra; 7029 + 7030 + ring_buffer_attach(event, rb); 7031 + 7032 + perf_event_update_time(event); 7033 + perf_event_init_userpage(event); 7034 + perf_event_update_userpage(event); 7035 + 7036 + perf_mmap_account(vma, user_extra, extra); 7037 + atomic_inc(&event->mmap_count); 7038 + 7039 + return 0; 7040 + } 7041 + 6973 7042 static int perf_mmap_aux(struct vm_area_struct *vma, struct perf_event *event, 6974 7043 unsigned long nr_pages) 6975 7044 { ··· 7119 7050 { 7120 7051 struct perf_event *event = file->private_data; 7121 7052 unsigned long vma_size, nr_pages; 7122 - long user_extra = 0, extra = 0; 7123 - struct perf_buffer *rb = NULL; 7124 - int ret, flags = 0; 7125 7053 mapped_f mapped; 7054 + int ret; 7126 7055 7127 7056 /* 7128 7057 * Don't allow mmap() of inherited per-task counters. This would ··· 7146 7079 if (vma_size != PAGE_SIZE * nr_pages) 7147 7080 return -EINVAL; 7148 7081 7149 - user_extra = nr_pages; 7150 - 7151 7082 mutex_lock(&event->mmap_mutex); 7152 7083 ret = -EINVAL; 7153 7084 ··· 7159 7094 goto unlock; 7160 7095 } 7161 7096 7162 - if (vma->vm_pgoff == 0) { 7163 - nr_pages -= 1; 7164 - 7165 - /* 7166 - * If we have rb pages ensure they're a power-of-two number, so we 7167 - * can do bitmasks instead of modulo. 7168 - */ 7169 - if (nr_pages != 0 && !is_power_of_2(nr_pages)) 7170 - goto unlock; 7171 - 7172 - WARN_ON_ONCE(event->ctx->parent_ctx); 7173 - 7174 - if (event->rb) { 7175 - if (data_page_nr(event->rb) != nr_pages) 7176 - goto unlock; 7177 - 7178 - if (atomic_inc_not_zero(&event->rb->mmap_count)) { 7179 - /* 7180 - * Success -- managed to mmap() the same buffer 7181 - * multiple times. 7182 - */ 7183 - ret = 0; 7184 - perf_mmap_account(vma, user_extra, extra); 7185 - atomic_inc(&event->mmap_count); 7186 - goto unlock; 7187 - } 7188 - 7189 - /* 7190 - * Raced against perf_mmap_close()'s 7191 - * atomic_dec_and_mutex_lock() remove the 7192 - * event and continue as if !event->rb 7193 - */ 7194 - ring_buffer_attach(event, NULL); 7195 - } 7196 - 7197 - if (!perf_mmap_calc_limits(vma, &user_extra, &extra)) { 7198 - ret = -EPERM; 7199 - goto unlock; 7200 - } 7201 - 7202 - if (vma->vm_flags & VM_WRITE) 7203 - flags |= RING_BUFFER_WRITABLE; 7204 - 7205 - rb = rb_alloc(nr_pages, 7206 - event->attr.watermark ? event->attr.wakeup_watermark : 0, 7207 - event->cpu, flags); 7208 - 7209 - if (!rb) { 7210 - ret = -ENOMEM; 7211 - goto unlock; 7212 - } 7213 - 7214 - atomic_set(&rb->mmap_count, 1); 7215 - rb->mmap_user = get_current_user(); 7216 - rb->mmap_locked = extra; 7217 - 7218 - ring_buffer_attach(event, rb); 7219 - 7220 - perf_event_update_time(event); 7221 - perf_event_init_userpage(event); 7222 - perf_event_update_userpage(event); 7223 - ret = 0; 7224 - 7225 - perf_mmap_account(vma, user_extra, extra); 7226 - atomic_inc(&event->mmap_count); 7227 - } else { 7097 + if (vma->vm_pgoff == 0) 7098 + ret = perf_mmap_rb(vma, event, nr_pages); 7099 + else 7228 7100 ret = perf_mmap_aux(vma, event, nr_pages); 7229 - } 7230 7101 7231 7102 unlock: 7232 7103 mutex_unlock(&event->mmap_mutex);