[PATCH 1/3] mm/lru_gen: add procfs support for lru_gen interfaces

Zicheng Wang posted 3 patches 3 days, 18 hours ago
[PATCH 1/3] mm/lru_gen: add procfs support for lru_gen interfaces
Posted by Zicheng Wang 3 days, 18 hours ago
This patch refactors the lru_gen and lru_gen_full control files to allow
their interfaces to be exposed under either debugfs or procfs.

Two main changes:
1. minimal code modification by reusing the existing seq_operations.
2. lru_gen file mode update from 0644 to 0664, so that Android's group
"system" can write to the file when procfs interface is enabled.

Signed-off-by: Zicheng Wang <wangzicheng@honor.com>
---
 mm/vmscan.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 674999999..dd30f3949 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -58,6 +58,7 @@
 #include <linux/random.h>
 #include <linux/mmu_notifier.h>
 #include <linux/parser.h>
+#include <linux/proc_fs.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -5324,9 +5325,17 @@ static const struct attribute_group lru_gen_attr_group = {
 };
 
 /******************************************************************************
- *                          debugfs interface
+ *                          lru_gen interface
  ******************************************************************************/
 
+static inline bool lru_gen_show_is_full(const struct file *file)
+{
+    /* procfs: i_private = (void *)1 means full
+     * debugfs: also works because debugfs sets i_private
+     */
+	return file->f_inode->i_private != NULL;
+}
+
 static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos)
 {
 	struct mem_cgroup *memcg;
@@ -5435,7 +5444,7 @@ static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
 static int lru_gen_seq_show(struct seq_file *m, void *v)
 {
 	unsigned long seq;
-	bool full = debugfs_get_aux_num(m->file);
+	bool full = lru_gen_show_is_full(m->file);
 	struct lruvec *lruvec = v;
 	struct lru_gen_folio *lrugen = &lruvec->lrugen;
 	int nid = lruvec_pgdat(lruvec)->node_id;
@@ -5671,6 +5680,7 @@ static int lru_gen_seq_open(struct inode *inode, struct file *file)
 	return seq_open(file, &lru_gen_seq_ops);
 }
 
+#ifndef CONFIG_LRU_GEN_PROCFS_CTRL
 static const struct file_operations lru_gen_rw_fops = {
 	.open = lru_gen_seq_open,
 	.read = seq_read,
@@ -5685,6 +5695,22 @@ static const struct file_operations lru_gen_ro_fops = {
 	.llseek = seq_lseek,
 	.release = seq_release,
 };
+#else
+static const struct proc_ops lru_gen_proc_rw_ops = {
+	.proc_open    = lru_gen_seq_open,
+	.proc_read    = seq_read,
+	.proc_write   = lru_gen_seq_write,
+	.proc_lseek   = seq_lseek,
+	.proc_release = seq_release,
+};
+
+static const struct proc_ops lru_gen_proc_ro_ops = {
+	.proc_open    = lru_gen_seq_open,
+	.proc_read    = seq_read,
+	.proc_lseek   = seq_lseek,
+	.proc_release = seq_release,
+};
+#endif
 
 /******************************************************************************
  *                          initialization
@@ -5772,10 +5798,17 @@ static int __init init_lru_gen(void)
 	if (sysfs_create_group(mm_kobj, &lru_gen_attr_group))
 		pr_err("lru_gen: failed to create sysfs group\n");
 
+#ifndef CONFIG_LRU_GEN_PROCFS_CTRL
 	debugfs_create_file_aux_num("lru_gen", 0644, NULL, NULL, false,
 				    &lru_gen_rw_fops);
 	debugfs_create_file_aux_num("lru_gen_full", 0444, NULL, NULL, true,
 				    &lru_gen_ro_fops);
+#else
+	proc_create_data("lru_gen", 0664, NULL,
+					&lru_gen_proc_rw_ops, NULL);
+	proc_create_data("lru_gen_full", 0444, NULL,
+					&lru_gen_proc_ro_ops, (void *)1);
+#endif
 
 	return 0;
 };
-- 
2.25.1