x86/intel_rdt: Prepare for RDT monitoring mkdir support
authorVikas Shivappa <vikas.shivappa@linux.intel.com>
Tue, 25 Jul 2017 21:14:31 +0000 (14:14 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 1 Aug 2017 20:41:23 +0000 (22:41 +0200)
Separate the ctrl mkdir code from the rest in order to prepare for
adding support for RDT monitoring mkdir support as well.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: peterz@infradead.org
Cc: eranian@google.com
Cc: vikas.shivappa@intel.com
Cc: ak@linux.intel.com
Cc: davidcc@google.com
Cc: reinette.chatre@intel.com
Link: http://lkml.kernel.org/r/1501017287-28083-13-git-send-email-vikas.shivappa@linux.intel.com
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c

index 14489a5ecf12298b3c7b4dba389e8e9a6ff7ab1f..b3c901a8295e447334bb7f8aa98d2bf837ef1015 100644 (file)
@@ -1082,46 +1082,35 @@ static struct file_system_type rdt_fs_type = {
        .kill_sb = rdt_kill_sb,
 };
 
-static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
-                         umode_t mode)
+static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
+                            struct kernfs_node *prgrp_kn,
+                            const char *name, umode_t mode,
+                            struct rdtgroup **r)
 {
-       struct rdtgroup *parent, *rdtgrp;
+       struct rdtgroup *prdtgrp, *rdtgrp;
        struct kernfs_node *kn;
-       int ret, closid;
-
-       /* Only allow mkdir in the root directory */
-       if (parent_kn != rdtgroup_default.kn)
-               return -EPERM;
-
-       /* Do not accept '\n' to avoid unparsable situation. */
-       if (strchr(name, '\n'))
-               return -EINVAL;
+       uint files = 0;
+       int ret;
 
-       parent = rdtgroup_kn_lock_live(parent_kn);
-       if (!parent) {
+       prdtgrp = rdtgroup_kn_lock_live(prgrp_kn);
+       if (!prdtgrp) {
                ret = -ENODEV;
                goto out_unlock;
        }
 
-       ret = closid_alloc();
-       if (ret < 0)
-               goto out_unlock;
-       closid = ret;
-
        /* allocate the rdtgroup. */
        rdtgrp = kzalloc(sizeof(*rdtgrp), GFP_KERNEL);
        if (!rdtgrp) {
                ret = -ENOSPC;
-               goto out_closid_free;
+               goto out_unlock;
        }
-       rdtgrp->closid = closid;
-       list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
+       *r = rdtgrp;
 
        /* kernfs creates the directory for rdtgrp */
-       kn = kernfs_create_dir(parent->kn, name, mode, rdtgrp);
+       kn = kernfs_create_dir(parent_kn, name, mode, rdtgrp);
        if (IS_ERR(kn)) {
                ret = PTR_ERR(kn);
-               goto out_cancel_ref;
+               goto out_free_rgrp;
        }
        rdtgrp->kn = kn;
 
@@ -1137,27 +1126,85 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
        if (ret)
                goto out_destroy;
 
-       ret = rdtgroup_add_files(kn, RF_CTRL_BASE);
+       files = RFTYPE_BASE | RFTYPE_CTRL;
+       ret = rdtgroup_add_files(kn, files);
        if (ret)
                goto out_destroy;
 
        kernfs_activate(kn);
 
-       ret = 0;
-       goto out_unlock;
+       /*
+        * The caller unlocks the prgrp_kn upon success.
+        */
+       return 0;
 
 out_destroy:
        kernfs_remove(rdtgrp->kn);
-out_cancel_ref:
-       list_del(&rdtgrp->rdtgroup_list);
+out_free_rgrp:
        kfree(rdtgrp);
-out_closid_free:
-       closid_free(closid);
 out_unlock:
-       rdtgroup_kn_unlock(parent_kn);
+       rdtgroup_kn_unlock(prgrp_kn);
+       return ret;
+}
+
+static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp)
+{
+       kernfs_remove(rgrp->kn);
+       kfree(rgrp);
+}
+
+/*
+ * These are rdtgroups created under the root directory. Can be used
+ * to allocate resources.
+ */
+static int rdtgroup_mkdir_ctrl(struct kernfs_node *parent_kn,
+                              struct kernfs_node *prgrp_kn,
+                              const char *name, umode_t mode)
+{
+       struct rdtgroup *rdtgrp;
+       struct kernfs_node *kn;
+       u32 closid;
+       int ret;
+
+       ret = mkdir_rdt_prepare(parent_kn, prgrp_kn, name, mode, &rdtgrp);
+       if (ret)
+               return ret;
+
+       kn = rdtgrp->kn;
+       ret = closid_alloc();
+       if (ret < 0)
+               goto out_common_fail;
+       closid = ret;
+
+       rdtgrp->closid = closid;
+       list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
+
+       goto out_unlock;
+
+out_common_fail:
+       mkdir_rdt_prepare_clean(rdtgrp);
+out_unlock:
+       rdtgroup_kn_unlock(prgrp_kn);
        return ret;
 }
 
+static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
+                         umode_t mode)
+{
+       /* Do not accept '\n' to avoid unparsable situation. */
+       if (strchr(name, '\n'))
+               return -EINVAL;
+
+       /*
+        * If the parent directory is the root directory and RDT
+        * allocation is supported, add a control rdtgroup.
+        */
+       if (rdt_alloc_capable && parent_kn == rdtgroup_default.kn)
+               return rdtgroup_mkdir_ctrl(parent_kn, parent_kn, name, mode);
+
+       return -EPERM;
+}
+
 static int rdtgroup_rmdir(struct kernfs_node *kn)
 {
        int ret, cpu, closid = rdtgroup_default.closid;