ANDROID: fs: Refactor FS readpage/write tracepoints.
authorMohan Srinivasan <srmohan@google.com>
Fri, 10 Feb 2017 22:26:23 +0000 (14:26 -0800)
committerAmit Pundir <amit.pundir@linaro.org>
Mon, 18 Dec 2017 15:41:22 +0000 (21:11 +0530)
Refactor the fs readpage/write tracepoints to move the
inode->path lookup outside the tracepoint code, and pass a pointer
to the path into the tracepoint code instead. This is necessary
because the tracepoint code runs non-preemptible. Thanks to
Trilok Soni for catching this in 4.4.

Signed-off-by: Mohan Srinivasan <srmohan@google.com>
[AmitP: Folded following android-4.9 commit changes into this patch
        a5c4dbb05ab7 ("ANDROID: Replace spaces by '_' for some android filesystem tracepoints.")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/readpage.c
fs/f2fs/data.c
fs/f2fs/inline.c
fs/mpage.c
include/trace/events/android_fs.h
include/trace/events/android_fs_template.h

index ddfc3bbcd4dea13d589346c0f6ffad5bdc1d6454..724a983aa17d03d0e26cce69503bbeeb3c89321f 100644 (file)
@@ -515,8 +515,16 @@ int ext4_readpage_inline(struct inode *inode, struct page *page)
                return -EAGAIN;
        }
 
-       trace_android_fs_dataread_start(inode, page_offset(page), PAGE_SIZE,
-                                       current->pid, current->comm);
+       if (trace_android_fs_dataread_start_enabled()) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
+               trace_android_fs_dataread_start(inode, page_offset(page),
+                                               PAGE_SIZE, current->pid,
+                                               path, current->comm);
+       }
 
        /*
         * Current inline data can only exist in the 1st page,
index d5c7b206e5af7061cf70a41af3777ee7e4583b67..8d15bbe667754a724edf0e5c1d83a8fd809444c0 100644 (file)
@@ -1244,8 +1244,16 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
        if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
                return -EIO;
 
-       trace_android_fs_datawrite_start(inode, pos, len,
-                                        current->pid, current->comm);
+       if (trace_android_fs_datawrite_start_enabled()) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
+               trace_android_fs_datawrite_start(inode, pos, len,
+                                                current->pid, path,
+                                                current->comm);
+       }
        trace_ext4_write_begin(inode, pos, len, flags);
        /*
         * Reserve one block more for addition to orphan list in case
@@ -3029,8 +3037,16 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
                                        len, flags, pagep, fsdata);
        }
        *fsdata = (void *)0;
-       trace_android_fs_datawrite_start(inode, pos, len,
-                                        current->pid, current->comm);
+       if (trace_android_fs_datawrite_start_enabled()) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
+               trace_android_fs_datawrite_start(inode, pos, len,
+                                                current->pid,
+                                                path, current->comm);
+       }
        trace_ext4_da_write_begin(inode, pos, len, flags);
 
        if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
@@ -3810,16 +3826,27 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                return 0;
 
        if (trace_android_fs_dataread_start_enabled() &&
-           (rw == READ))
+           (rw == READ)) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
                trace_android_fs_dataread_start(inode, offset, count,
-                                               current->pid,
+                                               current->pid, path,
                                                current->comm);
+       }
        if (trace_android_fs_datawrite_start_enabled() &&
-           (rw == WRITE))
+           (rw == WRITE)) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
                trace_android_fs_datawrite_start(inode, offset, count,
-                                                current->pid,
+                                                current->pid, path,
                                                 current->comm);
-
+       }
        trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));
        if (iov_iter_rw(iter) == READ)
                ret = ext4_direct_IO_read(iocb, iter);
index bda47851a9d3905e8667e7d20e4bdae6aaff3d3e..df22fcb3c41c2922fdf94602f3e412290fbb932b 100644 (file)
@@ -118,11 +118,17 @@ ext4_submit_bio_read(struct bio *bio)
                struct page *first_page = bio->bi_io_vec[0].bv_page;
 
                if (first_page != NULL) {
+                       char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+                       path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   first_page->mapping->host);
                        trace_android_fs_dataread_start(
                                first_page->mapping->host,
                                page_offset(first_page),
                                bio->bi_iter.bi_size,
                                current->pid,
+                               path,
                                current->comm);
                }
        }
index 21ec7c38904c6b7df620b8937128b0a3d64aa40e..f4741f016e2808b0723446db25c3bafa003f2e79 100644 (file)
@@ -1936,8 +1936,16 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
        block_t blkaddr = NULL_ADDR;
        int err = 0;
 
-       trace_android_fs_datawrite_start(inode, pos, len,
-                                        current->pid, current->comm);
+       if (trace_android_fs_datawrite_start_enabled()) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
+               trace_android_fs_datawrite_start(inode, pos, len,
+                                                current->pid, path,
+                                                current->comm);
+       }
        trace_f2fs_write_begin(inode, pos, len, flags);
 
        /*
@@ -2087,14 +2095,27 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
        trace_f2fs_direct_IO_enter(inode, offset, count, rw);
 
        if (trace_android_fs_dataread_start_enabled() &&
-           (rw == READ))
+           (rw == READ)) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
                trace_android_fs_dataread_start(inode, offset,
-                                               count, current->pid,
+                                               count, current->pid, path,
                                                current->comm);
+       }
        if (trace_android_fs_datawrite_start_enabled() &&
-           (rw == WRITE))
+           (rw == WRITE)) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
                trace_android_fs_datawrite_start(inode, offset, count,
-                                                current->pid, current->comm);
+                                                current->pid, path,
+                                                current->comm);
+       }
 
        down_read(&F2FS_I(inode)->dio_rwsem[rw]);
        err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
index f848eb3cdd979fe5751f31f52c8081ad7dafeafb..9fb5fdc6188826c603398997b3cb617316865eb1 100644 (file)
@@ -86,9 +86,16 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
 {
        struct page *ipage;
 
-       trace_android_fs_dataread_start(inode, page_offset(page),
-                                       PAGE_SIZE, current->pid,
-                                       current->comm);
+       if (trace_android_fs_dataread_start_enabled()) {
+               char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+               path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   inode);
+               trace_android_fs_dataread_start(inode, page_offset(page),
+                                               PAGE_SIZE, current->pid,
+                                               path, current->comm);
+       }
 
        ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
        if (IS_ERR(ipage)) {
index c31b6a48e6dc45892b4f9535881e9060beb6ef2b..93e3cf7bf27c7b524caf3f0f4584416452e98bee 100644 (file)
@@ -82,11 +82,17 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio)
                struct page *first_page = bio->bi_io_vec[0].bv_page;
 
                if (first_page != NULL) {
+                       char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
+
+                       path = android_fstrace_get_pathname(pathbuf,
+                                                   MAX_TRACE_PATHBUF_LEN,
+                                                   first_page->mapping->host);
                        trace_android_fs_dataread_start(
                                first_page->mapping->host,
                                page_offset(first_page),
                                bio->bi_iter.bi_size,
                                current->pid,
+                               path,
                                current->comm);
                }
        }
index 531da433a7bc8007f70993feb5527ad39b7ae936..49509533d3faab32355d7a3de8ec0fd00c7595d9 100644 (file)
@@ -9,8 +9,8 @@
 
 DEFINE_EVENT(android_fs_data_start_template, android_fs_dataread_start,
        TP_PROTO(struct inode *inode, loff_t offset, int bytes,
-                pid_t pid, char *command),
-       TP_ARGS(inode, offset, bytes, pid, command));
+                pid_t pid, char *pathname, char *command),
+       TP_ARGS(inode, offset, bytes, pid, pathname, command));
 
 DEFINE_EVENT(android_fs_data_end_template, android_fs_dataread_end,
        TP_PROTO(struct inode *inode, loff_t offset, int bytes),
@@ -18,14 +18,48 @@ DEFINE_EVENT(android_fs_data_end_template, android_fs_dataread_end,
 
 DEFINE_EVENT(android_fs_data_start_template, android_fs_datawrite_start,
        TP_PROTO(struct inode *inode, loff_t offset, int bytes,
-                pid_t pid, char *command),
-       TP_ARGS(inode, offset, bytes, pid, command));
+                pid_t pid, char *pathname, char *command),
+       TP_ARGS(inode, offset, bytes, pid, pathname, command));
 
 DEFINE_EVENT(android_fs_data_end_template, android_fs_datawrite_end,
        TP_PROTO(struct inode *inode, loff_t offset, int bytes),
-       TP_ARGS(inode, offset, bytes));
+            TP_ARGS(inode, offset, bytes));
 
 #endif /* _TRACE_ANDROID_FS_H */
 
 /* This part must be outside protection */
 #include <trace/define_trace.h>
+
+#ifndef ANDROID_FSTRACE_GET_PATHNAME
+#define ANDROID_FSTRACE_GET_PATHNAME
+
+/* Sizes an on-stack array, so careful if sizing this up ! */
+#define MAX_TRACE_PATHBUF_LEN  256
+
+static inline char *
+android_fstrace_get_pathname(char *buf, int buflen, struct inode *inode)
+{
+       char *path;
+       struct dentry *d;
+
+       /*
+        * d_obtain_alias() will either iput() if it locates an existing
+        * dentry or transfer the reference to the new dentry created.
+        * So get an extra reference here.
+        */
+       ihold(inode);
+       d = d_obtain_alias(inode);
+       if (likely(!IS_ERR(d))) {
+               path = dentry_path_raw(d, buf, buflen);
+               if (unlikely(IS_ERR(path))) {
+                       strcpy(buf, "ERROR");
+                       path = buf;
+               }
+               dput(d);
+       } else {
+               strcpy(buf, "ERROR");
+               path = buf;
+       }
+       return path;
+}
+#endif
index 618988b047c18b6cf10eb432f8841d342017c93c..b23d17b56c634359f7d1312969f5ef97b47aa781 100644 (file)
@@ -5,11 +5,10 @@
 
 DECLARE_EVENT_CLASS(android_fs_data_start_template,
        TP_PROTO(struct inode *inode, loff_t offset, int bytes,
-                pid_t pid, char *command),
-       TP_ARGS(inode, offset, bytes, pid, command),
+                pid_t pid, char *pathname, char *command),
+       TP_ARGS(inode, offset, bytes, pid, pathname, command),
        TP_STRUCT__entry(
-               __array(char, path, MAX_FILTER_STR_VAL);
-               __field(char *, pathname);
+               __string(pathbuf, pathname);
                __field(loff_t, offset);
                __field(int,    bytes);
                __field(loff_t, i_size);
@@ -19,40 +18,26 @@ DECLARE_EVENT_CLASS(android_fs_data_start_template,
        ),
        TP_fast_assign(
                {
-                       struct dentry *d;
-
                        /*
-                        * Grab a reference to the inode here because
-                        * d_obtain_alias() will either drop the inode
-                        * reference if it locates an existing dentry
-                        * or transfer the reference to the new dentry
-                        * created. In our case, the file is still open,
-                        * so the dentry is guaranteed to exist (connected),
-                        * so d_obtain_alias() drops the reference we
-                        * grabbed here.
+                        * Replace the spaces in filenames and cmdlines
+                        * because this screws up the tooling that parses
+                        * the traces.
                         */
-                       ihold(inode);
-                       d = d_obtain_alias(inode);
-                       if (!IS_ERR(d)) {
-                               __entry->pathname = dentry_path(d,
-                                                       __entry->path,
-                                                       MAX_FILTER_STR_VAL);
-                               dput(d);
-                       } else
-                               __entry->pathname = ERR_PTR(-EINVAL);
+                       __assign_str(pathbuf, pathname);
+                       (void)strreplace(__get_str(pathbuf), ' ', '_');
                        __entry->offset         = offset;
                        __entry->bytes          = bytes;
                        __entry->i_size         = i_size_read(inode);
                        __assign_str(cmdline, command);
+                       (void)strreplace(__get_str(cmdline), ' ', '_');
                        __entry->pid            = pid;
                        __entry->ino            = inode->i_ino;
                }
        ),
        TP_printk("entry_name %s, offset %llu, bytes %d, cmdline %s,"
                  " pid %d, i_size %llu, ino %lu",
-                 (IS_ERR(__entry->pathname) ? "ERROR" : __entry->pathname),
-                 __entry->offset, __entry->bytes, __get_str(cmdline),
-                 __entry->pid, __entry->i_size,
+                 __get_str(pathbuf), __entry->offset, __entry->bytes,
+                 __get_str(cmdline), __entry->pid, __entry->i_size,
                  (unsigned long) __entry->ino)
 );