Linux-Fsdevel Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Eugene Lubarsky <elubarsky.linux@gmail.com>
To: linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, adobriyan@gmail.com,
	avagin@gmail.com, dsahern@gmail.com
Subject: [RFC PATCH 1/5] fs/proc: Introduce /proc/all/stat
Date: Tue, 11 Aug 2020 00:58:48 +1000	[thread overview]
Message-ID: <20200810145852.9330-2-elubarsky.linux@gmail.com> (raw)
In-Reply-To: <20200810145852.9330-1-elubarsky.linux@gmail.com>

Returns stat lines for all visible processes in the existing format,
aiming to substantially reduce the number of syscalls that are needed 
for this common task.

Signed-off-by: Eugene Lubarsky <elubarsky.linux@gmail.com>
---
 fs/proc/base.c     | 98 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/proc/internal.h |  1 +
 fs/proc/root.c     |  1 +
 3 files changed, 100 insertions(+)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index a333caeca291..e0f60a1528b7 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3811,3 +3811,101 @@ void __init set_proc_pid_nlink(void)
 	nlink_tid = pid_entry_nlink(tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
 	nlink_tgid = pid_entry_nlink(tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
 }
+
+
+/*
+ * /proc/all/
+ */
+
+struct all_iter {
+	struct tgid_iter tgid_iter;
+	struct proc_fs_info *fs_info;
+	struct pid_namespace *ns;
+};
+
+static void *proc_all_start(struct seq_file *m, loff_t *pos)
+{
+	struct all_iter *iter = kmalloc(sizeof(struct all_iter), GFP_KERNEL);
+
+	iter->fs_info = proc_sb_info(file_inode(m->file)->i_sb);
+	iter->ns = proc_pid_ns(file_inode(m->file)->i_sb);
+
+	iter->tgid_iter.tgid = *pos;
+	iter->tgid_iter.task = NULL;
+	iter->tgid_iter = next_tgid(iter->ns, iter->tgid_iter);
+
+	if (!iter->tgid_iter.task) {
+		kfree(iter);
+		return NULL;
+	}
+
+	return iter;
+}
+
+static void *proc_all_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct all_iter *iter = (struct all_iter *) v;
+	struct proc_fs_info *fs_info = iter->fs_info;
+	struct tgid_iter *tgid_iter = &iter->tgid_iter;
+
+	do {
+		tgid_iter->tgid += 1;
+		*tgid_iter = next_tgid(iter->ns, *tgid_iter);
+	} while (tgid_iter->task &&
+				!has_pid_permissions(fs_info, tgid_iter->task, HIDEPID_INVISIBLE));
+
+	*pos = tgid_iter->tgid;
+
+	if (!tgid_iter->task) {
+		kfree(v);
+		return NULL;
+	}
+
+	return iter;
+}
+
+static void proc_all_stop(struct seq_file *m, void *v)
+{
+	if (v) {
+		struct all_iter *iter = (struct all_iter *) v;
+		struct task_struct *task = iter->tgid_iter.task;
+
+		if (task)
+			put_task_struct(task);
+
+	  kfree(v);
+	}
+}
+
+static int proc_all_stat(struct seq_file *m, void *v)
+{
+	struct all_iter *iter = (struct all_iter *) v;
+
+	return proc_tgid_stat(m, iter->ns, iter->tgid_iter.task->thread_pid, iter->tgid_iter.task);
+}
+
+
+#define PROC_ALL_OPS(NAME) static const struct seq_operations proc_all_##NAME##_ops = { \
+	.start	= proc_all_start, \
+	.next	= proc_all_next, \
+	.stop	= proc_all_stop, \
+	.show	= proc_all_##NAME \
+}
+
+PROC_ALL_OPS(stat);
+
+#define PROC_ALL_CREATE(NAME) \
+	do { \
+		if (!proc_create_seq(#NAME, 0, all_dir, &proc_all_##NAME##_ops)) \
+			return; \
+	} while (0)
+
+void __init proc_all_init(void)
+{
+	struct proc_dir_entry *all_dir = proc_mkdir("all", NULL);
+
+	if (!all_dir)
+		return;
+
+	PROC_ALL_CREATE(stat);
+}
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 917cc85e3466..b22d9cb619bf 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -171,6 +171,7 @@ extern int pid_delete_dentry(const struct dentry *);
 extern int proc_pid_readdir(struct file *, struct dir_context *);
 struct dentry *proc_pid_lookup(struct dentry *, unsigned int);
 extern loff_t mem_lseek(struct file *, loff_t, int);
+extern void proc_all_init(void);
 
 /* Lookups */
 typedef struct dentry *instantiate_t(struct dentry *,
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 5e444d4f9717..4b5cfd2cdc0a 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -291,6 +291,7 @@ void __init proc_root_init(void)
 	set_proc_pid_nlink();
 	proc_self_init();
 	proc_thread_self_init();
+	proc_all_init();
 	proc_symlink("mounts", NULL, "self/mounts");
 
 	proc_net_init();
-- 
2.25.1


  reply	other threads:[~2020-08-10 14:59 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-10 14:58 [RFC PATCH 0/5] Introduce /proc/all/ to gather stats from all processes Eugene Lubarsky
2020-08-10 14:58 ` Eugene Lubarsky [this message]
2020-08-10 14:58 ` [RFC PATCH 2/5] fs/proc: Introduce /proc/all/statm Eugene Lubarsky
2020-08-10 14:58 ` [RFC PATCH 3/5] fs/proc: Introduce /proc/all/status Eugene Lubarsky
2020-08-10 14:58 ` [RFC PATCH 4/5] fs/proc: Introduce /proc/all/io Eugene Lubarsky
2020-08-10 14:58 ` [RFC PATCH 5/5] fs/proc: Introduce /proc/all/statx Eugene Lubarsky
2020-08-10 15:04 ` [RFC PATCH 0/5] Introduce /proc/all/ to gather stats from all processes Greg KH
2020-08-10 15:27   ` Eugene Lubarsky
2020-08-10 15:41     ` Greg KH
2020-08-25  9:59       ` Eugene Lubarsky
2020-08-12  7:51 ` Andrei Vagin
2020-08-13  4:47   ` David Ahern
2020-08-13  8:03     ` Andrei Vagin
2020-08-13 15:01   ` Eugene Lubarsky
2020-08-20 17:41     ` Andrei Vagin
2020-08-25 10:00       ` Eugene Lubarsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200810145852.9330-2-elubarsky.linux@gmail.com \
    --to=elubarsky.linux@gmail.com \
    --cc=adobriyan@gmail.com \
    --cc=avagin@gmail.com \
    --cc=dsahern@gmail.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --subject='Re: [RFC PATCH 1/5] fs/proc: Introduce /proc/all/stat' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).