|
@@ -239,6 +239,17 @@ static struct cpuset top_cpuset = {
|
|
|
|
|
|
static DEFINE_MUTEX(callback_mutex);
|
|
|
|
|
|
+/*
|
|
|
+ * cpuset_buffer_lock protects both the cpuset_name and cpuset_nodelist
|
|
|
+ * buffers. They are statically allocated to prevent using excess stack
|
|
|
+ * when calling cpuset_print_task_mems_allowed().
|
|
|
+ */
|
|
|
+#define CPUSET_NAME_LEN (128)
|
|
|
+#define CPUSET_NODELIST_LEN (256)
|
|
|
+static char cpuset_name[CPUSET_NAME_LEN];
|
|
|
+static char cpuset_nodelist[CPUSET_NODELIST_LEN];
|
|
|
+static DEFINE_SPINLOCK(cpuset_buffer_lock);
|
|
|
+
|
|
|
/*
|
|
|
* This is ugly, but preserves the userspace API for existing cpuset
|
|
|
* users. If someone tries to mount the "cpuset" filesystem, we
|
|
@@ -2356,6 +2367,29 @@ int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
|
|
|
return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * cpuset_print_task_mems_allowed - prints task's cpuset and mems_allowed
|
|
|
+ * @task: pointer to task_struct of some task.
|
|
|
+ *
|
|
|
+ * Description: Prints @task's name, cpuset name, and cached copy of its
|
|
|
+ * mems_allowed to the kernel log. Must hold task_lock(task) to allow
|
|
|
+ * dereferencing task_cs(task).
|
|
|
+ */
|
|
|
+void cpuset_print_task_mems_allowed(struct task_struct *tsk)
|
|
|
+{
|
|
|
+ struct dentry *dentry;
|
|
|
+
|
|
|
+ dentry = task_cs(tsk)->css.cgroup->dentry;
|
|
|
+ spin_lock(&cpuset_buffer_lock);
|
|
|
+ snprintf(cpuset_name, CPUSET_NAME_LEN,
|
|
|
+ dentry ? (const char *)dentry->d_name.name : "/");
|
|
|
+ nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN,
|
|
|
+ tsk->mems_allowed);
|
|
|
+ printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n",
|
|
|
+ tsk->comm, cpuset_name, cpuset_nodelist);
|
|
|
+ spin_unlock(&cpuset_buffer_lock);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Collection of memory_pressure is suppressed unless
|
|
|
* this flag is enabled by writing "1" to the special
|