[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080118094048.10e79ff9@laptopd505.fenrus.org>
Date: Fri, 18 Jan 2008 09:40:48 -0800
From: Arjan van de Ven <arjan@...radead.org>
To: Arjan van de Ven <arjan@...ux.intel.com>
Cc: Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Ingo Molnar <mingo@...e.hu>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: [patch 2/3] Latencytop instrumentations part 1
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 <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/latencytop.h>
#include <asm/uaccess.h>
#include <scsi/scsi.h>
@@ -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 <linux/init.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
+#include <linux/latencytop.h>
#include <asm/uaccess.h>
#include <scsi/scsi.h>
@@ -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 <linux/bitops.h>
#include <linux/mpage.h>
#include <linux/bit_spinlock.h>
+#include <linux/latencytop.h>
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 <linux/bitops.h>
#include <linux/mutex.h>
#include <linux/anon_inodes.h>
+#include <linux/latencytop.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -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 <linux/mpage.h>
#include <linux/uio.h>
#include <linux/bio.h>
+#include <linux/latencytop.h>
#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 <linux/bootmem.h>
#include <linux/inotify.h>
#include <linux/mount.h>
+#include <linux/latencytop.h>
/*
* 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 <linux/poison.h>
#include <linux/proc_fs.h>
#include <linux/debugfs.h>
+#include <linux/ioprio.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -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 <linux/timer.h>
#include <linux/mm.h>
#include <linux/highmem.h>
+#include <linux/latencytop.h>
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 <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/audit.h>
+#include <linux/latencytop.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -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 <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include <linux/latencytop.h>
#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 <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/debug_locks.h>
+#include <linux/latencytop.h>
/*
* 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 <linux/sched.h>
#include <linux/module.h>
#include <linux/rwsem.h>
+#include <linux/latencytop.h>
#include <asm/system.h>
#include <asm/atomic.h>
@@ -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@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists