LTTng instrumentation (arch independent)
Subsystems (16)
cover LTTng instrumentation (arch independent)
Hi,
This is the second RFC post for the LTTng architecture independent instrumentation. I have mostly received interesting ideas from the mm group, which I have added here.
It applies on top of 2.6.24-rc4-git3, on top of the Linux Kernel Markers with Immediate Values patchset.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/7 Include marker.h in kernel.h -- temporary, for code readability
This patch is a hack to make my life easier : it lessens the conflicts due to header includes that changes between the kernel versions.
The proper way to do this is to include <linux/marker.h> in every file using the markers.
NOT FOR UPSTREAM.
--- include/linux/kernel.h | 1 + 1 file changed, 1 insertion(+)
include/linux/kernel.h +1 -0
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/marker.h> #include <asm/byteorder.h> #include <asm/bug.h>
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 2/7 LTTng instrumentation fs
In reply to Mathieu DesnoyersCore filesystem events markers.
--- fs/buffer.c | 2 ++ fs/compat.c | 1 + fs/exec.c | 1 + fs/ioctl.c | 2 ++ fs/open.c | 2 ++ fs/read_write.c | 22 ++++++++++++++++++++-- fs/select.c | 4 ++++ 7 files changed, 32 insertions(+), 2 deletions(-)
fs/buffer.c +2 -0
@@ -89,7 +89,9 @@ void fastcall unlock_buffer(struct buffe*/ void __wait_on_buffer (struct buffer_head * bh) { +trace_mark (fs_buffer_wait_start,"bh %p" , bh);wait_on_bit (&bh->b_state, BH_Lock, sync_buffer,TASK_UNINTERRUPTIBLE ); +trace_mark (fs_buffer_wait_end,"bh %p" , bh); } static void
fs/compat.c +1 -0
@@ -1408,6 +1408,7 @@ int compat_do_execve(char * filename, retval =search_binary_handler (bprm, regs);if (retval >=0 ) { +trace_mark (fs_exec,"filename %s" , filename);/* execve success */ security_bprm_free (bprm);acct_update_integrals (current);
fs/ioctl.c +2 -0
@@ -164,6 +164,8 @@ asmlinkage long sys_ioctl(unsigned int fif (!filp) goto out; +trace_mark (fs_ioctl,"fd %u cmd %u arg %lu" , fd, cmd, arg); + error =security_file_ioctl (filp, cmd, arg);if (error) goto out_fput;
fs/open.c +2 -0
@@ -1043,6 +1043,7 @@ long do_sys_open(int dfd, const char __ufsnotify_open (f->f_path.dentry);fd_install (fd, f); } +trace_mark (fs_open,"fd %d filename %s" , fd, tmp); }putname (tmp); }
@@ -1133,6 +1134,7 @@ asmlinkage long sys_close(unsigned int f filp = fdt->fd[fd];if (!filp) goto out_unlock; +trace_mark (fs_close,"fd %u" , fd);rcu_assign_pointer (fdt->fd[fd],NULL );FD_CLR (fd, fdt->close_on_exec);__put_unused_fd (files, fd);
fs/read_write.c +20 -2
@@ -146,6 +146,9 @@ asmlinkage off_t sys_lseek(unsigned intif (res != (loff_t )retval) retval = -EOVERFLOW ;/* LFS: should only happen on 32 bit platforms */ } + +trace_mark (fs_lseek,"fd %u offset %ld origin %u" , fd, offset, origin); +fput_light (file, fput_needed); bad:return retval;
@@ -173,6 +176,10 @@ asmlinkage long sys_llseek(unsigned int offset =vfs_llseek (file, ((loff_t ) offset_high <<32 ) | offset_low, origin); +trace_mark (fs_llseek,"fd %u offset %llu origin %u" , fd, + (unsigned long long )offset, + origin); + retval = (int )offset;if (offset >=0 ) { retval = -EFAULT ;
@@ -363,6 +370,7 @@ asmlinkage ssize_t sys_read(unsigned int file =fget_light (fd, &fput_needed);if (file) {loff_t pos =file_pos_read (file); +trace_mark (fs_read,"fd %u count %zu" , fd, count); ret =vfs_read (file, buf, count, &pos);file_pos_write (file, pos);fput_light (file, fput_needed);
@@ -381,6 +389,7 @@ asmlinkage ssize_t sys_write(unsigned in file =fget_light (fd, &fput_needed);if (file) {loff_t pos =file_pos_read (file); +trace_mark (fs_write,"fd %u count %zu" , fd, count); ret =vfs_write (file, buf, count, &pos);file_pos_write (file, pos);fput_light (file, fput_needed);
@@ -402,8 +411,12 @@ asmlinkage ssize_t sys_pread64(unsigned file =fget_light (fd, &fput_needed);if (file) { ret = -ESPIPE ; -if (file->f_mode &FMODE_PREAD ) +if (file->f_mode &FMODE_PREAD ) { +trace_mark (fs_pread64,"fd %u count %zu pos %llu" , + fd, count, (unsigned long long )pos); ret =vfs_read (file, buf, count, &pos); + } +fput_light (file, fput_needed); }
@@ -423,8 +436,11 @@ asmlinkage ssize_t sys_pwrite64(unsigned file =fget_light (fd, &fput_needed);if (file) { ret = -ESPIPE ; -if (file->f_mode &FMODE_PWRITE ) +if (file->f_mode &FMODE_PWRITE ) { +trace_mark (fs_pwrite64,"fd %u count %zu pos %llu" , + fd, count, (unsigned long long )pos); ret =vfs_write (file, buf, count, &pos); + }fput_light (file, fput_needed); }
@@ -670,6 +686,7 @@ sys_readv(unsigned long fd, const struct file =fget_light (fd, &fput_needed);if (file) {loff_t pos =file_pos_read (file); +trace_mark (fs_readv,"fd %lu vlen %lu" , fd, vlen); ret =vfs_readv (file, vec, vlen, &pos);file_pos_write (file, pos);fput_light (file, fput_needed);
@@ -691,6 +708,7 @@ sys_writev(unsigned long fd, const struc file =fget_light (fd, &fput_needed);if (file) {loff_t pos =file_pos_read (file); +trace_mark (fs_writev,"fd %lu vlen %lu" , fd, vlen); ret =vfs_writev (file, vec, vlen, &pos);file_pos_write (file, pos);fput_light (file, fput_needed);
fs/select.c +4 -0
@@ -231,6 +231,9 @@ int do_select(int n, fd_set_bits *fds, s file =fget_light (i, &fput_needed);if (file) { f_op = file->f_op; +trace_mark (fs_select, +"fd %d timeout #8d%lld" , + i, (long long )*timeout); mask =DEFAULT_POLLMASK ;if (f_op && f_op->poll) mask = (*f_op->poll)(file, retval ?NULL : wait);
@@ -559,6 +562,7 @@ static inline unsigned int do_pollfd(str file =fget_light (fd, &fput_needed); mask =POLLNVAL ;if (file !=NULL ) { +trace_mark (fs_pollfd,"fd %d" , fd); mask =DEFAULT_POLLMASK ;if (file->f_op && file->f_op->poll) mask = file->f_op->poll (file, pwait);
fs/exec.c +1 -0
@@ -1351,6 +1351,7 @@ int do_execve(char * filename, retval =search_binary_handler (bprm,regs);if (retval >=0 ) { +trace_mark (fs_exec,"filename %s" , filename);/* execve success */ free_arg_pages (bprm);security_bprm_free (bprm);
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 3/7 LTTng instrumentation ipc
In reply to Mathieu DesnoyersInterprocess communication, core events.
--- ipc/msg.c | 5 ++++- ipc/sem.c | 5 ++++- ipc/shm.c | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-)
ipc/msg.c +4 -1
@@ -315,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, instruct ipc_namespace *ns;struct ipc_ops msg_ops;struct ipc_params msg_params; +long ret; ns = current->nsproxy->ipc_ns;
@@ -325,7 +326,9 @@ asmlinkage long sys_msgget(key_t key, in msg_params.key = key; msg_params.flg = msgflg; -return ipcget (ns, &msg_ids (ns), &msg_ops, &msg_params); + ret =ipcget (ns, &msg_ids (ns), &msg_ops, &msg_params); +trace_mark (ipc_msg_create,"id %ld flags %d" , ret, msgflg); +return ret; } static inline unsigned long
ipc/sem.c +4 -1
@@ -334,6 +334,7 @@ asmlinkage long sys_semget(key_t key, instruct ipc_namespace *ns;struct ipc_ops sem_ops;struct ipc_params sem_params; +long err; ns = current->nsproxy->ipc_ns;
@@ -348,7 +349,9 @@ asmlinkage long sys_semget(key_t key, in sem_params.flg = semflg; sem_params.u.nsems = nsems; -return ipcget (ns, &sem_ids (ns), &sem_ops, &sem_params); + err =ipcget (ns, &sem_ids (ns), &sem_ops, &sem_params); +trace_mark (ipc_sem_create,"id %ld flags %d" , err, semflg); +return err; }/* Manage the doubly linked list sma->sem_pending as a FIFO:
ipc/shm.c +4 -1
@@ -497,6 +497,7 @@ asmlinkage long sys_shmget (key_t key, sstruct ipc_namespace *ns;struct ipc_ops shm_ops;struct ipc_params shm_params; +long err; ns = current->nsproxy->ipc_ns;
@@ -508,7 +509,9 @@ asmlinkage long sys_shmget (key_t key, s shm_params.flg = shmflg; shm_params.u.size = size; -return ipcget (ns, &shm_ids (ns), &shm_ops, &shm_params); + err =ipcget (ns, &shm_ids (ns), &shm_ops, &shm_params); +trace_mark (ipc_shm_create,"id %ld flags %d" , err, shmflg); +return err; }static inline unsigned long copy_shmid_to_user (void __user *buf,struct shmid64_ds *in,int version)
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 4/7 LTTng instrumentation kernel
In reply to Mathieu DesnoyersCore kernel events.
*not* present in this patch because they are architecture specific :
- syscall entry/exit
- traps
- kernel thread creation
--- kernel/exit.c | 6 ++++++ kernel/fork.c | 4 ++++ kernel/irq/handle.c | 6 ++++++ kernel/itimer.c | 11 +++++++++++ kernel/kthread.c | 4 ++++ kernel/lockdep.c | 19 +++++++++++++++++++ kernel/module.c | 4 ++++ kernel/printk.c | 26 ++++++++++++++++++++++++++ kernel/sched.c | 11 +++++++++++ kernel/signal.c | 2 ++ kernel/softirq.c | 22 ++++++++++++++++++++++ kernel/timer.c | 12 +++++++++++- 12 files changed, 126 insertions(+), 1 deletion(-)
kernel/irq/handle.c +6 -0
@@ -130,6 +130,10 @@ irqreturn_t handle_IRQ_event(unsigned in {irqreturn_t ret, retval =IRQ_NONE ;unsigned int status =0 ; +struct pt_regs *regs =get_irq_regs (); + +trace_mark (kernel_irq_entry,"irq_id %u kernel_mode %u" , irq, + (regs)?(!user_mode (regs)):(1 ));handle_dynamic_tick (action);
@@ -148,6 +152,8 @@ irqreturn_t handle_IRQ_event(unsigned inadd_interrupt_randomness (irq);local_irq_disable (); +trace_mark (kernel_irq_exit,MARK_NOARGS ); +return retval; }
kernel/itimer.c +11 -0
@@ -132,6 +132,8 @@ enum hrtimer_restart it_real_fn(struct hstruct signal_struct *sig = container_of(timer, struct signal_struct, real_timer); +trace_mark (kernel_timer_itimer_expired,"pid %d" , sig->tsk->pid); +send_group_sig_info (SIGALRM ,SEND_SIG_PRIV , sig->tsk);return HRTIMER_NORESTART ;
@@ -157,6 +159,15 @@ int do_setitimer(int which, struct itime !timeval_valid(&value->it_interval))return -EINVAL ; +trace_mark (kernel_timer_itimer_set, +"which %d interval_sec %ld interval_usec %ld " +"value_sec %ld value_usec %ld" , + which, + value->it_interval.tv_sec, + value->it_interval.tv_usec, + value->it_value.tv_sec, + value->it_value.tv_usec); +switch (which) {case ITIMER_REAL : again:
kernel/kthread.c +4 -0
@@ -195,6 +195,8 @@ int kthread_stop(struct task_struct *k)/* It could exit after stop_info.k set, but before wake_up_process. */ get_task_struct (k); +trace_mark (kernel_kthread_stop,"pid %d" , k->pid); +/* Must init completion *before* thread sees kthread_stop_info.k */ init_completion (&kthread_stop_info.done);smp_wmb ();
@@ -210,6 +212,8 @@ int kthread_stop(struct task_struct *k) ret = kthread_stop_info.err;mutex_unlock (&kthread_stop_lock); +trace_mark (kernel_kthread_stop_ret,"ret %d" , ret); +return ret; }EXPORT_SYMBOL (kthread_stop);
kernel/lockdep.c +19 -0
@@ -2014,6 +2014,9 @@ void trace_hardirqs_on(void)struct task_struct *curr = current;unsigned long ip; +_trace_mark (locking_hardirqs_on,"ip #p%lu" , + (unsigned long )__builtin_return_address (0 )); +if (unlikely (!debug_locks || current->lockdep_recursion))return ;
@@ -2061,6 +2064,9 @@ void trace_hardirqs_off(void) {struct task_struct *curr = current; +_trace_mark (locking_hardirqs_off,"ip #p%lu" , + (unsigned long )__builtin_return_address (0 )); +if (unlikely (!debug_locks || current->lockdep_recursion))return ;
@@ -2088,6 +2094,9 @@ void trace_softirqs_on(unsigned long ip) {struct task_struct *curr = current; +_trace_mark (locking_softirqs_on,"ip #p%lu" , + (unsigned long )__builtin_return_address (0 )); +if (unlikely (!debug_locks))return ;
@@ -2122,6 +2131,9 @@ void trace_softirqs_off(unsigned long ip {struct task_struct *curr = current; +_trace_mark (locking_softirqs_off,"ip #p%lu" , + (unsigned long )__builtin_return_address (0 )); +if (unlikely (!debug_locks))return ;
@@ -2358,6 +2370,10 @@ static int __lock_acquire(struct lockdepint chain_head =0 ;u64 chain_key; +_trace_mark (locking_lock_acquire, +"ip #p%lu subclass %u lock %p trylock %d" , + ip, subclass, lock, trylock); +if (!prove_locking) check =1 ;
@@ -2631,6 +2647,9 @@ __lock_release(struct lockdep_map *lock, {struct task_struct *curr = current; +_trace_mark (locking_lock_release,"ip #p%lu lock %p nested %d" , + ip, lock, nested); +if (!check_unlock (curr, lock, ip))return ;
kernel/printk.c +26 -0
@@ -619,6 +619,7 @@ asmlinkage int printk(const char *fmt, .int r;va_start (args, fmt); +trace_mark (kernel_printk,"ip %p" ,__builtin_return_address (0 )); r =vprintk (fmt, args);va_end (args);
@@ -653,6 +654,31 @@ asmlinkage int vprintk(const char *fmt,/* Emit the output into the temporary buffer */ printed_len =vscnprintf (printk_buf,sizeof (printk_buf), fmt, args); +if (printed_len >0 ) { +unsigned int loglevel; +int mark_len; +char *mark_buf; +char saved_char; + +if (printk_buf[0 ] =='<' && printk_buf[1 ] >='0' && + printk_buf[1 ] <='7' && printk_buf[2 ] =='>' ) { + loglevel = printk_buf[1 ] -'0' ; + mark_buf = &printk_buf[3 ]; + mark_len = printed_len -3 ; + }else { + loglevel = default_message_loglevel; + mark_buf = printk_buf; + mark_len = printed_len; + } +if (mark_buf[mark_len -1 ] =='\n' ) + mark_len--; + saved_char = mark_buf[mark_len]; + mark_buf[mark_len] ='\0' ; +_trace_mark (kernel_vprintk,"loglevel %c string %s ip %p" , + loglevel, mark_buf,__builtin_return_address (0 )); + mark_buf[mark_len] = saved_char; + } +/* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here
kernel/sched.c +11 -0
@@ -1172,6 +1172,8 @@ void wait_task_inactive(struct task_stru* just go back and repeat. */ rq =task_rq_lock (p, &flags); +trace_mark (kernel_sched_wait_task,"pid %d state %ld" , + p->pid, p->state); running =task_running (rq, p); on_rq = p->se.on_rq;task_rq_unlock (rq, &flags);
@@ -1506,6 +1508,8 @@ static int try_to_wake_up(struct task_st#endif rq =task_rq_lock (p, &flags); +trace_mark (kernel_sched_try_wakeup,"pid %d state %ld" , + p->pid, p->state); old_state = p->state;if (!(old_state & state)) goto out;
@@ -1744,6 +1748,8 @@ void fastcall wake_up_new_task(struct tastruct rq *rq; rq =task_rq_lock (p, &flags); +trace_mark (kernel_sched_wakeup_new_task,"pid %d state %ld" , + p->pid, p->state);BUG_ON (p->state !=TASK_RUNNING );update_rq_clock (rq);
@@ -1922,6 +1928,9 @@ context_switch(struct rq *rq, struct tasstruct mm_struct *mm, *oldmm;prepare_task_switch (rq, prev, next); +trace_mark (kernel_sched_schedule, +"prev_pid %d next_pid %d prev_state %ld" , + prev->pid, next->pid, prev->state); mm = next->mm; oldmm = prev->active_mm;/*
@@ -2150,6 +2159,8 @@ static void sched_migrate_task(struct ta || unlikely(cpu_is_offline(dest_cpu))) goto out; +trace_mark (kernel_sched_migrate_task,"pid %d state %ld dest_cpu %d" , + p->pid, p->state, dest_cpu);/* force the process onto the specified CPU */ if (migrate_task (p, dest_cpu, &req)) {/* Need to wait for migration thread (might exit: take ref). */
kernel/signal.c +2 -0
@@ -663,6 +663,8 @@ static int send_signal(int sig, struct sstruct sigqueue * q =NULL ;int ret =0 ; +trace_mark (kernel_send_signal,"pid %d signal %d" , t->pid, sig); +/* * Deliver the signal to listening signalfds. This must be called * with the sighand lock held.
kernel/softirq.c +22 -0
@@ -229,7 +229,15 @@ restart: do { if (pending & 1) { + trace_mark(kernel_softirq_entry, "softirq_id %lu", + ((unsigned long)h + - (unsigned long)softirq_vec) + / sizeof(*h)); h->action(h); + trace_mark(kernel_softirq_exit, "softirq_id %lu", + ((unsigned long)h + - (unsigned long)softirq_vec) + / sizeof(*h)); rcu_bh_qsctr_inc(cpu); } h++;
@@ -315,6 +323,8 @@ void irq_exit(void)*/ inline fastcall void raise_softirq_irqoff(unsigned int nr) { +trace_mark (kernel_softirq_raise,"softirq %u" , nr); +__raise_softirq_irqoff (nr);/*
@@ -400,7 +410,13 @@ static void tasklet_action(struct softirif (!atomic_read (&t->count)) {if (!test_and_clear_bit (TASKLET_STATE_SCHED , &t->state))BUG (); +trace_mark (kernel_tasklet_low_entry, +"func %p data %lu" , + t->func, t->data); t->func (t->data); +trace_mark (kernel_tasklet_low_exit, +"func %p data %lu" , + t->func, t->data);tasklet_unlock (t);continue ; }
@@ -433,7 +449,13 @@ static void tasklet_hi_action(struct sofif (!atomic_read (&t->count)) {if (!test_and_clear_bit (TASKLET_STATE_SCHED , &t->state))BUG (); +trace_mark (kernel_tasklet_high_entry, +"func %p data %lu" , + t->func, t->data); t->func (t->data); +trace_mark (kernel_tasklet_high_exit, +"func %p data %lu" , + t->func, t->data);tasklet_unlock (t);continue ; }
kernel/timer.c +11 -1
@@ -43,6 +43,7 @@#include <asm/div64.h> #include <asm/timex.h> #include <asm/io.h> +#include <asm/irq_regs.h> u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
@@ -290,6 +291,8 @@ static void internal_add_timer(tvec_base i = (expires >> (TVR_BITS +3 *TVN_BITS )) &TVN_MASK ; vec = base->tv5.vec + i; } +trace_mark (kernel_timer_set,"expires %lu function %p data %lu" , + expires, timer->function, timer->data);/* * Timers are FIFO: */
@@ -931,6 +934,11 @@ void do_timer(unsigned long ticks) { jiffies_64 += ticks;update_times (ticks); +trace_mark (kernel_timer_update_time, +"jiffies #8u%llu xtime_sec %ld xtime_nsec %ld " +"walltomonotonic_sec %ld walltomonotonic_nsec %ld" , + (unsigned long long )jiffies_64, xtime.tv_sec, xtime.tv_nsec, + wall_to_monotonic.tv_sec, wall_to_monotonic.tv_nsec); }#ifdef __ARCH_WANT_SYS_ALARM
@@ -1012,7 +1020,9 @@ asmlinkage long sys_getegid(void)static void process_timeout (unsigned long __data) { -wake_up_process ((struct task_struct *)__data); +struct task_struct *task = (struct task_struct *)__data; +trace_mark (kernel_timer_timeout,"pid %d" , task->pid); +wake_up_process (task); }/**
kernel/exit.c +6 -0
@@ -139,6 +139,8 @@ static void __exit_signal(struct task_ststatic void delayed_put_task_struct (struct rcu_head *rhp) { +trace_mark (kernel_process_free,"pid %d" , + container_of(rhp, struct task_struct, rcu)->pid);put_task_struct (container_of(rhp ,struct task_struct ,rcu )); }
@@ -994,6 +996,8 @@ fastcall NORET_TYPE void do_exit(long coif (group_dead)acct_process (); +trace_mark (kernel_process_exit,"pid %d" , tsk->pid); +exit_sem (tsk);__exit_files (tsk);__exit_fs (tsk);
@@ -1537,6 +1541,8 @@ static long do_wait(pid_t pid, int optioint flag, retval;int allowed, denied; +trace_mark (kernel_process_wait,"pid %d" , pid); +add_wait_queue (¤t->signal->wait_chldexit,&wait); repeat:/*
kernel/fork.c +4 -0
@@ -1426,6 +1426,10 @@ long do_fork(unsigned long clone_flags,if (!IS_ERR (p)) {struct completion vfork; +trace_mark (kernel_process_fork, +"parent_pid %d child_pid %d child_tgid %d" , + current->pid, p->pid, p->tgid); +/* * this is enough to call pid_nr_ns here, but this if * improves optimisation of regular fork()
kernel/module.c +4 -0
@@ -1296,6 +1296,8 @@ static int __unlink_module(void *_mod)/* Free a module, remove from lists, etc (must hold module_mutex). */ static void free_module (struct module *mod) { +trace_mark (kernel_module_free,"name %s" , mod->name); +/* Delete from various lists */ stop_machine_run (__unlink_module, mod,NR_CPUS );remove_notes_attrs (mod);
@@ -2065,6 +2067,8 @@ static struct module *load_module(void _/* Get rid of temporary copy */ vfree (hdr); +trace_mark (kernel_module_load,"name %s" , mod->name); +/* Done! */ return mod;
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 5/7 LTTng instrumentation mm
In reply to Mathieu DesnoyersMemory management core events.
Changelog:
- Use page_to_pfn for swap out instrumentation, wait_on_page_bit, do_swap_page, page alloc/free.
- add missing free_hot_cold_page instrumentation.
- add hugetlb page_alloc page_free instrumentation.
- Add write_access to mm fault.
- Add page bit_nr waited for by wait_on_page_bit.
- Move page alloc instrumentation to __aloc_pages so we cover the alloc zeroed page path.
- Add swap file used for swap in and swap out events.
- Dump the swap files, instrument swapon and swapoff.
--- include/linux/swapops.h | 8 ++++++++ mm/filemap.c | 6 ++++++ mm/hugetlb.c | 2 ++ mm/memory.c | 38 +++++++++++++++++++++++++++++--------- mm/page_alloc.c | 6 ++++++ mm/page_io.c | 5 +++++ mm/swapfile.c | 22 ++++++++++++++++++++++ 7 files changed, 78 insertions(+), 9 deletions(-)
mm/filemap.c +6 -0
@@ -514,9 +514,15 @@ void fastcall wait_on_page_bit(struct pa {DEFINE_WAIT_BIT (wait, &page->flags, bit_nr); +trace_mark (mm_filemap_wait_start,"pfn %lu bit_nr %d" , +page_to_pfn (page), bit_nr); +if (test_bit (bit_nr, &page->flags))__wait_on_bit (page_waitqueue (page), &wait, sync_page,TASK_UNINTERRUPTIBLE ); + +trace_mark (mm_filemap_wait_end,"pfn %lu bit_nr %d" , +page_to_pfn (page), bit_nr); }EXPORT_SYMBOL (wait_on_page_bit);
mm/memory.c +29 -9
@@ -2090,6 +2090,10 @@ static int do_swap_page(struct mm_struct/* Had to read the page from swap area: Major fault */ ret =VM_FAULT_MAJOR ;count_vm_event (PGMAJFAULT ); +trace_mark (mm_swap_in,"pfn %lu filp %p offset %lu" , +page_to_pfn (page), +get_swap_info_struct (swp_type (entry))->swap_file, +swp_offset (entry)); }mark_page_accessed (page);
@@ -2526,30 +2530,46 @@ unlock:int handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access) { +int res;pgd_t *pgd;pud_t *pud;pmd_t *pmd;pte_t *pte; +trace_mark (mm_handle_fault_entry, +"address %lu ip #p%ld write_access %d" , + address,KSTK_EIP (current), write_access); +__set_current_state (TASK_RUNNING );count_vm_event (PGFAULT ); -if (unlikely (is_vm_hugetlb_page (vma))) -return hugetlb_fault (mm, vma, address, write_access); +if (unlikely (is_vm_hugetlb_page (vma))) { + res =hugetlb_fault (mm, vma, address, write_access); + goto end; + } pgd =pgd_offset (mm, address); pud =pud_alloc (mm, pgd, address); -if (!pud) -return VM_FAULT_OOM ; +if (!pud) { + res =VM_FAULT_OOM ; + goto end; + } pmd =pmd_alloc (mm, pud, address); -if (!pmd) -return VM_FAULT_OOM ; +if (!pmd) { + res =VM_FAULT_OOM ; + goto end; + } pte =pte_alloc_map (mm, pmd, address); -if (!pte) -return VM_FAULT_OOM ; +if (!pte) { + res =VM_FAULT_OOM ; + goto end; + } -return handle_pte_fault (mm, vma, address, pte, pmd, write_access); + res =handle_pte_fault (mm, vma, address, pte, pmd, write_access); +end: +trace_mark (mm_handle_fault_exit,MARK_NOARGS ); +return res; }#ifndef __PAGETABLE_PUD_FOLDED
mm/page_alloc.c +6 -0
@@ -518,6 +518,9 @@ static void __free_pages_ok(struct pageint i;int reserved =0 ; +trace_mark (mm_page_free,"order %u pfn %lu" , + order,page_to_pfn (page)); +for (i =0 ; i < (1 << order) ; ++i) reserved +=free_pages_check (page + i);if (reserved)
@@ -980,6 +983,8 @@ static void fastcall free_hot_cold_page(struct per_cpu_pages *pcp;unsigned long flags; +trace_mark (mm_page_free,"order %u pfn %lu" ,0 ,page_to_pfn (page)); +if (PageAnon (page)) page->mapping =NULL ;if (free_pages_check (page))
@@ -1624,6 +1629,7 @@ nopage:show_mem (); } got_pg: +trace_mark (mm_page_alloc,"order %u pfn %lu" , order,page_to_pfn (page));return page; }
mm/page_io.c +5 -0
@@ -114,6 +114,11 @@ int swap_writepage(struct page *page, st rw |= (1 <<BIO_RW_SYNC );count_vm_event (PSWPOUT );set_page_writeback (page); +trace_mark (mm_swap_out,"pfn %lu filp %p offset %lu" , +page_to_pfn (page), +get_swap_info_struct (swp_type ( +page_swp_entry (page)))->swap_file, +swp_offset (page_swp_entry (page)));unlock_page (page);submit_bio (rw, bio); out:
mm/hugetlb.c +2 -0
@@ -118,6 +118,7 @@ static void free_huge_page(struct page *int nid =page_to_nid (page);struct address_space *mapping; +trace_mark (mm_huge_page_free,"pfn %lu" ,page_to_pfn (page)); mapping = (struct address_space *)page_private (page);BUG_ON (page_count (page));INIT_LIST_HEAD (&page->lru);
@@ -401,6 +402,7 @@ static struct page *alloc_huge_page(struif (!IS_ERR (page)) {set_page_refcounted (page);set_page_private (page, (unsigned long ) mapping); +trace_mark (mm_huge_page_alloc,"pfn %lu" ,page_to_pfn (page)); }return page; }
include/linux/swapops.h +8 -0
@@ -68,6 +68,14 @@ static inline pte_t swp_entry_to_pte(swpreturn __swp_entry_to_pte (arch_entry); } +static inline swp_entry_t page_swp_entry (struct page *page) +{ +swp_entry_t entry; +VM_BUG_ON (!PageSwapCache (page)); + entry.val =page_private (page); +return entry; +} +#ifdef CONFIG_MIGRATION static inline swp_entry_t make_migration_entry (struct page *page,int write) {
mm/swapfile.c +22 -0
@@ -1279,6 +1279,7 @@ asmlinkage long sys_swapoff(const char _ swap_map = p->swap_map; p->swap_map =NULL ; p->flags =0 ; +trace_mark (mm_swap_file_close,"filp %p" , swap_file);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex);vfree (swap_map);
@@ -1660,6 +1661,8 @@ asmlinkage long sys_swapon(const char __ }else { swap_info[prev].next = p - swap_info; } +trace_mark (mm_swap_file_open,"filp %p filename %s" , + swap_file, name);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex); error =0 ;
@@ -1796,3 +1799,22 @@ int valid_swaphandles(swp_entry_t entry,spin_unlock (&swap_lock);return ret; } + +void ltt_dump_swap_files (void *call_data) +{ +int type; +struct swap_info_struct * p =NULL ; + +mutex_lock (&swapon_mutex); +for (type = swap_list.head; type >=0 ; type = swap_info[type].next) { + p = swap_info + type; +if ((p->flags &SWP_ACTIVE ) !=SWP_ACTIVE ) +continue ; +__trace_mark (0 , statedump_swap_files, call_data, +"filp %p vfsmount %p dname %s" , + p->swap_file, p->swap_file->f_vfsmnt, + p->swap_file->f_dentry->d_name.name); + } +mutex_unlock (&swapon_mutex); +} +EXPORT_SYMBOL_GPL (ltt_dump_swap_files);
Signature · 9 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/7 LTTng instrumentation net
In reply to Mathieu DesnoyersNetwork core events.
--- net/core/dev.c | 5 +++++ net/ipv4/devinet.c | 5 +++++ net/socket.c | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+)
net/core/dev.c +5 -0
@@ -1639,6 +1639,8 @@ int dev_queue_xmit(struct sk_buff *skb) } gso: +trace_mark (net_dev_xmit,"skb %p protocol #2u%hu" , skb, skb->protocol); +spin_lock_prefetch (&dev->queue_lock);/* Disable soft irqs for various locks below. Also
@@ -2039,6 +2041,9 @@ int netif_receive_skb(struct sk_buff *sk__get_cpu_var (netdev_rx_stat).total++; +trace_mark (net_dev_receive,"skb %p protocol #2u%hu" , + skb, skb->protocol); +skb_reset_network_header (skb);skb_reset_transport_header (skb); skb->mac_len = skb->network_header - skb->mac_header;
net/ipv4/devinet.c +5 -0
@@ -262,6 +262,8 @@ static void __inet_del_ifa(struct in_devstruct in_ifaddr **ifap1 = &ifa1->ifa_next;while ((ifa = *ifap1) !=NULL ) { +trace_mark (net_del_ifa_ipv4,"label %s" , + ifa->ifa_label);if (!(ifa->ifa_flags &IFA_F_SECONDARY ) && ifa1->ifa_scope <= ifa->ifa_scope) last_prim = ifa;
@@ -368,6 +370,9 @@ static int __inet_insert_ifa(struct in_i } ifa->ifa_flags |=IFA_F_SECONDARY ; } +trace_mark (net_insert_ifa_ipv4,"label %s address #4u%lu" , + ifa->ifa_label, + (unsigned long )ifa->ifa_address); }if (!(ifa->ifa_flags &IFA_F_SECONDARY )) {
net/socket.c +18 -0
@@ -563,6 +563,11 @@ int sock_sendmsg(struct socket *sock, ststruct sock_iocb siocb;int ret; +trace_mark (net_socket_sendmsg, +"sock %p family %d type %d protocol %d size %zu" , + sock, sock->sk->sk_family, sock->sk->sk_type, + sock->sk->sk_protocol, size); +init_sync_kiocb (&iocb,NULL ); iocb.private = &siocb; ret =__sock_sendmsg (&iocb, sock, msg, size);
@@ -646,7 +651,13 @@ int sock_recvmsg(struct socket *sock, ststruct sock_iocb siocb;int ret; +trace_mark (net_socket_recvmsg, +"sock %p family %d type %d protocol %d size %zu" , + sock, sock->sk->sk_family, sock->sk->sk_type, + sock->sk->sk_protocol, size); +init_sync_kiocb (&iocb,NULL ); + iocb.private = &siocb; ret =__sock_recvmsg (&iocb, sock, msg, size, flags);if (-EIOCBQUEUED == ret)
@@ -1212,6 +1223,11 @@ asmlinkage long sys_socket(int family, iif (retval <0 ) goto out_release; +trace_mark (net_socket_create, +"sock %p family %d type %d protocol %d fd %d" , + sock, sock->sk->sk_family, sock->sk->sk_type, + sock->sk->sk_protocol, retval); + out:/* It may be already another descriptor 8) Not kernel problem. */ return retval;
@@ -2021,6 +2037,8 @@ asmlinkage long sys_socketcall(int call, a0 = a[0 ]; a1 = a[1 ]; +trace_mark (net_socket_call,"call %d a0 %lu" , call, a0); +switch (call) {case SYS_SOCKET : err =sys_socket (a0, a1, a[2 ]);
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 7/7 Add Markers Into Semaphore Primitives
In reply to Mathieu DesnoyersThis patch adds several markers around semaphore primitives. Along with a tracing application this patch can be useful for measuring kernel semaphore usage and contention.
--- lib/semaphore-sleepers.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
lib/semaphore-sleepers.c +9 -0
@@ -15,6 +15,7 @@#include <linux/sched.h> #include <linux/err.h> #include <linux/init.h> +#include <linux/marker.h> #include <asm/semaphore.h> /*
@@ -50,6 +51,7 @@ fastcall void __up(struct semaphore *sem) { +trace_mark (sem_up,"%p" , sem);wake_up (&sem->wait); }
@@ -59,6 +61,7 @@ fastcall void __sched __down(struct semaphore * sem)DECLARE_WAITQUEUE (wait, tsk);unsigned long flags; +trace_mark (sem_down,"%p" , sem); tsk->state =TASK_UNINTERRUPTIBLE ;spin_lock_irqsave (&sem->wait.lock, flags);add_wait_queue_exclusive_locked (&sem->wait, &wait);
@@ -73,12 +76,14 @@ fastcall void __sched __down(struct semaphore * sem)* the wait_queue_head. */ if (!atomic_add_negative (sleepers -1 , &sem->count)) { +trace_mark (sem_down_resume,"%p" , sem); sem->sleepers =0 ;break ; } sem->sleepers =1 ;/* us - see -1 above */ spin_unlock_irqrestore (&sem->wait.lock, flags); +trace_mark (sem_down_sched,"%p" , sem);schedule ();spin_lock_irqsave (&sem->wait.lock, flags);
@@ -97,6 +102,7 @@ fastcall int __sched __down_interruptible(struct semaphore * sem)DECLARE_WAITQUEUE (wait, tsk);unsigned long flags; +trace_mark (sem_down_intr,"%p" , sem); tsk->state =TASK_INTERRUPTIBLE ;spin_lock_irqsave (&sem->wait.lock, flags);add_wait_queue_exclusive_locked (&sem->wait, &wait);
@@ -113,6 +119,7 @@ fastcall int __sched __down_interruptible(struct semaphore * sem)* and exit. */ if (signal_pending (current)) { +trace_mark (sem_down_intr_fail,"%p" , sem); retval = -EINTR ; sem->sleepers =0 ;atomic_add (sleepers, &sem->count);
@@ -126,12 +133,14 @@ fastcall int __sched __down_interruptible(struct semaphore * sem)* still hoping to get the semaphore. */ if (!atomic_add_negative (sleepers -1 , &sem->count)) { +trace_mark (sem_down_intr_resume,"%p" , sem); sem->sleepers =0 ;break ; } sem->sleepers =1 ;/* us - see -1 above */ spin_unlock_irqrestore (&sem->wait.lock, flags); +trace_mark (sem_down_intr_sched,"%p" , sem);schedule ();spin_lock_irqsave (&sem->wait.lock, flags);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68