2323#include <linux/fs.h>
2424#include <linux/sysfs.h>
2525#include <linux/kernfs.h>
26+ #include <linux/seq_file.h>
27+ #include <linux/sched.h>
2628#include <linux/slab.h>
2729
2830#include <uapi/linux/magic.h>
@@ -34,6 +36,176 @@ struct kernfs_root *rdt_root;
3436struct rdtgroup rdtgroup_default ;
3537LIST_HEAD (rdt_all_groups );
3638
39+ /* Kernel fs node for "info" directory under root */
40+ static struct kernfs_node * kn_info ;
41+
42+ /* set uid and gid of rdtgroup dirs and files to that of the creator */
43+ static int rdtgroup_kn_set_ugid (struct kernfs_node * kn )
44+ {
45+ struct iattr iattr = { .ia_valid = ATTR_UID | ATTR_GID ,
46+ .ia_uid = current_fsuid (),
47+ .ia_gid = current_fsgid (), };
48+
49+ if (uid_eq (iattr .ia_uid , GLOBAL_ROOT_UID ) &&
50+ gid_eq (iattr .ia_gid , GLOBAL_ROOT_GID ))
51+ return 0 ;
52+
53+ return kernfs_setattr (kn , & iattr );
54+ }
55+
56+ static int rdtgroup_add_file (struct kernfs_node * parent_kn , struct rftype * rft )
57+ {
58+ struct kernfs_node * kn ;
59+ int ret ;
60+
61+ kn = __kernfs_create_file (parent_kn , rft -> name , rft -> mode ,
62+ 0 , rft -> kf_ops , rft , NULL , NULL );
63+ if (IS_ERR (kn ))
64+ return PTR_ERR (kn );
65+
66+ ret = rdtgroup_kn_set_ugid (kn );
67+ if (ret ) {
68+ kernfs_remove (kn );
69+ return ret ;
70+ }
71+
72+ return 0 ;
73+ }
74+
75+ static int rdtgroup_add_files (struct kernfs_node * kn , struct rftype * rfts ,
76+ int len )
77+ {
78+ struct rftype * rft ;
79+ int ret ;
80+
81+ lockdep_assert_held (& rdtgroup_mutex );
82+
83+ for (rft = rfts ; rft < rfts + len ; rft ++ ) {
84+ ret = rdtgroup_add_file (kn , rft );
85+ if (ret )
86+ goto error ;
87+ }
88+
89+ return 0 ;
90+ error :
91+ pr_warn ("Failed to add %s, err=%d\n" , rft -> name , ret );
92+ while (-- rft >= rfts )
93+ kernfs_remove_by_name (kn , rft -> name );
94+ return ret ;
95+ }
96+
97+ static int rdtgroup_seqfile_show (struct seq_file * m , void * arg )
98+ {
99+ struct kernfs_open_file * of = m -> private ;
100+ struct rftype * rft = of -> kn -> priv ;
101+
102+ if (rft -> seq_show )
103+ return rft -> seq_show (of , m , arg );
104+ return 0 ;
105+ }
106+
107+ static ssize_t rdtgroup_file_write (struct kernfs_open_file * of , char * buf ,
108+ size_t nbytes , loff_t off )
109+ {
110+ struct rftype * rft = of -> kn -> priv ;
111+
112+ if (rft -> write )
113+ return rft -> write (of , buf , nbytes , off );
114+
115+ return - EINVAL ;
116+ }
117+
118+ static struct kernfs_ops rdtgroup_kf_single_ops = {
119+ .atomic_write_len = PAGE_SIZE ,
120+ .write = rdtgroup_file_write ,
121+ .seq_show = rdtgroup_seqfile_show ,
122+ };
123+
124+ static int rdt_num_closids_show (struct kernfs_open_file * of ,
125+ struct seq_file * seq , void * v )
126+ {
127+ struct rdt_resource * r = of -> kn -> parent -> priv ;
128+
129+ seq_printf (seq , "%d\n" , r -> num_closid );
130+
131+ return 0 ;
132+ }
133+
134+ static int rdt_cbm_mask_show (struct kernfs_open_file * of ,
135+ struct seq_file * seq , void * v )
136+ {
137+ struct rdt_resource * r = of -> kn -> parent -> priv ;
138+
139+ seq_printf (seq , "%x\n" , r -> max_cbm );
140+
141+ return 0 ;
142+ }
143+
144+ /* rdtgroup information files for one cache resource. */
145+ static struct rftype res_info_files [] = {
146+ {
147+ .name = "num_closids" ,
148+ .mode = 0444 ,
149+ .kf_ops = & rdtgroup_kf_single_ops ,
150+ .seq_show = rdt_num_closids_show ,
151+ },
152+ {
153+ .name = "cbm_mask" ,
154+ .mode = 0444 ,
155+ .kf_ops = & rdtgroup_kf_single_ops ,
156+ .seq_show = rdt_cbm_mask_show ,
157+ },
158+ };
159+
160+ static int rdtgroup_create_info_dir (struct kernfs_node * parent_kn )
161+ {
162+ struct kernfs_node * kn_subdir ;
163+ struct rdt_resource * r ;
164+ int ret ;
165+
166+ /* create the directory */
167+ kn_info = kernfs_create_dir (parent_kn , "info" , parent_kn -> mode , NULL );
168+ if (IS_ERR (kn_info ))
169+ return PTR_ERR (kn_info );
170+ kernfs_get (kn_info );
171+
172+ for_each_enabled_rdt_resource (r ) {
173+ kn_subdir = kernfs_create_dir (kn_info , r -> name ,
174+ kn_info -> mode , r );
175+ if (IS_ERR (kn_subdir )) {
176+ ret = PTR_ERR (kn_subdir );
177+ goto out_destroy ;
178+ }
179+ kernfs_get (kn_subdir );
180+ ret = rdtgroup_kn_set_ugid (kn_subdir );
181+ if (ret )
182+ goto out_destroy ;
183+ ret = rdtgroup_add_files (kn_subdir , res_info_files ,
184+ ARRAY_SIZE (res_info_files ));
185+ if (ret )
186+ goto out_destroy ;
187+ kernfs_activate (kn_subdir );
188+ }
189+
190+ /*
191+ * This extra ref will be put in kernfs_remove() and guarantees
192+ * that @rdtgrp->kn is always accessible.
193+ */
194+ kernfs_get (kn_info );
195+
196+ ret = rdtgroup_kn_set_ugid (kn_info );
197+ if (ret )
198+ goto out_destroy ;
199+
200+ kernfs_activate (kn_info );
201+
202+ return 0 ;
203+
204+ out_destroy :
205+ kernfs_remove (kn_info );
206+ return ret ;
207+ }
208+
37209static void l3_qos_cfg_update (void * arg )
38210{
39211 bool * enable = arg ;
@@ -137,6 +309,10 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type,
137309 goto out_cdp ;
138310 }
139311
312+ ret = rdtgroup_create_info_dir (rdtgroup_default .kn );
313+ if (ret )
314+ goto out_cdp ;
315+
140316 dentry = kernfs_mount (fs_type , flags , rdt_root ,
141317 RDTGROUP_SUPER_MAGIC , NULL );
142318 if (IS_ERR (dentry ))
@@ -191,6 +367,14 @@ static int reset_all_cbms(struct rdt_resource *r)
191367 return 0 ;
192368}
193369
370+ /*
371+ * Forcibly remove all of subdirectories under root.
372+ */
373+ static void rmdir_all_sub (void )
374+ {
375+ kernfs_remove (kn_info );
376+ }
377+
194378static void rdt_kill_sb (struct super_block * sb )
195379{
196380 struct rdt_resource * r ;
@@ -201,6 +385,7 @@ static void rdt_kill_sb(struct super_block *sb)
201385 for_each_enabled_rdt_resource (r )
202386 reset_all_cbms (r );
203387 cdp_disable ();
388+ rmdir_all_sub ();
204389 static_branch_disable (& rdt_enable_key );
205390 kernfs_kill_sb (sb );
206391 mutex_unlock (& rdtgroup_mutex );
0 commit comments