Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763826AbYARRln (ORCPT ); Fri, 18 Jan 2008 12:41:43 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759846AbYARRlf (ORCPT ); Fri, 18 Jan 2008 12:41:35 -0500 Received: from pentafluge.infradead.org ([213.146.154.40]:47995 "EHLO pentafluge.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758742AbYARRlc (ORCPT ); Fri, 18 Jan 2008 12:41:32 -0500 Date: Fri, 18 Jan 2008 09:40:48 -0800 From: Arjan van de Ven To: Arjan van de Ven Cc: Linux Kernel Mailing List , Linus Torvalds , Ingo Molnar , Andrew Morton Subject: [patch 2/3] Latencytop instrumentations part 1 Message-ID: <20080118094048.10e79ff9@laptopd505.fenrus.org> In-Reply-To: <4790E3A6.7060807@linux.intel.com> References: <4790E3A6.7060807@linux.intel.com> Organization: Intel X-Mailer: Claws Mail 3.2.0 (GTK+ 2.12.3; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Bad-Reply: References and In-Reply-To but no 'Re:' in Subject. X-SRS-Rewrite: SMTP reverse-path rewritten from by pentafluge.infradead.org See http://www.infradead.org/rpr.html Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 28205 Lines: 957 This patch contains the first set of instrumentations for latencytop; each instrumentation needs to be evaluated for usefulness before this can go into mainline; posting here just to show how the infrastructure can be used --- arch/x86/mm/fault_64.c | 4 ++++ block/ll_rw_blk.c | 3 +++ drivers/scsi/hosts.c | 1 - drivers/scsi/scsi_error.c | 6 +++++- drivers/scsi/scsi_lib.c | 4 ++++ drivers/scsi/sd.c | 5 +++++ drivers/scsi/sr.c | 12 +++++++++++- fs/buffer.c | 22 +++++++++++++++++++++- fs/eventpoll.c | 5 +++++ fs/ext3/inode.c | 30 ++++++++++++++++++++++++++++-- fs/inode.c | 13 +++++++++++++ fs/jbd/checkpoint.c | 6 ++++++ fs/jbd/commit.c | 5 +++++ fs/jbd/journal.c | 5 +++++ fs/jbd/transaction.c | 13 +++++++++++++ fs/pipe.c | 5 +++++ fs/select.c | 3 +++ fs/sync.c | 19 +++++++++++++++++-- kernel/fork.c | 4 ++++ kernel/futex.c | 8 +++++++- kernel/mutex.c | 13 +++++++++++++ kernel/rwsem.c | 12 +++++++++++- mm/filemap.c | 6 ++++++ mm/slub.c | 7 ++++++- 24 files changed, 200 insertions(+), 11 deletions(-) Index: linux-2.6.24-rc7/arch/x86/mm/fault_64.c =================================================================== --- linux-2.6.24-rc7.orig/arch/x86/mm/fault_64.c +++ linux-2.6.24-rc7/arch/x86/mm/fault_64.c @@ -303,6 +303,7 @@ asmlinkage void __kprobes do_page_fault( int write, fault; unsigned long flags; siginfo_t info; + struct latency_entry reason; /* * We can fault from pretty much anywhere, with unknown IRQ state. @@ -441,7 +442,10 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ + + set_latency_reason("page fault", &reason); fault = handle_mm_fault(mm, vma, address, write); + restore_latency_reason(&reason); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; Index: linux-2.6.24-rc7/block/ll_rw_blk.c =================================================================== --- linux-2.6.24-rc7.orig/block/ll_rw_blk.c +++ linux-2.6.24-rc7/block/ll_rw_blk.c @@ -2190,7 +2190,9 @@ static struct request *get_request_wait( { const int rw = rw_flags & 0x01; struct request *rq; + struct latency_entry reason; + set_latency_reason("Waiting for a block layer request", &reason); rq = get_request(q, rw_flags, bio, GFP_NOIO); while (!rq) { DEFINE_WAIT(wait); @@ -2224,6 +2226,7 @@ static struct request *get_request_wait( finish_wait(&rl->wait[rw], &wait); } + restore_latency_reason(&reason); return rq; } Index: linux-2.6.24-rc7/drivers/scsi/scsi_error.c =================================================================== --- linux-2.6.24-rc7.orig/drivers/scsi/scsi_error.c +++ linux-2.6.24-rc7/drivers/scsi/scsi_error.c @@ -228,11 +227,16 @@ void scsi_times_out(struct scsi_cmnd *sc int scsi_block_when_processing_errors(struct scsi_device *sdev) { int online; + struct latency_entry reason; + + set_latency_reason("SCSI block due to error recovery", &reason); wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host)); online = scsi_device_online(sdev); + restore_latency_reason(&reason); + SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __FUNCTION__, online)); Index: linux-2.6.24-rc7/drivers/scsi/scsi_lib.c =================================================================== --- linux-2.6.24-rc7.orig/drivers/scsi/scsi_lib.c +++ linux-2.6.24-rc7/drivers/scsi/scsi_lib.c @@ -183,6 +183,9 @@ int scsi_execute(struct scsi_device *sde struct request *req; int write = (data_direction == DMA_TO_DEVICE); int ret = DRIVER_ERROR << 24; + struct latency_entry reason; + + set_latency_reason("SCSI layer command execute", &reason); req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); @@ -208,6 +211,7 @@ int scsi_execute(struct scsi_device *sde out: blk_put_request(req); + restore_latency_reason(&reason); return ret; } EXPORT_SYMBOL(scsi_execute); Index: linux-2.6.24-rc7/drivers/scsi/sd.c =================================================================== --- linux-2.6.24-rc7.orig/drivers/scsi/sd.c +++ linux-2.6.24-rc7/drivers/scsi/sd.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -796,10 +797,13 @@ static int sd_sync_cache(struct scsi_dis int retries, res; struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr sshdr; + struct latency_entry reason; if (!scsi_device_online(sdp)) return -ENODEV; + set_latency_reason("SCSI disk cache synchronize", &reason); + for (retries = 3; retries > 0; --retries) { unsigned char cmd[10] = { 0 }; @@ -821,6 +825,7 @@ static int sd_sync_cache(struct scsi_dis sd_print_sense_hdr(sdkp, &sshdr); } + restore_latency_reason(&reason); if (res) return -EIO; return 0; Index: linux-2.6.24-rc7/drivers/scsi/sr.c =================================================================== --- linux-2.6.24-rc7.orig/drivers/scsi/sr.c +++ linux-2.6.24-rc7/drivers/scsi/sr.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -468,6 +469,7 @@ static int sr_block_ioctl(struct inode * struct scsi_device *sdev = cd->device; void __user *argp = (void __user *)arg; int ret; + struct latency_entry reason; /* * Send SCSI addressing ioctls directly to mid level, send other @@ -479,7 +481,9 @@ static int sr_block_ioctl(struct inode * return scsi_ioctl(sdev, cmd, argp); } + set_latency_reason("SCSI cdrom ioctl", &reason); ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); + restore_latency_reason(&reason); if (ret != -ENOSYS) return ret; @@ -489,10 +493,16 @@ static int sr_block_ioctl(struct inode * * case fall through to scsi_ioctl, which will return ENDOEV again * if it doesn't recognise the ioctl */ + set_latency_reason("SCSI nonblockable ioctl", &reason); ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL); + restore_latency_reason(&reason); if (ret != -ENODEV) return ret; - return scsi_ioctl(sdev, cmd, argp); + set_latency_reason("SCSI ioctl", &reason); + ret = scsi_ioctl(sdev, cmd, argp); + restore_latency_reason(&reason); + + return ret; } static int sr_block_media_changed(struct gendisk *disk) Index: linux-2.6.24-rc7/fs/buffer.c =================================================================== --- linux-2.6.24-rc7.orig/fs/buffer.c +++ linux-2.6.24-rc7/fs/buffer.c @@ -41,6 +41,7 @@ #include #include #include +#include static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); @@ -69,8 +70,11 @@ static int sync_buffer(void *word) void fastcall __lock_buffer(struct buffer_head *bh) { + struct latency_entry reason; + set_latency_reason("Locking buffer head", &reason); wait_on_bit_lock(&bh->b_state, BH_Lock, sync_buffer, TASK_UNINTERRUPTIBLE); + restore_latency_reason(&reason); } EXPORT_SYMBOL(__lock_buffer); @@ -89,7 +93,10 @@ void fastcall unlock_buffer(struct buffe */ void __wait_on_buffer(struct buffer_head * bh) { + struct latency_entry reason; + set_latency_reason("Waiting for buffer IO", &reason); wait_on_bit(&bh->b_state, BH_Lock, sync_buffer, TASK_UNINTERRUPTIBLE); + restore_latency_reason(&reason); } static void @@ -606,6 +613,9 @@ static int osync_buffers_list(spinlock_t struct buffer_head *bh; struct list_head *p; int err = 0; + struct latency_entry reason; + + set_latency_reason("(O)sync the buffer list", &reason); spin_lock(lock); repeat: @@ -623,6 +633,7 @@ repeat: } } spin_unlock(lock); + restore_latency_reason(&reason); return err; } @@ -1208,19 +1219,25 @@ void __bforget(struct buffer_head *bh) static struct buffer_head *__bread_slow(struct buffer_head *bh) { + struct latency_entry reason; + set_latency_reason("Synchronous bufferhead read", &reason); lock_buffer(bh); if (buffer_uptodate(bh)) { unlock_buffer(bh); + restore_latency_reason(&reason); return bh; } else { get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(READ, bh); wait_on_buffer(bh); - if (buffer_uptodate(bh)) + if (buffer_uptodate(bh)) { + restore_latency_reason(&reason); return bh; + } } brelse(bh); + restore_latency_reason(&reason); return NULL; } @@ -2973,6 +2990,8 @@ void ll_rw_block(int rw, int nr, struct int sync_dirty_buffer(struct buffer_head *bh) { int ret = 0; + struct latency_entry reason; + set_latency_reason("syncing diry buffer", &reason); WARN_ON(atomic_read(&bh->b_count) < 1); lock_buffer(bh); @@ -2990,6 +3009,7 @@ int sync_dirty_buffer(struct buffer_head } else { unlock_buffer(bh); } + restore_latency_reason(&reason); return ret; } Index: linux-2.6.24-rc7/fs/eventpoll.c =================================================================== --- linux-2.6.24-rc7.orig/fs/eventpoll.c +++ linux-2.6.24-rc7/fs/eventpoll.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1219,6 +1220,7 @@ asmlinkage long sys_epoll_wait(int epfd, int error; struct file *file; struct eventpoll *ep; + struct latency_entry reason; DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n", current, epfd, events, maxevents, timeout)); @@ -1227,6 +1229,8 @@ asmlinkage long sys_epoll_wait(int epfd, if (maxevents <= 0 || maxevents > EP_MAX_EVENTS) return -EINVAL; + set_latency_reason_user("Waiting for event (epoll)", &reason, 5000); + /* Verify that the area passed by the user is writeable */ if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) { error = -EFAULT; @@ -1262,6 +1266,7 @@ error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n", current, epfd, events, maxevents, timeout, error)); + restore_latency_reason(&reason); return error; } Index: linux-2.6.24-rc7/fs/ext3/inode.c =================================================================== --- linux-2.6.24-rc7.orig/fs/ext3/inode.c +++ linux-2.6.24-rc7/fs/ext3/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "xattr.h" #include "acl.h" @@ -357,7 +358,9 @@ static Indirect *ext3_get_branch(struct struct super_block *sb = inode->i_sb; Indirect *p = chain; struct buffer_head *bh; + struct latency_entry reason; + set_latency_reason("EXT3 - reading indirect blocks", &reason); *err = 0; /* i_data is not going away, no lock needed */ add_chain (chain, NULL, EXT3_I(inode)->i_data + *offsets); @@ -375,6 +378,7 @@ static Indirect *ext3_get_branch(struct if (!p->key) goto no_block; } + restore_latency_reason(&reason); return NULL; changed: @@ -384,6 +388,7 @@ changed: failure: *err = -EIO; no_block: + restore_latency_reason(&reason); return p; } @@ -1255,6 +1260,9 @@ static int ext3_ordered_write_end(struct struct inode *inode = file->f_mapping->host; unsigned from, to; int ret = 0, ret2; + struct latency_entry reason; + + set_latency_reason("EXT3 ordered write", &reason); from = pos & (PAGE_CACHE_SIZE - 1); to = from + len; @@ -1284,6 +1292,8 @@ static int ext3_ordered_write_end(struct unlock_page(page); page_cache_release(page); + restore_latency_reason(&reason); + return ret ? ret : copied; } @@ -1641,14 +1651,25 @@ out_unlock: static int ext3_readpage(struct file *file, struct page *page) { - return mpage_readpage(page, ext3_get_block); + int ret; + struct latency_entry reason; + set_latency_reason("EXT3 readpage", &reason); + ret = mpage_readpage(page, ext3_get_block); + restore_latency_reason(&reason); + return ret; } static int ext3_readpages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { - return mpage_readpages(mapping, pages, nr_pages, ext3_get_block); + int ret; + struct latency_entry reason; + set_latency_reason("EXT3 readpages", &reason); + ret = mpage_readpages(mapping, pages, nr_pages, ext3_get_block); + restore_latency_reason(&reason); + + return ret; } static void ext3_invalidatepage(struct page *page, unsigned long offset) @@ -2665,6 +2686,9 @@ void ext3_read_inode(struct inode * inod struct ext3_inode_info *ei = EXT3_I(inode); struct buffer_head *bh; int block; + struct latency_entry reason; + + set_latency_reason("EXT3 reading inode", &reason); #ifdef CONFIG_EXT3_FS_POSIX_ACL ei->i_acl = EXT3_ACL_NOT_CACHED; @@ -2787,10 +2811,12 @@ void ext3_read_inode(struct inode * inod } brelse (iloc.bh); ext3_set_inode_flags(inode); + restore_latency_reason(&reason); return; bad_inode: make_bad_inode(inode); + restore_latency_reason(&reason); return; } Index: linux-2.6.24-rc7/fs/inode.c =================================================================== --- linux-2.6.24-rc7.orig/fs/inode.c +++ linux-2.6.24-rc7/fs/inode.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * This is needed for the following functions: @@ -1202,6 +1203,7 @@ void touch_atime(struct vfsmount *mnt, s { struct inode *inode = dentry->d_inode; struct timespec now; + struct latency_entry reason; if (inode->i_flags & S_NOATIME) return; @@ -1237,8 +1239,10 @@ void touch_atime(struct vfsmount *mnt, s if (timespec_equal(&inode->i_atime, &now)) return; + set_latency_reason("updating atime", &reason); inode->i_atime = now; mark_inode_dirty_sync(inode); + restore_latency_reason(&reason); } EXPORT_SYMBOL(touch_atime); @@ -1314,13 +1318,22 @@ int inode_wait(void *word) static void __wait_on_freeing_inode(struct inode *inode) { wait_queue_head_t *wq; + char buffer[32]; + struct latency_entry reason; DEFINE_WAIT_BIT(wait, &inode->i_state, __I_LOCK); + + sprintf(buffer, "%x:%x %lu %lx", MAJOR(inode->i_sb->s_dev), + MINOR(inode->i_sb->s_dev), inode->i_ino, inode->i_state); + + set_latency_reason_param("Waiting for file delete to complete", + buffer, &reason); wq = bit_waitqueue(&inode->i_state, __I_LOCK); prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); spin_unlock(&inode_lock); schedule(); finish_wait(wq, &wait.wait); spin_lock(&inode_lock); + restore_latency_reason(&reason); } /* Index: linux-2.6.24-rc7/fs/jbd/checkpoint.c =================================================================== --- linux-2.6.24-rc7.orig/fs/jbd/checkpoint.c +++ linux-2.6.24-rc7/fs/jbd/checkpoint.c @@ -301,9 +301,11 @@ int log_do_checkpoint(journal_t *journal transaction_t *transaction; tid_t this_tid; int result; + struct latency_entry reason; jbd_debug(1, "Start checkpoint\n"); + /* * First thing: if there are any transactions in the log which * don't need checkpointing, just eliminate them from the @@ -314,6 +316,8 @@ int log_do_checkpoint(journal_t *journal if (result <= 0) return result; + set_latency_reason("EXT3 (jbd) checkpointing", &reason); + /* * OK, we need to start writing disk blocks. Take one transaction * and write it. @@ -375,6 +379,8 @@ restart: out: spin_unlock(&journal->j_list_lock); result = cleanup_journal_tail(journal); + + restore_latency_reason(&reason); if (result < 0) return result; return 0; Index: linux-2.6.24-rc7/fs/jbd/commit.c =================================================================== --- linux-2.6.24-rc7.orig/fs/jbd/commit.c +++ linux-2.6.24-rc7/fs/jbd/commit.c @@ -104,6 +104,7 @@ static int journal_write_commit_record(j { struct journal_head *descriptor; struct buffer_head *bh; + struct latency_entry reason; int i, ret; int barrier_done = 0; @@ -129,6 +130,9 @@ static int journal_write_commit_record(j if (journal->j_flags & JFS_BARRIER) { set_buffer_ordered(bh); barrier_done = 1; + set_latency_reason("Writing commit block (barrier)", &reason); + } else { + set_latency_reason("Writing commit block", &reason); } ret = sync_dirty_buffer(bh); /* is it possible for another commit to fail at roughly @@ -156,6 +160,7 @@ static int journal_write_commit_record(j put_bh(bh); /* One for getblk() */ journal_put_journal_head(descriptor); + restore_latency_reason(&reason); return (ret == -EIO); } Index: linux-2.6.24-rc7/fs/jbd/journal.c =================================================================== --- linux-2.6.24-rc7.orig/fs/jbd/journal.c +++ linux-2.6.24-rc7/fs/jbd/journal.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -1335,6 +1336,9 @@ int journal_flush(journal_t *journal) int err = 0; transaction_t *transaction = NULL; unsigned long old_tail; + struct latency_entry reason; + + set_latency_reason("EXT3 (jbd) flushing journal", &reason); spin_lock(&journal->j_state_lock); @@ -1384,6 +1388,7 @@ int journal_flush(journal_t *journal) J_ASSERT(journal->j_head == journal->j_tail); J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence); spin_unlock(&journal->j_state_lock); + restore_latency_reason(&reason); return err; } Index: linux-2.6.24-rc7/fs/jbd/transaction.c =================================================================== --- linux-2.6.24-rc7.orig/fs/jbd/transaction.c +++ linux-2.6.24-rc7/fs/jbd/transaction.c @@ -25,6 +25,7 @@ #include #include #include +#include static void __journal_temp_unlink_buffer(struct journal_head *jh); @@ -85,6 +86,9 @@ static int start_this_handle(journal_t * int nblocks = handle->h_buffer_credits; transaction_t *new_transaction = NULL; int ret = 0; + struct latency_entry reason; + + set_latency_reason("EXT3 (jbd) journal transaction", &reason); if (nblocks > journal->j_max_transaction_buffers) { printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", @@ -229,6 +233,7 @@ repeat_locked: out: if (unlikely(new_transaction)) /* It's usually NULL */ kfree(new_transaction); + restore_latency_reason(&reason); return ret; } @@ -431,6 +436,9 @@ int journal_restart(handle_t *handle, in void journal_lock_updates(journal_t *journal) { DEFINE_WAIT(wait); + struct latency_entry reason; + + set_latency_reason("EXT3 (jbd) transaction barrier", &reason); spin_lock(&journal->j_state_lock); ++journal->j_barrier_count; @@ -464,6 +472,7 @@ void journal_lock_updates(journal_t *jou * too. */ mutex_lock(&journal->j_barrier); + restore_latency_reason(&reason); } /** @@ -535,10 +544,13 @@ do_get_write_access(handle_t *handle, st int error; char *frozen_buffer = NULL; int need_copy = 0; + struct latency_entry reason; if (is_handle_aborted(handle)) return -EROFS; + set_latency_reason("EXT3 (jbd) do_get_write_access", &reason); + transaction = handle->h_transaction; journal = transaction->t_journal; @@ -737,6 +749,7 @@ out: jbd_free(frozen_buffer, bh->b_size); JBUFFER_TRACE(jh, "exit"); + restore_latency_reason(&reason); return error; } Index: linux-2.6.24-rc7/fs/pipe.c =================================================================== --- linux-2.6.24-rc7.orig/fs/pipe.c +++ linux-2.6.24-rc7/fs/pipe.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -402,12 +403,15 @@ pipe_write(struct kiocb *iocb, const str struct iovec *iov = (struct iovec *)_iov; size_t total_len; ssize_t chars; + struct latency_entry reason; total_len = iov_length(iov, nr_segs); /* Null write succeeds. */ if (unlikely(total_len == 0)) return 0; + set_latency_reason("writing to a pipe", &reason); + do_wakeup = 0; ret = 0; mutex_lock(&inode->i_mutex); @@ -560,6 +564,7 @@ out: } if (ret > 0) file_update_time(filp); + restore_latency_reason(&reason); return ret; } Index: linux-2.6.24-rc7/fs/select.c =================================================================== --- linux-2.6.24-rc7.orig/fs/select.c +++ linux-2.6.24-rc7/fs/select.c @@ -186,6 +186,7 @@ int do_select(int n, fd_set_bits *fds, s struct poll_wqueues table; poll_table *wait; int retval, i; + struct latency_entry reason; rcu_read_lock(); retval = max_select_fd(n, fds); @@ -195,6 +196,7 @@ int do_select(int n, fd_set_bits *fds, s return retval; n = retval; + set_latency_reason_user("Waiting for event (select)", &reason, 5000); poll_initwait(&table); wait = &table.pt; if (!*timeout) @@ -284,6 +286,7 @@ int do_select(int n, fd_set_bits *fds, s poll_freewait(&table); + restore_latency_reason(&reason); return retval; } Index: linux-2.6.24-rc7/fs/sync.c =================================================================== --- linux-2.6.24-rc7.orig/fs/sync.c +++ linux-2.6.24-rc7/fs/sync.c @@ -13,6 +13,7 @@ #include #include #include +#include #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ SYNC_FILE_RANGE_WAIT_AFTER) @@ -38,7 +39,11 @@ static void do_sync(unsigned long wait) asmlinkage long sys_sync(void) { + struct latency_entry reason; + set_latency_reason("sync system call", &reason); do_sync(1); + restore_latency_reason(&reason); + return 0; } @@ -120,12 +125,22 @@ static long __do_fsync(unsigned int fd, asmlinkage long sys_fsync(unsigned int fd) { - return __do_fsync(fd, 0); + long ret; + struct latency_entry reason; + set_latency_reason("fsync system call", &reason); + ret = __do_fsync(fd, 0); + restore_latency_reason(&reason); + return ret; } asmlinkage long sys_fdatasync(unsigned int fd) { - return __do_fsync(fd, 1); + long ret; + struct latency_entry reason; + set_latency_reason("fdatasync system call", &reason); + ret = __do_fsync(fd, 1); + restore_latency_reason(&reason); + return ret; } /* Index: linux-2.6.24-rc7/kernel/fork.c =================================================================== --- linux-2.6.24-rc7.orig/kernel/fork.c +++ linux-2.6.24-rc7/kernel/fork.c @@ -1411,6 +1411,9 @@ long do_fork(unsigned long clone_flags, struct task_struct *p; int trace = 0; long nr; + struct latency_entry reason; + + set_latency_reason("process fork", &reason); if (unlikely(current->ptrace)) { trace = fork_traceflag (clone_flags); @@ -1473,6 +1476,7 @@ long do_fork(unsigned long clone_flags, } else { nr = PTR_ERR(p); } + restore_latency_reason(&reason); return nr; } Index: linux-2.6.24-rc7/kernel/futex.c =================================================================== --- linux-2.6.24-rc7.orig/kernel/futex.c +++ linux-2.6.24-rc7/kernel/futex.c @@ -2051,9 +2051,11 @@ asmlinkage long sys_futex(u32 __user *ua u32 val3) { struct timespec ts; + long ret; ktime_t t, *tp = NULL; u32 val2 = 0; int cmd = op & FUTEX_CMD_MASK; + struct latency_entry reason; if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) { if (copy_from_user(&ts, utime, sizeof(ts)) != 0) @@ -2074,7 +2076,11 @@ asmlinkage long sys_futex(u32 __user *ua cmd == FUTEX_WAKE_OP) val2 = (u32) (unsigned long) utime; - return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); + set_latency_reason_user("Userspace lock contention (futex)", + &reason, 5000); + ret = do_futex(uaddr, op, val, tp, uaddr2, val2, val3); + restore_latency_reason(&reason); + return ret; } static int futexfs_get_sb(struct file_system_type *fs_type, Index: linux-2.6.24-rc7/kernel/mutex.c =================================================================== --- linux-2.6.24-rc7.orig/kernel/mutex.c +++ linux-2.6.24-rc7/kernel/mutex.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * In the DEBUG case we are using the "NULL fastpath" for mutexes, @@ -298,8 +299,20 @@ static void fastcall noinline __sched __mutex_lock_slowpath(atomic_t *lock_count) { struct mutex *lock = container_of(lock_count, struct mutex, count); + struct latency_entry reason; +#ifdef CONFIG_DEBUG_MUTEXES + /* do something with ->owner here */ +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC + char *name; + name = lock->dep_map.name; + set_latency_reason_param("mutex lock", name, &reason); +#else + set_latency_reason("mutex lock", &reason); +#endif __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, _RET_IP_); + restore_latency_reason(&reason); } static int fastcall noinline __sched Index: linux-2.6.24-rc7/kernel/rwsem.c =================================================================== --- linux-2.6.24-rc7.orig/kernel/rwsem.c +++ linux-2.6.24-rc7/kernel/rwsem.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -18,10 +19,15 @@ */ void __sched down_read(struct rw_semaphore *sem) { + struct latency_entry reason; + might_sleep(); - rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); + set_latency_reason("rwsem read lock", &reason); + rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(sem, __down_read_trylock, __down_read); + + restore_latency_reason(&reason); } EXPORT_SYMBOL(down_read); @@ -45,10 +51,14 @@ EXPORT_SYMBOL(down_read_trylock); */ void __sched down_write(struct rw_semaphore *sem) { + struct latency_entry reason; + set_latency_reason("rwsem write lock", &reason); might_sleep(); + rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(sem, __down_write_trylock, __down_write); + restore_latency_reason(&reason); } EXPORT_SYMBOL(down_write); Index: linux-2.6.24-rc7/mm/filemap.c =================================================================== --- linux-2.6.24-rc7.orig/mm/filemap.c +++ linux-2.6.24-rc7/mm/filemap.c @@ -525,10 +525,13 @@ static inline void wake_up_page(struct p void fastcall wait_on_page_bit(struct page *page, int bit_nr) { DEFINE_WAIT_BIT(wait, &page->flags, bit_nr); + struct latency_entry reason; + set_latency_reason("Waiting for page IO/lock", &reason); if (test_bit(bit_nr, &page->flags)) __wait_on_bit(page_waitqueue(page), &wait, sync_page, TASK_UNINTERRUPTIBLE); + restore_latency_reason(&reason); } EXPORT_SYMBOL(wait_on_page_bit); @@ -583,9 +586,12 @@ EXPORT_SYMBOL(end_page_writeback); void fastcall __lock_page(struct page *page) { DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); + struct latency_entry reason; + set_latency_reason("locking page", &reason); __wait_on_bit_lock(page_waitqueue(page), &wait, sync_page, TASK_UNINTERRUPTIBLE); + restore_latency_reason(&reason); } EXPORT_SYMBOL(__lock_page); Index: linux-2.6.24-rc7/mm/slub.c =================================================================== --- linux-2.6.24-rc7.orig/mm/slub.c +++ linux-2.6.24-rc7/mm/slub.c @@ -1566,7 +1566,12 @@ static void __always_inline *slab_alloc( void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) { - return slab_alloc(s, gfpflags, -1, __builtin_return_address(0)); + void *ptr; + struct latency_entry reason; + set_latency_reason("Allocating slab memory", &reason); + ptr = slab_alloc(s, gfpflags, -1, __builtin_return_address(0)); + restore_latency_reason(&reason); + return ptr; } EXPORT_SYMBOL(kmem_cache_alloc); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/