All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
To: linux-kernel@vger.kernel.org,
	Christoph Hellwig <hch@infradead.org>,
	Andrew Morton <akpm@osdl.org>, Ingo Molnar <mingo@redhat.com>,
	Greg Kroah-Hartman <gregkh@suse.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Tom Zanussi <zanussi@us.ibm.com>,
	Karim Yaghmour <karim@opersys.com>,
	Paul Mundt <lethal@linux-sh.org>, Jes Sorensen <jes@sgi.com>,
	Richard J Moore <richardj_moore@uk.ibm.com>,
	"Martin J. Bligh" <mbligh@mbligh.org>,
	Michel Dagenais <michel.dagenais@polymtl.ca>,
	Douglas Niehaus <niehaus@eecs.ku.edu>,
	ltt-dev@shafik.org, systemtap@sources.redhat.com
Subject: [PATCH 15/16] LTTng 0.6.36 for 2.6.18 : Userspace tracing
Date: Fri, 24 Nov 2006 17:04:13 -0500	[thread overview]
Message-ID: <20061124220413.GP25048@Krystal> (raw)

Userspace tracing : facility registration and event logging through system
call.

patch15-2.6.18-lttng-core-0.6.36-userspace-tracing.diff

Signed-off-by : Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>


--BEGIN--
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -82,6 +82,7 @@ #include <linux/timer.h>
 #include <linux/hrtimer.h>
 
 #include <asm/processor.h>
+#include <linux/ltt-facilities.h>
 
 struct exec_domain;
 struct futex_pi_state;
@@ -996,6 +997,9 @@ #endif
 #ifdef	CONFIG_TASK_DELAY_ACCT
 	struct task_delay_info *delays;
 #endif
+#ifdef CONFIG_LTT_USERSPACE_GENERIC
+	ltt_facility_t ltt_facilities[LTT_FAC_PER_PROCESS];
+#endif //CONFIG_LTT_USERSPACE_GENERIC
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -111,6 +111,8 @@ cond_syscall(sys_vm86old);
 cond_syscall(sys_vm86);
 cond_syscall(compat_sys_ipc);
 cond_syscall(compat_sys_sysctl);
+cond_syscall(sys_ltt_trace_generic);
+cond_syscall(sys_ltt_register_generic);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
--- /dev/null
+++ b/ltt/ltt-syscall.c
@@ -0,0 +1,184 @@
+/******************************************************************************
+ * ltt-syscall.c
+ *
+ * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
+ * March 2006
+ *
+ * LTT userspace tracing syscalls
+ */
+
+#include <linux/errno.h>
+#include <linux/syscalls.h>
+#include <linux/sched.h>
+#include <linux/ltt-facilities.h>
+#include <ltt/ltt-tracer.h>
+
+#include <asm/uaccess.h>
+
+/* User event logging function */
+static inline int trace_user_event(unsigned int facility_id,
+		unsigned int event_id,
+		void __user *data, size_t data_size, int blocking,
+		int high_priority)
+{
+	int ret = 0;
+	unsigned int index;
+	struct ltt_channel_struct *channel;
+	struct ltt_trace_struct *trace;
+	void *transport_data;
+	void *buffer = NULL;
+	size_t real_to_base = 0; /* buffer allocated on arch_size alignment */
+	size_t *to_base = &real_to_base;
+	size_t real_to = 0;
+	size_t *to = &real_to;
+	size_t real_len = 0;
+	size_t *len = &real_len;
+	size_t reserve_size;
+	size_t slot_size;
+	u64 tsc;
+	size_t before_hdr_pad, after_hdr_pad, header_size;
+	struct user_dbg_data dbg;
+
+	dbg.avail_size = 0;
+	dbg.write = 0;
+	dbg.read = 0;
+
+	if (ltt_traces.num_active_traces == 0)
+		return 0;
+
+	/* Assume that the padding for alignment starts at a
+	 * sizeof(void *) address. */
+
+	reserve_size = data_size;
+
+	if (high_priority)
+		index = GET_CHANNEL_INDEX(processes);
+	else
+		index = GET_CHANNEL_INDEX(cpu);
+
+	preempt_disable();
+
+	if (blocking) {
+		/* User space requested blocking mode :
+		 * If one of the active traces has free space below a specific
+		 * threshold value, we reenable preemption and block. */
+block_test_begin:
+		list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+			if (!trace->active)
+  				continue;
+
+			if (trace->ops->user_blocking(trace, index, data_size,
+							&dbg))
+ 				goto block_test_begin;
+		}
+	}
+	ltt_nesting[smp_processor_id()]++;
+	list_for_each_entry_rcu(trace, &ltt_traces.head, list) {
+		if (!trace->active)
+			continue;
+		channel = ltt_get_channel_from_index(trace, index);
+		slot_size = 0;
+		buffer = ltt_reserve_slot(trace, channel, &transport_data,
+			reserve_size, &slot_size, &tsc,
+			&before_hdr_pad, &after_hdr_pad, &header_size);
+		if (!buffer) {
+			if (blocking)
+				trace->ops->user_errors(trace,
+					index, data_size, &dbg);
+			continue; /* buffer full */
+		}
+		*to_base = *to = *len = 0;
+		ltt_write_event_header(trace, channel, buffer,
+			facility_id, event_id,
+			reserve_size, before_hdr_pad, tsc);
+		*to_base += before_hdr_pad + after_hdr_pad + header_size;
+		/* Hope the user pages are not swapped out. In the rare case
+		 * where it is, the slot will be zeroed and EFAULT returned. */
+		if (__copy_from_user_inatomic(buffer+*to_base+*to, data,
+					data_size))
+			ret = -EFAULT;	/* Data is garbage in the slot */
+		ltt_commit_slot(channel, &transport_data, buffer, slot_size);
+		if (ret != 0)
+			break;
+	}
+	ltt_nesting[smp_processor_id()]--;
+	preempt_enable_no_resched();
+	return ret;
+}
+
+asmlinkage long sys_ltt_trace_generic(unsigned int facility_id,
+		unsigned int event_id,
+		void __user *data,
+		size_t data_size,
+		int blocking,
+		int high_priority)
+{
+	if (!ltt_facility_user_access_ok(facility_id))
+		return -EPERM;
+	if (!access_ok(VERIFY_READ, data, data_size))
+			return -EFAULT;
+	
+	return trace_user_event(facility_id, event_id, data, data_size,
+			blocking, high_priority);
+}
+
+asmlinkage long sys_ltt_register_generic(unsigned int __user *facility_id,
+		const struct user_facility_info __user *info)
+{
+	struct user_facility_info kinfo;
+	int fac_id;
+	unsigned int i;
+
+	/* Check if the process has already registered the maximum number of 
+	 * allowed facilities */
+	if (current->ltt_facilities[LTT_FAC_PER_PROCESS-1] != 0)
+		return -EPERM;
+	
+	if (copy_from_user(&kinfo, info, sizeof(*info)))
+		return -EFAULT;
+
+	/* Verify if facility is already registered */
+	printk(KERN_DEBUG "LTT register generic for %s\n", kinfo.name);
+	fac_id = ltt_facility_verify(LTT_FACILITY_TYPE_USER,
+				kinfo.name,
+				kinfo.num_events,
+				kinfo.checksum,
+				kinfo.int_size,
+				kinfo.long_size,
+				kinfo.pointer_size,
+				kinfo.size_t_size,
+				kinfo.alignment);
+	
+	printk(KERN_DEBUG "LTT verify return %d\n", fac_id);
+	if (fac_id > 0)
+		goto found;
+	
+	fac_id = ltt_facility_register(LTT_FACILITY_TYPE_USER,
+				kinfo.name,
+				kinfo.num_events,
+				kinfo.checksum,
+				kinfo.int_size,
+				kinfo.long_size,
+				kinfo.pointer_size,
+				kinfo.size_t_size,
+				kinfo.alignment);
+
+	printk(KERN_DEBUG "LTT register return %d\n", fac_id);
+	if (fac_id == 0)
+		return -EPERM;
+	if (fac_id < 0)
+		return fac_id;	/* Error */
+found:
+	get_task_struct(current->group_leader);
+	for (i = 0; i < LTT_FAC_PER_PROCESS; i++) {
+		if (current->group_leader->ltt_facilities[i] == 0) {
+			current->group_leader->ltt_facilities[i] =
+				(ltt_facility_t)fac_id;
+			break;
+		}
+	}
+	put_task_struct(current->group_leader);
+	/* Write facility_id */
+	put_user((unsigned int)fac_id, facility_id);
+	return 0;
+}
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -38,6 +38,7 @@ #include <linux/compat.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/audit.h> /* for audit_free() */
 #include <linux/resource.h>
+#include <linux/ltt-facilities.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -59,6 +60,17 @@ static void __unhash_process(struct task
 
 		list_del_rcu(&p->tasks);
 		__get_cpu_var(process_counts)--;
+#ifdef CONFIG_LTT_USERSPACE_GENERIC
+		{
+			int i;
+			for (i = 0; i < LTT_FAC_PER_PROCESS; i++) {
+				if (p->ltt_facilities[i] == 0)
+					break;
+				WARN_ON(ltt_facility_unregister(
+							p->ltt_facilities[i]));
+			}
+		}
+#endif //CONFIG_LTT_USERSPACE_GENERIC
 	}
 	list_del_rcu(&p->thread_group);
 	remove_parent(p);
@@ -170,6 +182,7 @@ repeat:
 	write_unlock_irq(&tasklist_lock);
 	proc_flush_task(p);
 	release_thread(p);
+	MARK(kernel_process_free, "%d", p->pid);
 	call_rcu(&p->rcu, delayed_put_task_struct);
 
 	p = leader;
@@ -913,6 +926,8 @@ #endif
 
 	if (group_dead)
 		acct_process();
+	MARK(kernel_process_exit, "%d", tsk->pid);
+	
 	exit_sem(tsk);
 	__exit_files(tsk);
 	__exit_fs(tsk);
@@ -1440,6 +1455,8 @@ static long do_wait(pid_t pid, int optio
 	struct task_struct *tsk;
 	int flag, retval;
 
+	MARK(kernel_process_wait, "%d", pid);
+
 	add_wait_queue(&current->signal->wait_chldexit,&wait);
 repeat:
 	/*
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -45,6 +45,7 @@ #include <linux/acct.h>
 #include <linux/cn_proc.h>
 #include <linux/delayacct.h>
 #include <linux/taskstats_kern.h>
+#include <linux/ltt-facilities.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -64,6 +65,7 @@ int max_threads;		/* tunable limit on nr
 DEFINE_PER_CPU(unsigned long, process_counts) = 0;
 
 __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
+EXPORT_SYMBOL(tasklist_lock);
 
 int nr_processes(void)
 {
@@ -1133,6 +1135,13 @@ #endif
 	 * of CLONE_PTRACE.
 	 */
 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
+#ifdef CONFIG_MARKERS
+	/*
+	 * Syscall tracing must always be turned on when markers are enabled.
+	 * Use the syscall audit thread flag for now, as it is never cleared.
+	 */
+	set_tsk_thread_flag(p, TIF_SYSCALL_AUDIT);
+#endif
 #ifdef TIF_SYSCALL_EMU
 	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
 #endif
@@ -1142,6 +1151,20 @@ #endif
 	   
 	p->parent_exec_id = p->self_exec_id;
 
+#ifdef CONFIG_LTT_USERSPACE_GENERIC
+	if (clone_flags & CLONE_THREAD)
+		memset(p->ltt_facilities, 0, sizeof(p->ltt_facilities));
+	else {
+		int i;
+		for (i = 0; i < LTT_FAC_PER_PROCESS; i++) {
+			p->ltt_facilities[i] = current->ltt_facilities[i];
+			if (p->ltt_facilities[i] != 0)
+				ltt_facility_ref(p->ltt_facilities[i]);
+		}
+	}
+
+#endif //CONFIG_LTT_USERSPACE_GENERIC
+	
 	/* ok, now we should be set up.. */
 	p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
 	p->pdeath_signal = 0;
@@ -1198,7 +1221,7 @@ #endif
 		spin_unlock(&current->sighand->siglock);
 		write_unlock_irq(&tasklist_lock);
 		retval = -ERESTARTNOINTR;
-		goto bad_fork_cleanup_namespace;
+		goto bad_fork_cleanup_ltt_facilities;
 	}
 
 	if (clone_flags & CLONE_THREAD) {
@@ -1251,6 +1274,18 @@ #endif
 	proc_fork_connector(p);
 	return p;
 
+bad_fork_cleanup_ltt_facilities:
+#ifdef CONFIG_LTT_USERSPACE_GENERIC
+		{
+			int i;
+			for (i = 0; i < LTT_FAC_PER_PROCESS; i++) {
+				if (p->ltt_facilities[i] == 0)
+					break;
+				WARN_ON(ltt_facility_unregister(
+							p->ltt_facilities[i]));
+			}
+		}
+#endif //CONFIG_LTT_USERSPACE_GENERIC
 bad_fork_cleanup_namespace:
 	exit_namespace(p);
 bad_fork_cleanup_keys:
@@ -1364,6 +1399,9 @@ long do_fork(unsigned long clone_flags,
 	if (!IS_ERR(p)) {
 		struct completion vfork;
 
+		MARK(kernel_process_fork, "%d %d %d",
+			current->pid, p->pid, p->tgid);
+
 		if (clone_flags & CLONE_VFORK) {
 			p->vfork_done = &vfork;
 			init_completion(&vfork);
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -347,6 +347,8 @@ #define __NR_inotify_rm_watch		(__NR_SYS
 #define __NR_mbind			(__NR_SYSCALL_BASE+319)
 #define __NR_get_mempolicy		(__NR_SYSCALL_BASE+320)
 #define __NR_set_mempolicy		(__NR_SYSCALL_BASE+321)
+#define	__NR_ltt_trace_generic		(__NR_SYSCALL_BASE+322)
+#define	__NR_ltt_register_generic	(__NR_SYSCALL_BASE+323)
 
 /*
  * The following SWIs are ARM private.
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -323,10 +323,12 @@ #define __NR_sync_file_range	314
 #define __NR_tee		315
 #define __NR_vmsplice		316
 #define __NR_move_pages		317
+#define __NR_ltt_trace_generic	318
+#define __NR_ltt_register_generic	319
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 318
+#define NR_syscalls 320
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -329,16 +329,18 @@ #define __NR_sync_file_range		(__NR_Linu
 #define __NR_tee			(__NR_Linux + 306)
 #define __NR_vmsplice			(__NR_Linux + 307)
 #define __NR_move_pages			(__NR_Linux + 308)
+#define	__NR_ltt_trace_generic		(__NR_Linux + 309)
+#define	__NR_ltt_register_generic	(__NR_Linux + 310)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		308
+#define __NR_Linux_syscalls		310
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		308
+#define __NR_O32_Linux_syscalls		310
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -614,16 +616,18 @@ #define __NR_sync_file_range		(__NR_Linu
 #define __NR_tee			(__NR_Linux + 265)
 #define __NR_vmsplice			(__NR_Linux + 266)
 #define __NR_move_pages			(__NR_Linux + 267)
+#define	__NR_ltt_trace_generic		(__NR_Linux + 268)
+#define	__NR_ltt_register_generic	(__NR_Linux + 269)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		267
+#define __NR_Linux_syscalls		269
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		267
+#define __NR_64_Linux_syscalls		269
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -903,16 +907,19 @@ #define __NR_sync_file_range		(__NR_Linu
 #define __NR_tee			(__NR_Linux + 269)
 #define __NR_vmsplice			(__NR_Linux + 270)
 #define __NR_move_pages			(__NR_Linux + 271)
+#define	__NR_ltt_trace_generic		(__NR_Linux + 272)
+#define	__NR_ltt_register_generic	(__NR_Linux + 273)
+
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		271
+#define __NR_Linux_syscalls		273
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		271
+#define __NR_N32_Linux_syscalls		273
 
 #ifdef __KERNEL__
 
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -323,10 +323,12 @@ #define __NR_fchmodat		297
 #define __NR_faccessat		298
 #define __NR_get_robust_list	299
 #define __NR_set_robust_list	300
+#define __NR_ltt_trace_generic	301
+#define __NR_ltt_register_generic	302
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		301
+#define __NR_syscalls		303
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -304,3 +304,5 @@ SYSCALL_SPU(fchmodat)
 SYSCALL_SPU(faccessat)
 COMPAT_SYS_SPU(get_robust_list)
 COMPAT_SYS_SPU(set_robust_list)
+SYSCALL(ltt_trace_generic)
+SYSCALL(ltt_register_generic)
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -619,10 +619,14 @@ #define __NR_vmsplice		278
 __SYSCALL(__NR_vmsplice, sys_vmsplice)
 #define __NR_move_pages		279
 __SYSCALL(__NR_move_pages, sys_move_pages)
+#define __NR_ltt_trace_generic		280
+__SYSCALL(__NR_ltt_trace_generic,	sys_ltt_trace_generic)
+#define __NR_ltt_register_generic		281
+__SYSCALL(__NR_ltt_register_generic,	sys_ltt_register_generic)
 
 #ifdef __KERNEL__
 
-#define __NR_syscall_max __NR_move_pages
+#define __NR_syscall_max __NR_ltt_register_generic
 
 #ifndef __NO_STUBS
 
--END--

OpenPGP public key:              http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint:     8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68 

             reply	other threads:[~2006-11-24 22:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-11-24 22:04 Mathieu Desnoyers [this message]
2006-11-25  2:54 ` [PATCH 15/16] LTTng 0.6.36 for 2.6.18 : Userspace tracing Ralf Baechle
2006-11-25  3:12   ` Mathieu Desnoyers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061124220413.GP25048@Krystal \
    --to=mathieu.desnoyers@polymtl.ca \
    --cc=akpm@osdl.org \
    --cc=gregkh@suse.de \
    --cc=hch@infradead.org \
    --cc=jes@sgi.com \
    --cc=karim@opersys.com \
    --cc=lethal@linux-sh.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ltt-dev@shafik.org \
    --cc=mbligh@mbligh.org \
    --cc=michel.dagenais@polymtl.ca \
    --cc=mingo@redhat.com \
    --cc=niehaus@eecs.ku.edu \
    --cc=richardj_moore@uk.ibm.com \
    --cc=systemtap@sources.redhat.com \
    --cc=tglx@linutronix.de \
    --cc=zanussi@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.