Re: [PATCH 05/12] uprobes: move offset and ref_ctr_offset into uprobe_consumer
On Mon, 24 Jun 2024 17:21:37 -0700 Andrii Nakryiko wrote: > Simplify uprobe registration/unregistration interfaces by making offset > and ref_ctr_offset part of uprobe_consumer "interface". In practice, all > existing users already store these fields somewhere in uprobe_consumer's > containing structure, so this doesn't pose any problem. We just move > some fields around. > > On the other hand, this simplifies uprobe_register() and > uprobe_unregister() API by having only struct uprobe_consumer as one > thing representing attachment/detachment entity. This makes batched > versions of uprobe_register() and uprobe_unregister() simpler. > > This also makes uprobe_register_refctr() unnecessary, so remove it and > simplify consumers. > > No functional changes intended. > Looks good to me. Acked-by: Masami Hiramatsu (Google) Thanks! > Signed-off-by: Andrii Nakryiko > --- > include/linux/uprobes.h | 18 +++ > kernel/events/uprobes.c | 19 ++- > kernel/trace/bpf_trace.c | 21 +++- > kernel/trace/trace_uprobe.c | 53 --- > .../selftests/bpf/bpf_testmod/bpf_testmod.c | 23 > 5 files changed, 55 insertions(+), 79 deletions(-) > > diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h > index b503fafb7fb3..a75ba37ce3c8 100644 > --- a/include/linux/uprobes.h > +++ b/include/linux/uprobes.h > @@ -42,6 +42,11 @@ struct uprobe_consumer { > enum uprobe_filter_ctx ctx, > struct mm_struct *mm); > > + /* associated file offset of this probe */ > + loff_t offset; > + /* associated refctr file offset of this probe, or zero */ > + loff_t ref_ctr_offset; > + /* for internal uprobe infra use, consumers shouldn't touch fields > below */ > struct uprobe_consumer *next; > }; > > @@ -110,10 +115,9 @@ extern bool is_trap_insn(uprobe_opcode_t *insn); > extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); > extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); > extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct > *mm, unsigned long vaddr, uprobe_opcode_t); > -extern int uprobe_register(struct inode *inode, loff_t offset, struct > uprobe_consumer *uc); > -extern int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t > ref_ctr_offset, struct uprobe_consumer *uc); > +extern int uprobe_register(struct inode *inode, struct uprobe_consumer *uc); > extern int uprobe_apply(struct inode *inode, loff_t offset, struct > uprobe_consumer *uc, bool); > -extern void uprobe_unregister(struct inode *inode, loff_t offset, struct > uprobe_consumer *uc); > +extern void uprobe_unregister(struct inode *inode, struct uprobe_consumer > *uc); > extern int uprobe_mmap(struct vm_area_struct *vma); > extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, > unsigned long end); > extern void uprobe_start_dup_mmap(void); > @@ -152,11 +156,7 @@ static inline void uprobes_init(void) > #define uprobe_get_trap_addr(regs) instruction_pointer(regs) > > static inline int > -uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer > *uc) > -{ > - return -ENOSYS; > -} > -static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, > loff_t ref_ctr_offset, struct uprobe_consumer *uc) > +uprobe_register(struct inode *inode, struct uprobe_consumer *uc) > { > return -ENOSYS; > } > @@ -166,7 +166,7 @@ uprobe_apply(struct inode *inode, loff_t offset, struct > uprobe_consumer *uc, boo > return -ENOSYS; > } > static inline void > -uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer > *uc) > +uprobe_unregister(struct inode *inode, struct uprobe_consumer *uc) > { > } > static inline int uprobe_mmap(struct vm_area_struct *vma) > diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c > index 8ce669bc6474..2544e8b79bad 100644 > --- a/kernel/events/uprobes.c > +++ b/kernel/events/uprobes.c > @@ -1197,14 +1197,13 @@ __uprobe_unregister(struct uprobe *uprobe, struct > uprobe_consumer *uc) > /* > * uprobe_unregister - unregister an already registered probe. > * @inode: the file in which the probe has to be removed. > - * @offset: offset from the start of the file. > - * @uc: identify which probe if multiple probes are colocated. > + * @uc: identify which probe consumer to unregister. > */ > -void uprobe_unregister(struct inode *inode, loff_t offset, struct > uprobe_consumer *uc) > +void uprobe_unregister(struct inode *inode, struct uprobe_consumer *uc) > { > struct uprobe *uprobe; > > - uprobe = find_uprobe(inode, offset); > + uprobe = find_uprobe(inode, uc->offset); > if (WARN_ON(!uprobe)) > return; > > @@ -1277,20 +1276,12 @@ static int __uprobe_register(struct inode *inode, > loff_t offset, > return ret; > }
[PATCH 05/12] uprobes: move offset and ref_ctr_offset into uprobe_consumer
Simplify uprobe registration/unregistration interfaces by making offset and ref_ctr_offset part of uprobe_consumer "interface". In practice, all existing users already store these fields somewhere in uprobe_consumer's containing structure, so this doesn't pose any problem. We just move some fields around. On the other hand, this simplifies uprobe_register() and uprobe_unregister() API by having only struct uprobe_consumer as one thing representing attachment/detachment entity. This makes batched versions of uprobe_register() and uprobe_unregister() simpler. This also makes uprobe_register_refctr() unnecessary, so remove it and simplify consumers. No functional changes intended. Signed-off-by: Andrii Nakryiko --- include/linux/uprobes.h | 18 +++ kernel/events/uprobes.c | 19 ++- kernel/trace/bpf_trace.c | 21 +++- kernel/trace/trace_uprobe.c | 53 --- .../selftests/bpf/bpf_testmod/bpf_testmod.c | 23 5 files changed, 55 insertions(+), 79 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index b503fafb7fb3..a75ba37ce3c8 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -42,6 +42,11 @@ struct uprobe_consumer { enum uprobe_filter_ctx ctx, struct mm_struct *mm); + /* associated file offset of this probe */ + loff_t offset; + /* associated refctr file offset of this probe, or zero */ + loff_t ref_ctr_offset; + /* for internal uprobe infra use, consumers shouldn't touch fields below */ struct uprobe_consumer *next; }; @@ -110,10 +115,9 @@ extern bool is_trap_insn(uprobe_opcode_t *insn); extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); -extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); -extern int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc); +extern int uprobe_register(struct inode *inode, struct uprobe_consumer *uc); extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); -extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); +extern void uprobe_unregister(struct inode *inode, struct uprobe_consumer *uc); extern int uprobe_mmap(struct vm_area_struct *vma); extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void uprobe_start_dup_mmap(void); @@ -152,11 +156,7 @@ static inline void uprobes_init(void) #define uprobe_get_trap_addr(regs) instruction_pointer(regs) static inline int -uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) -{ - return -ENOSYS; -} -static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc) +uprobe_register(struct inode *inode, struct uprobe_consumer *uc) { return -ENOSYS; } @@ -166,7 +166,7 @@ uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, boo return -ENOSYS; } static inline void -uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) +uprobe_unregister(struct inode *inode, struct uprobe_consumer *uc) { } static inline int uprobe_mmap(struct vm_area_struct *vma) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 8ce669bc6474..2544e8b79bad 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1197,14 +1197,13 @@ __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc) /* * uprobe_unregister - unregister an already registered probe. * @inode: the file in which the probe has to be removed. - * @offset: offset from the start of the file. - * @uc: identify which probe if multiple probes are colocated. + * @uc: identify which probe consumer to unregister. */ -void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) +void uprobe_unregister(struct inode *inode, struct uprobe_consumer *uc) { struct uprobe *uprobe; - uprobe = find_uprobe(inode, offset); + uprobe = find_uprobe(inode, uc->offset); if (WARN_ON(!uprobe)) return; @@ -1277,20 +1276,12 @@ static int __uprobe_register(struct inode *inode, loff_t offset, return ret; } -int uprobe_register(struct inode *inode, loff_t offset, - struct uprobe_consumer *uc) +int uprobe_register(struct inode *inode, struct uprobe_consumer *uc) { - return __uprobe_register(inode, offset, 0, uc); + return __uprobe_register(inode, uc->offset, uc->ref_ctr_offset, uc); }