Merge tag 'pm-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[cascardo/linux.git] / kernel / cpuset.c
index c27e533..29f815d 100644 (file)
@@ -325,8 +325,7 @@ static struct file_system_type cpuset_fs_type = {
 /*
  * Return in pmask the portion of a cpusets's cpus_allowed that
  * are online.  If none are online, walk up the cpuset hierarchy
- * until we find one that does have some online cpus.  The top
- * cpuset always has some cpus online.
+ * until we find one that does have some online cpus.
  *
  * One way or another, we guarantee to return some non-empty subset
  * of cpu_online_mask.
@@ -335,8 +334,20 @@ static struct file_system_type cpuset_fs_type = {
  */
 static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask)
 {
-       while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask))
+       while (!cpumask_intersects(cs->effective_cpus, cpu_online_mask)) {
                cs = parent_cs(cs);
+               if (unlikely(!cs)) {
+                       /*
+                        * The top cpuset doesn't have any online cpu as a
+                        * consequence of a race between cpuset_hotplug_work
+                        * and cpu hotplug notifier.  But we know the top
+                        * cpuset's effective_cpus is on its way to to be
+                        * identical to cpu_online_mask.
+                        */
+                       cpumask_copy(pmask, cpu_online_mask);
+                       return;
+               }
+       }
        cpumask_and(pmask, cs->effective_cpus, cpu_online_mask);
 }
 
@@ -2074,7 +2085,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
  * which could have been changed by cpuset just after it inherits the
  * state from the parent and before it sits on the cgroup's task list.
  */
-void cpuset_fork(struct task_struct *task)
+static void cpuset_fork(struct task_struct *task)
 {
        if (task_css_is_root(task, cpuset_cgrp_id))
                return;
@@ -2704,7 +2715,7 @@ void __cpuset_memory_pressure_bump(void)
 int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
                     struct pid *pid, struct task_struct *tsk)
 {
-       char *buf, *p;
+       char *buf;
        struct cgroup_subsys_state *css;
        int retval;
 
@@ -2713,14 +2724,15 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
        if (!buf)
                goto out;
 
-       retval = -ENAMETOOLONG;
        css = task_get_css(tsk, cpuset_cgrp_id);
-       p = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
-                          current->nsproxy->cgroup_ns);
+       retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
+                               current->nsproxy->cgroup_ns);
        css_put(css);
-       if (!p)
+       if (retval >= PATH_MAX)
+               retval = -ENAMETOOLONG;
+       if (retval < 0)
                goto out_free;
-       seq_puts(m, p);
+       seq_puts(m, buf);
        seq_putc(m, '\n');
        retval = 0;
 out_free: