]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
blktrace: add an option to allow displaying cgroup path
authorShaohua Li <shli@fb.com>
Wed, 12 Jul 2017 18:49:55 +0000 (11:49 -0700)
committerJens Axboe <axboe@kernel.dk>
Sat, 29 Jul 2017 15:00:03 +0000 (09:00 -0600)
By default we output cgroup id in blktrace. This adds an option to
display cgroup path. Since get cgroup path is a relativly heavy
operation, we don't enable it by default.

with the option enabled, blktrace will output something like this:
dd-1353  [007] d..2   293.015252:   8,0   /test/level  D   R 24 + 8 [dd]

Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/kernfs/mount.c
include/linux/cgroup.h
include/linux/kernfs.h
kernel/cgroup/cgroup.c
kernel/trace/blktrace.c

index fa323589704f828c808127304af1615ca0f3f6df..7c452f4d83e937e3d66def4841c7b693b0023551 100644 (file)
@@ -65,6 +65,25 @@ const struct super_operations kernfs_sops = {
        .show_path      = kernfs_sop_show_path,
 };
 
+/*
+ * Similar to kernfs_fh_get_inode, this one gets kernfs node from inode
+ * number and generation
+ */
+struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root,
+       const union kernfs_node_id *id)
+{
+       struct kernfs_node *kn;
+
+       kn = kernfs_find_and_get_node_by_ino(root, id->ino);
+       if (!kn)
+               return NULL;
+       if (kn->id.generation != id->generation) {
+               kernfs_put(kn);
+               return NULL;
+       }
+       return kn;
+}
+
 static struct inode *kernfs_fh_get_inode(struct super_block *sb,
                u64 ino, u32 generation)
 {
index 52ef9a68ff14c438db1256aedd97701f0094a65f..6144fe923b73b5d29285a1c74a5c42fd0912d32d 100644 (file)
@@ -613,6 +613,9 @@ static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp)
 {
        return &cgrp->kn->id;
 }
+
+void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
+                                       char *buf, size_t buflen);
 #else /* !CONFIG_CGROUPS */
 
 struct cgroup_subsys_state;
@@ -645,6 +648,9 @@ static inline bool task_under_cgroup_hierarchy(struct task_struct *task,
 {
        return true;
 }
+
+static inline void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
+       char *buf, size_t buflen) {}
 #endif /* !CONFIG_CGROUPS */
 
 /*
index d149361e58756d0ea93deb014121e965a3fe8097..ab25c8b6d9e33d84bbaca9410af75339fa94385b 100644 (file)
@@ -358,6 +358,8 @@ struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns);
 
 void kernfs_init(void);
 
+struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root,
+       const union kernfs_node_id *id);
 #else  /* CONFIG_KERNFS */
 
 static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
index 6cefa277f39c61b3ad1004bec9331bd2e883f317..2aba1c519138c2f2a61eef51dcd7ce8283cac5e9 100644 (file)
@@ -4701,6 +4701,18 @@ static int __init cgroup_wq_init(void)
 }
 core_initcall(cgroup_wq_init);
 
+void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
+                                       char *buf, size_t buflen)
+{
+       struct kernfs_node *kn;
+
+       kn = kernfs_get_node_by_id(cgrp_dfl_root.kf_root, id);
+       if (!kn)
+               return;
+       kernfs_path(kn, buf, buflen);
+       kernfs_put(kn);
+}
+
 /*
  * proc_cgroup_show()
  *  - Print task's cgroup paths into seq_file, one line for each hierarchy
index f393d7a43695e4c142605354e89139d332a87594..e90974ed4532748d5f3467e445254b13f8f8545c 100644 (file)
@@ -48,12 +48,14 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(running_trace_lock);
 /* Select an alternative, minimalistic output than the original one */
 #define TRACE_BLK_OPT_CLASSIC  0x1
 #define TRACE_BLK_OPT_CGROUP   0x2
+#define TRACE_BLK_OPT_CGNAME   0x4
 
 static struct tracer_opt blk_tracer_opts[] = {
        /* Default disable the minimalistic output */
        { TRACER_OPT(blk_classic, TRACE_BLK_OPT_CLASSIC) },
 #ifdef CONFIG_BLK_CGROUP
        { TRACER_OPT(blk_cgroup, TRACE_BLK_OPT_CGROUP) },
+       { TRACER_OPT(blk_cgname, TRACE_BLK_OPT_CGNAME) },
 #endif
        { }
 };
@@ -1213,7 +1215,17 @@ static void blk_log_action(struct trace_iterator *iter, const char *act,
        if (has_cg) {
                const union kernfs_node_id *id = cgid_start(iter->ent);
 
-               trace_seq_printf(&iter->seq, "%3d,%-3d %x,%-x %2s %3s ",
+               if (blk_tracer_flags.val & TRACE_BLK_OPT_CGNAME) {
+                       char blkcg_name_buf[NAME_MAX + 1] = "<...>";
+
+                       cgroup_path_from_kernfs_id(id, blkcg_name_buf,
+                               sizeof(blkcg_name_buf));
+                       trace_seq_printf(&iter->seq, "%3d,%-3d %s %2s %3s ",
+                                MAJOR(t->device), MINOR(t->device),
+                                blkcg_name_buf, act, rwbs);
+               } else
+                       trace_seq_printf(&iter->seq,
+                                "%3d,%-3d %x,%-x %2s %3s ",
                                 MAJOR(t->device), MINOR(t->device),
                                 id->ino, id->generation, act, rwbs);
        } else