[DTrace-devel] DTrace-V1-ized 5.9 pushed to linux-git.oracle.com and github

Nick Alcock nick.alcock at oracle.com
Mon Oct 12 09:13:07 PDT 2020


Tests passed on x86-64 and AArch64 with https://github.com/oracle/dtrace-utils
(master branch). (Non-stress tests only: one stress test currently
fails on x86-64. This is unlikely to affect normal use unless you do
something most unusual like chill()ing on all fbt probes at once.)

Pushed to <https://github.com/oracle/dtrace-linux-kernel> as a branch
with v1 in the name.

This push is of DTrace v1, using a specialized kernel module rather than BPF.

This update includes adaptation to ongoing kernel build system and API
changes, and a bugfix to dwarf2ctf that allows emission of restrict-
qualified types. (This bug is hard to miss, since a warning is emitted
to stderr every time it is hit: it's very rare, since dwarf2ctf skips
function types, and restrict qualifiers aren't much use anywhere else.)

Changes since 5.8.11:


 1:  87fdc34de617 !  1:  c9c0769a51b6 ctf: generate CTF information for the kernel
    @@ Documentation/process/changes.rst: OpenSSL
     
      ## Makefile ##
     @@ Makefile: cmd_link-vmlinux =                                                 \
    - 	$(CONFIG_SHELL) $< $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) ;    \
    + 	$(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)";    \
      	$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
      
     -vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
    @@ scripts/dwarf2ctf/.gitignore (new)
      ## scripts/dwarf2ctf/Makefile (new) ##
     @@
     +ifdef CONFIG_CTF
    -+always-$(CONFIG_CTF) := dwarf2ctf
    -+hostprogs	:= $(always-y)
    ++hostprogs-always-$(CONFIG_CTF)	:= dwarf2ctf
     +
     +dwarf2ctf-objs  := dwarf2ctf.o eu_simple.o
     +
    @@ scripts/dwarf2ctf/dwarf2ctf.c (new)
     +		if (assembly_len < walk->tag)
     +			assembly_len = walk->tag;
     +	}
    ++	assembly_len++;
     +
    -+	assembly_tab = calloc(sizeof(ctf_assembly_fun *), assembly_len + 1);
    ++	assembly_tab = calloc(sizeof(ctf_assembly_fun *), assembly_len);
     +	assembly_filter_tab = calloc(sizeof(ctf_assembly_filter_fun *),
    -+				     assembly_len + 1);
    ++				     assembly_len);
     +	if ((assembly_tab == NULL) || (assembly_filter_tab == NULL)) {
     +		pr_err("Out of memory allocating assembly table\n");
     +		exit(1);
    @@ scripts/dwarf2ctf/dwarf2ctf.c (new)
     +	 */
     +	return (found_subprogram &&
     +		(add_parent ||
    -+		 (dwarf_tag(parent) <= assembly_len &&
    ++		 (dwarf_tag(parent) < assembly_len &&
     +		  assembly_tab[dwarf_tag(parent)] != NULL)));
     +err:
     +	pr_err("Cannot fetch %s of DIE at offset %lu in %s: %s\n",
    @@ scripts/dwarf2ctf/dwarf2ctf.c (new)
     +	 * emit CTF: call the processing function for all such.
     +	 */
     +	do {
    -+		if ((dwarf_tag(die) <= assembly_len) &&
    ++		if ((dwarf_tag(die) < assembly_len) &&
     +		    (assembly_filter_tab[dwarf_tag(die)] == NULL ||
     +		     assembly_filter_tab[dwarf_tag(die)](file_name, dwarf, die,
     +							 parent_die)) &&
    @@ scripts/dwarf2ctf/dwarf2ctf.c (new)
     +			mark_seen_contained(&child, module_name, overrides, data);
     +			/* fall through */
     +		default:
    -+			if (dwarf_tag(&child) <= assembly_len &&
    ++			if (dwarf_tag(&child) < assembly_len &&
     +			    assembly_tab[dwarf_tag(&child)] != NULL) {
     +
     +				char *id = type_id(&child, overrides, NULL, NULL);
    @@ scripts/package/mkspec: EXCLUDES="$RCS_TAR_IGNORE --exclude=*vmlinux* --exclude=
      	Summary: The Linux Kernel
     @@ scripts/package/mkspec: sed -e '/^DEL/d' -e 's/^\t*//' <<EOF
      	Vendor: The Linux Community
    - 	URL: http://www.kernel.org
    + 	URL: https://www.kernel.org
      $S	Source: kernel-$__KERNELRELEASE.tar.gz
     +$C	BuildRequires: libdtrace-ctf >= 0.5.0
     +$C	BuildRequires: libdtrace-ctf-devel >= 0.5.0
 2:  f417fb34a1e6 !  2:  9d2bf6eb3ee9 kallsyms: introduce new /proc/kallmodsyms including builtin modules too
    @@ include/linux/kallsyms.h: static inline void *dereference_symbol_descriptor(void
     +	loff_t pos_arch_end;
     +	loff_t pos_mod_end;
     +	loff_t pos_ftrace_mod_end;
    ++	loff_t pos_bpf_end;
     +	unsigned long value;
     +	unsigned int nameoff; /* If iterating in core kernel symbols. */
     +	unsigned long size;
    @@ include/linux/kallsyms.h: int lookup_symbol_attrs(unsigned long addr, unsigned l
      static inline unsigned long kallsyms_lookup_name(const char *name)
     
      ## include/linux/module.h ##
    -@@ include/linux/module.h: bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
    +@@ include/linux/module.h: struct symsearch {
      /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
         symnum out of range. */
      int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
    @@ kernel/kallsyms.c: int sprint_backtrace(char *buffer, unsigned long address)
     -	loff_t pos_arch_end;
     -	loff_t pos_mod_end;
     -	loff_t pos_ftrace_mod_end;
    +-	loff_t pos_bpf_end;
     -	unsigned long value;
     -	unsigned int nameoff; /* If iterating in core kernel symbols. */
     -	char type;
    @@ kernel/kallsyms.c: static int get_ksymbol_mod(struct kallsym_iter *iter)
      	if (ret < 0) {
      		iter->pos_mod_end = iter->pos;
      		return 0;
    -@@ kernel/kallsyms.c: static int get_ksymbol_bpf(struct kallsym_iter *iter)
    +@@ kernel/kallsyms.c: static int get_ksymbol_kprobe(struct kallsym_iter *iter)
      static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
      {
      	unsigned off = iter->nameoff;
    @@ kernel/kallsyms.c: static unsigned long get_ksymbol_core(struct kallsym_iter *it
      	iter->name[0] = '\0';
      	iter->nameoff = get_symbol_offset(new_pos);
     @@ kernel/kallsyms.c: static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
    - 		iter->pos_ftrace_mod_end = 0;
    + 		iter->pos_bpf_end = 0;
      	}
      }
     +EXPORT_SYMBOL_GPL(kallsyms_iter_reset);
    @@ kernel/module.c: int module_get_kallsym(unsigned int symnum, unsigned long *valu
      		}
     
      ## scripts/Makefile ##
    -@@ scripts/Makefile: always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
    - always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)		+= extract-cert
    - always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)	+= insert-sys-cert
    +@@ scripts/Makefile: hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
    + hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)	+= extract-cert
    + hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)	+= insert-sys-cert
      
     +kallsyms-objs   := kallsyms.o
     +
 3:  f7f6c23e6091 !  3:  9b4fcbb25da4 waitfd: new syscall implementing waitpid() over fds
    @@ include/linux/syscalls.h: long ksys_old_shmctl(int shmid, int cmd, struct shmid_
     +asmlinkage long sys_waitfd(int which, pid_t upid, int options, int flags);
     +#endif
      
    - #endif
    + int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
    + 		int __user *optlen);
     
      ## include/uapi/asm-generic/unistd.h ##
     @@ include/uapi/asm-generic/unistd.h: __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
 4:  6768beca1fe8 !  4:  3f8362ef4278 dtrace: core and x86
    @@ fs/exec.c
      
      #include <linux/uaccess.h>
      #include <asm/mmu_context.h>
    -@@ fs/exec.c: static int __do_execve_file(int fd, struct filename *filename,
    +@@ fs/exec.c: static int bprm_execve(struct linux_binprm *bprm,
      		goto out;
      
      	/* execve succeeded */
    @@ include/linux/dtrace_cpu.h (new)
     +
     +#include <linux/ktime.h>
     +#include <linux/mutex.h>
    -+#include <linux/rwlock.h>
    ++#include <linux/spinlock.h>
     +#include <linux/dtrace_types.h>
     +#include <linux/dtrace_cpu_defines.h>
     +#include <asm/dtrace_cpuinfo.h>
    @@ include/linux/rwlock.h: do {								\
     
      ## include/linux/sched.h ##
     @@
    - #include <linux/posix-timers.h>
      #include <linux/rseq.h>
    + #include <linux/seqlock.h>
      #include <linux/kcsan.h>
     +#include <linux/dtrace_task.h>
      
    @@ init/Kconfig: config PROFILING
     
      ## init/main.c ##
     @@
    - #include <linux/jump_label.h>
      #include <linux/mem_encrypt.h>
      #include <linux/kcsan.h>
    + #include <linux/init_syscalls.h>
     +#include <linux/dtrace_cpu.h>
     +#include <linux/dtrace_os.h>
      
      #include <asm/io.h>
      #include <asm/bugs.h>
    -@@ init/main.c: asmlinkage __visible void __init start_kernel(void)
    +@@ init/main.c: asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
      	sfi_init_late();
      	kcsan_init();
      
    @@ kernel/fork.c: static __latent_entropy struct task_struct *copy_process(
     +#endif
     +
      	proc_fork_connector(p);
    + 	sched_post_fork(p);
      	cgroup_post_fork(p, args);
    - 	perf_event_fork(p);
     
      ## kernel/module.c ##
     @@
 5:  f7ca6d9cd87b =  5:  303a8f2e1064 dtrace: modular components and x86 support
 6:  c78a4d7230c6 =  6:  1f20467d463a dtrace: systrace provider core components
 7:  a48e15c8d77d =  7:  b05219eb3600 dtrace: systrace provider
 8:  9614c130f296 !  8:  30fac92b7707 dtrace: sdt provider core components
    @@ arch/x86/kernel/dtrace_sdt.c (new)
     + * FILE:        dtrace_sdt.c
     + * DESCRIPTION: Dynamic Tracing: SDT registration code (arch-specific)
     + *
    -+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
    ++ * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
     + */
     +
     +#include <linux/kernel.h>
    @@ arch/x86/kernel/dtrace_sdt.c (new)
     +#include <linux/dtrace_os.h>
     +#include <linux/sdt.h>
     +#include <linux/slab.h>
    ++#include <linux/sync_core.h>
     +#include <linux/vmalloc.h>
     +#include <asm/nmi.h>
     +#include <asm/nops.h>
    @@ scripts/.gitignore: asn1_compiler
     +kmodsdt
     
      ## scripts/Makefile ##
    -@@ scripts/Makefile: always-$(CONFIG_ASN1)				+= asn1_compiler
    - always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
    - always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)		+= extract-cert
    - always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)	+= insert-sys-cert
    -+always-$(CONFIG_DTRACE)				+= kmodsdt
    +@@ scripts/Makefile: hostprogs-always-$(CONFIG_ASN1)				+= asn1_compiler
    + hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
    + hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)	+= extract-cert
    + hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)	+= insert-sys-cert
    ++hostprogs-always-$(CONFIG_DTRACE)			+= kmodsdt
      
      kallsyms-objs   := kallsyms.o
      
    @@ scripts/Makefile: HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
     +HOSTLDLIBS_kmodsdt := -lelf
     +endif
     +
    - hostprogs := $(always-y) $(always-m)
    - 
      # The following programs are only built on demand
    + hostprogs += unifdef
    + 
     
      ## scripts/Makefile.modfinal ##
     @@
    @@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
     -vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
     +vmlinux_link vmlinux "" "${kallsymso}" ${btf_vmlinux_bin_o} ${sdtstubo} ${sdtinfoo}
      
    - if [ -n "${CONFIG_BUILDTIME_TABLE_SORT}" ]; then
    - 	info SORTTAB vmlinux
    + # fill in BTF IDs
    + if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
     
      ## scripts/mod/modpost.c ##
     @@ scripts/mod/modpost.c: static int check_exports(struct module *mod)
 9:  87f7d3a86028 =  9:  bd6aed4de36e dtrace: sdt provider for x86
10:  3c4374bf28ab = 10:  44b188df4c01 dtrace: profile provider and test probe core components
11:  eca3e22904a1 = 11:  f0ab47d4b61b dtrace: profile and tick providers built on cyclics
12:  fe9299935932 = 12:  83bdd9292adb dtrace: USDT and pid provider core and x86 components
13:  e76e7b30998e = 13:  9cb2ed1f5136 dtrace: USDT and pid providers
14:  5b4492052b6e ! 14:  9afcc0094c04 dtrace: function boundary tracing (FBT) core and x86 components
    @@ arch/x86/entry/entry_64.S
      #include <asm/frame.h>
      #include <asm/trapnr.h>
      #include <asm/nospec-branch.h>
    +-#include <asm/fsgsbase.h>
     +#include <asm/dtrace_util.h>
      #include <linux/err.h>
      
    @@ arch/x86/hyperv/hv_init.c: DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_reenlightenment)
      void set_hv_tscchange_cb(void (*cb)(void))
     
      ## arch/x86/include/asm/idtentry.h ##
    -@@ arch/x86/include/asm/idtentry.h: void idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit);
    +@@ arch/x86/include/asm/idtentry.h: void idtentry_exit_nmi(struct pt_regs *regs, bool irq_state);
      #define DECLARE_IDTENTRY(vector, func)					\
      	asmlinkage void asm_##func(void);				\
      	asmlinkage void xen_asm_##func(void);				\
    @@ arch/x86/include/asm/idtentry.h: void idtentry_exit_cond_rcu(struct pt_regs *reg
      
      /**
       * DEFINE_IDTENTRY - Emit code for simple IDT entry points
    -@@ arch/x86/include/asm/idtentry.h: void idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit);
    +@@ arch/x86/include/asm/idtentry.h: void idtentry_exit_nmi(struct pt_regs *regs, bool irq_state);
       * which has to run before returning to the low level assembly code.
       */
      #define DEFINE_IDTENTRY(func)						\
    @@ arch/x86/include/asm/idtentry.h: void idtentry_exit_cond_rcu(struct pt_regs *reg
     -__visible noinstr void func(struct pt_regs *regs)			\
     +__visible noinstr int func(struct pt_regs *regs)			\
      {									\
    - 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
    + 	irqentry_state_t state = irqentry_enter(regs);			\
     +	int ret;							\
      									\
      	instrumentation_begin();					\
     -	__##func (regs);						\
     +	ret = __##func (regs);						\
      	instrumentation_end();						\
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
    + 	irqentry_exit(regs, state);					\
     +	return ret;							\
      }									\
      									\
    @@ arch/x86/include/asm/idtentry.h: static __always_inline void __##func(struct pt_
     +__visible noinstr int func(struct pt_regs *regs,			\
     +			   unsigned long error_code)			\
      {									\
    - 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
    + 	irqentry_state_t state = irqentry_enter(regs);			\
     +	int ret;							\
      									\
      	instrumentation_begin();					\
     -	__##func (regs, error_code);					\
     +	ret = __##func (regs, error_code);				\
      	instrumentation_end();						\
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
    + 	irqentry_exit(regs, state);					\
     +	return ret;							\
      }									\
      									\
    @@ arch/x86/include/asm/idtentry.h: __visible noinstr void func(struct pt_regs *reg
      /**
       * DECLARE_IDTENTRY_IRQ - Declare functions for device interrupt IDT entry
     @@ arch/x86/include/asm/idtentry.h: __visible noinstr void func(struct pt_regs *regs, unsigned long error_code)
    -  * KVM L1D flush request is set.
    +  * has to be done in the function body if necessary.
       */
      #define DEFINE_IDTENTRY_IRQ(func)					\
     -static __always_inline void __##func(struct pt_regs *regs, u8 vector);	\
    @@ arch/x86/include/asm/idtentry.h: __visible noinstr void func(struct pt_regs *reg
     +__visible noinstr int func(struct pt_regs *regs,			\
     +			   unsigned long error_code)			\
      {									\
    - 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
    + 	irqentry_state_t state = irqentry_enter(regs);			\
     +	int ret;							\
      									\
      	instrumentation_begin();					\
    @@ arch/x86/include/asm/idtentry.h: __visible noinstr void func(struct pt_regs *reg
     +	ret = __##func (regs, (u8)error_code);				\
      	irq_exit_rcu();							\
      	instrumentation_end();						\
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
    + 	irqentry_exit(regs, state);					\
     +	return ret;							\
      }									\
      									\
    @@ arch/x86/include/asm/idtentry.h: static __always_inline void __##func(struct pt_
     -__visible noinstr void func(struct pt_regs *regs)			\
     +__visible noinstr int func(struct pt_regs *regs)			\
      {									\
    - 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
    + 	irqentry_state_t state = irqentry_enter(regs);			\
    ++	int ret;							\
      									\
    -@@ arch/x86/include/asm/idtentry.h: __visible noinstr void func(struct pt_regs *regs)			\
    + 	instrumentation_begin();					\
    + 	irq_enter_rcu();						\
    + 	kvm_set_cpu_l1tf_flush_l1d();					\
    +-	run_sysvec_on_irqstack_cond(__##func, regs);			\
    ++	ret = run_sysvec_on_irqstack_cond(__##func, regs);		\
      	irq_exit_rcu();							\
      	instrumentation_end();						\
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
    -+	return 0;							\
    + 	irqentry_exit(regs, state);					\
    ++	return ret;							\
      }									\
      									\
     -static noinline void __##func(struct pt_regs *regs)
    @@ arch/x86/include/asm/idtentry.h: static noinline void __##func(struct pt_regs *r
     -__visible noinstr void func(struct pt_regs *regs)			\
     +__visible noinstr int func(struct pt_regs *regs)			\
      {									\
    - 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
    + 	irqentry_state_t state = irqentry_enter(regs);			\
     +	int ret;							\
      									\
      	instrumentation_begin();					\
    @@ arch/x86/include/asm/idtentry.h: static noinline void __##func(struct pt_regs *r
     +	ret = __##func (regs);						\
      	__irq_exit_raw();						\
      	instrumentation_end();						\
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
    + 	irqentry_exit(regs, state);					\
     +	return ret;							\
      }									\
      									\
    @@ arch/x86/include/asm/idtentry.h: static __always_inline void __##func(struct pt_
      #endif	/* !CONFIG_X86_64 */
      
     
    + ## arch/x86/include/asm/irq_stack.h ##
    +@@ arch/x86/include/asm/irq_stack.h: static __always_inline bool irqstack_active(void)
    + 	return __this_cpu_read(irq_count) != -1;
    + }
    + 
    +-void asm_call_on_stack(void *sp, void (*func)(void), void *arg);
    +-void asm_call_sysvec_on_stack(void *sp, void (*func)(struct pt_regs *regs),
    +-			      struct pt_regs *regs);
    +-void asm_call_irq_on_stack(void *sp, void (*func)(struct irq_desc *desc),
    +-			   struct irq_desc *desc);
    ++int asm_call_on_stack(void *sp, void (*func)(void), void *arg);
    ++int asm_call_sysvec_on_stack(void *sp, int (*func)(struct pt_regs *regs),
    ++			     struct pt_regs *regs);
    ++int asm_call_irq_on_stack(void *sp, void (*func)(struct irq_desc *desc),
    ++			  struct irq_desc *desc);
    + 
    + static __always_inline void __run_on_irqstack(void (*func)(void))
    + {
    +@@ arch/x86/include/asm/irq_stack.h: static __always_inline void __run_on_irqstack(void (*func)(void))
    + 	__this_cpu_sub(irq_count, 1);
    + }
    + 
    +-static __always_inline void
    +-__run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs),
    ++static __always_inline int
    ++__run_sysvec_on_irqstack(int (*func)(struct pt_regs *regs),
    + 			 struct pt_regs *regs)
    + {
    + 	void *tos = __this_cpu_read(hardirq_stack_ptr);
    ++	int ret;
    + 
    + 	__this_cpu_add(irq_count, 1);
    +-	asm_call_sysvec_on_stack(tos - 8, func, regs);
    ++	ret = asm_call_sysvec_on_stack(tos - 8, func, regs);
    + 	__this_cpu_sub(irq_count, 1);
    ++	return ret;
    + }
    + 
    + static __always_inline void
    +@@ arch/x86/include/asm/irq_stack.h: __run_irq_on_irqstack(void (*func)(struct irq_desc *desc),
    + 
    + #else /* CONFIG_X86_64 */
    + static inline bool irqstack_active(void) { return false; }
    +-static inline void __run_on_irqstack(void (*func)(void)) { }
    +-static inline void __run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs),
    +-					    struct pt_regs *regs) { }
    +-static inline void __run_irq_on_irqstack(void (*func)(struct irq_desc *desc),
    +-					 struct irq_desc *desc) { }
    ++static inline int __run_on_irqstack(int (*func)(void)) { }
    ++static inline int __run_sysvec_on_irqstack(int (*func)(struct pt_regs *regs),
    ++					   struct pt_regs *regs) { }
    ++static inline int __run_irq_on_irqstack(int (*func)(struct irq_desc *desc),
    ++					struct irq_desc *desc) { }
    + #endif /* !CONFIG_X86_64 */
    + 
    + static __always_inline bool irq_needs_irq_stack(struct pt_regs *regs)
    +@@ arch/x86/include/asm/irq_stack.h: static __always_inline void run_on_irqstack_cond(void (*func)(void),
    + 		func();
    + }
    + 
    +-static __always_inline void
    +-run_sysvec_on_irqstack_cond(void (*func)(struct pt_regs *regs),
    ++static __always_inline int
    ++run_sysvec_on_irqstack_cond(int (*func)(struct pt_regs *regs),
    + 			    struct pt_regs *regs)
    + {
    + 	lockdep_assert_irqs_disabled();
    + 
    + 	if (irq_needs_irq_stack(regs))
    +-		__run_sysvec_on_irqstack(func, regs);
    ++		return __run_sysvec_on_irqstack(func, regs);
    + 	else
    +-		func(regs);
    ++		return func(regs);
    + }
    + 
    + static __always_inline void
    +
      ## arch/x86/kernel/apic/apic.c ##
     @@ arch/x86/kernel/apic/apic.c: DEFINE_IDTENTRY_SYSVEC(sysvec_apic_timer_interrupt)
      	trace_local_timer_exit(LOCAL_TIMER_VECTOR);
    @@ arch/x86/kernel/irq_work.c: DEFINE_IDTENTRY_SYSVEC(sysvec_irq_work)
      void arch_irq_work_raise(void)
     
      ## arch/x86/kernel/nmi.c ##
    -@@ arch/x86/kernel/nmi.c: static DEFINE_PER_CPU(unsigned long, nmi_dr7);
    - DEFINE_IDTENTRY_RAW(exc_nmi)
    - {
    +@@ arch/x86/kernel/nmi.c: DEFINE_IDTENTRY_RAW(exc_nmi)
    + 	bool irq_state;
    + 
      	if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id()))
     -		return;
     +		return 0;
    @@ arch/x86/kernel/traps.c: DEFINE_IDTENTRY_RAW(exc_invalid_op)
     -		return;
     +		return 0;
      
    - 	rcu_exit = idtentry_enter_cond_rcu(regs);
    + 	state = irqentry_enter(regs);
      	instrumentation_begin();
      	handle_invalid_op(regs);
      	instrumentation_end();
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);
    + 	irqentry_exit(regs, state);
     +	return 0;
      }
      
    @@ arch/x86/kernel/traps.c: static bool do_int3(struct pt_regs *regs)
     +		return 0;
      
      	/*
    - 	 * idtentry_enter_user() uses static_branch_{,un}likely() and therefore
    + 	 * irqentry_enter_from_user_mode() uses static_branch_{,un}likely()
     @@ arch/x86/kernel/traps.c: DEFINE_IDTENTRY_RAW(exc_int3)
      	if (user_mode(regs)) {
    - 		idtentry_enter_user(regs);
    + 		irqentry_enter_from_user_mode(regs);
      		instrumentation_begin();
     -		do_int3_user(regs);
     +		ret = do_int3_user(regs);
      		instrumentation_end();
    - 		idtentry_exit_user(regs);
    + 		irqentry_exit_to_user_mode(regs);
      	} else {
    - 		nmi_enter();
    + 		bool irq_state = idtentry_enter_nmi(regs);
      		instrumentation_begin();
    - 		trace_hardirqs_off_finish();
     -		if (!do_int3(regs))
     +		if (!do_int3(regs, &ret))
      			die("int3", regs, 0);
    - 		if (regs->flags & X86_EFLAGS_IF)
    - 			trace_hardirqs_on_prepare();
      		instrumentation_end();
    - 		nmi_exit();
    + 		idtentry_exit_nmi(regs, irq_state);
      	}
     +	return ret;
      }
    @@ arch/x86/mm/fault.c: DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
     @@ arch/x86/mm/fault.c: DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
      	instrumentation_end();
      
    - 	idtentry_exit_cond_rcu(regs, rcu_exit);
    + 	irqentry_exit(regs, state);
     +	return 0;
      }
     
    @@ arch/x86/xen/enlighten_hvm.c: DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)
     
      ## arch/x86/xen/enlighten_pv.c ##
     @@ arch/x86/xen/enlighten_pv.c: static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
    + 	preempt_enable();
      }
      
    - #ifdef CONFIG_X86_64
     -void noist_exc_debug(struct pt_regs *regs);
     +int noist_exc_debug(struct pt_regs *regs);
      
    @@ kernel/dtrace/dtrace_os.c: void __init dtrace_os_init(void)
     
      ## kernel/kprobes.c ##
     @@
    - #include <linux/cpu.h>
      #include <linux/jump_label.h>
    + #include <linux/perf_event.h>
      
     +#ifdef CONFIG_DTRACE
     +#include <linux/dtrace_fbt.h>
15:  8e8c6f6dc1c6 = 15:  c5af61db4875 dtrace: fbt provider, modular components
16:  9637d9dca8a5 = 16:  5617fe25b354 dtrace, arm: arm64 port
17:  3a9239c75e11 ! 17:  e756f3b9d344 dtrace: add SDT probes
    @@ block/bio.c: void bio_endio(struct bio *bio)
      	if (bio->bi_end_io)
     
      ## block/blk-core.c ##
    -@@ block/blk-core.c: generic_make_request_checks(struct bio *bio)
    +@@ block/blk-core.c: static noinline_for_stack bool submit_bio_checks(struct bio *bio)
      		 */
      		bio_set_flag(bio, BIO_TRACE_COMPLETION);
      	}
    @@ fs/exec.c
      #include <linux/dtrace_os.h>
      
      #include <linux/uaccess.h>
    -@@ fs/exec.c: static int __do_execve_file(int fd, struct filename *filename,
    - 	check_unsafe_exec(bprm);
    +@@ fs/exec.c: static int bprm_execve(struct linux_binprm *bprm,
      	current->in_execve = 1;
      
    --	if (!file)
    -+	if (!file) {
    - 		file = do_open_execat(fd, filename, flags);
    -+		DTRACE_PROC(exec, char *, filename->name);
    -+	}
    + 	file = do_open_execat(fd, filename, flags);
    ++	DTRACE_PROC(exec, char *, filename->name);
      	retval = PTR_ERR(file);
      	if (IS_ERR(file))
      		goto out_unmark;
    -@@ fs/exec.c: static int __do_execve_file(int fd, struct filename *filename,
    - 		putname(filename);
    +@@ fs/exec.c: static int bprm_execve(struct linux_binprm *bprm,
    + 	task_numa_free(current, false);
      	if (displaced)
      		put_files_struct(displaced);
     +
    @@ fs/exec.c: static int __do_execve_file(int fd, struct filename *filename,
      	return retval;
      
      out:
    -@@ fs/exec.c: static int __do_execve_file(int fd, struct filename *filename,
    - 	if (displaced)
    - 		reset_files_struct(displaced);
    +@@ fs/exec.c: static int do_execveat_common(int fd, struct filename *filename,
    + 
      out_ret:
    --	if (filename)
    -+	if (filename) {
    - 		putname(filename);
    + 	putname(filename);
    ++	if (retval < 0)
    ++		DTRACE_PROC(exec__failure, int, retval);
    + 	return retval;
    + }
    + 
    +@@ fs/exec.c: int kernel_execve(const char *kernel_filename,
    + 	free_bprm(bprm);
    + out_ret:
    + 	putname(filename);
    ++	if (retval < 0)
     +		DTRACE_PROC(exec__failure, int, retval);
    -+	}
      	return retval;
      }
      
    @@ net/ipv4/tcp_output.c: int tcp_connect(struct sock *sk)
     
      ## net/ipv4/udp.c ##
     @@
    - #include <net/xfrm.h>
      #include <trace/events/udp.h>
      #include <linux/static_key.h>
    + #include <linux/btf_ids.h>
     +#include <linux/sdt.h>
      #include <trace/events/skb.h>
      #include <net/busy_poll.h>
18:  75bc3b84ca22 = 18:  be29c750e742 dtrace: add rcu_irq_exit and rcu_nmi_exit_common to FBT blacklist
19:  c75c3720af7e = 19:  343e811c4804 dtrace: add sample script for building DTrace on Fedora
20:  c6c81f53132a = 20:  1c33df24bb35 locking: publicize mutex_owner and mutex_owned again
21:  3983ebd752b3 = 21:  0236c7f19fef dtrace, sdt: use gawk everywhere, not awk
22:  be0816c0a8a1 = 22:  c731ef8ca2d6 dtrace: move _sdt_probes array into a separately-compiled file



More information about the DTrace-devel mailing list