lkml.org 
[lkml]   [2021]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 4/6] cgroup/cpuset: Show invalid partition reason string
    Date
    There are a number of different reasons which can cause a partition to
    become invalid. A user seeing an invalid partition may not know exactly
    why. To help user to get a better understanding of the underlying reason,
    The cpuset.cpus.partition control file, when read, will now report the
    reason why a partition become invalid. When a partition does become
    invalid, reading the control file will show "root invalid (<reason>)"
    where <reason> is a string that describes why the partition is invalid.

    Signed-off-by: Waiman Long <longman@redhat.com>
    ---
    kernel/cgroup/cpuset.c | 48 +++++++++++++++++++++++++++++++++++++++---
    1 file changed, 45 insertions(+), 3 deletions(-)

    diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
    index fab31921728c..9c5ecc8d100c 100644
    --- a/kernel/cgroup/cpuset.c
    +++ b/kernel/cgroup/cpuset.c
    @@ -78,6 +78,24 @@ struct fmeter {
    spinlock_t lock; /* guards read or write of above */
    };

    +/*
    + * Invalid partition error code
    + */
    +enum prs_errcode {
    + PERR_NONE = 0,
    + PERR_INVCPUS,
    + PERR_NOCPUS,
    + PERR_PARENT,
    + PERR_HOTPLUG,
    +};
    +
    +static const char * const perr_strings[] = {
    + [PERR_INVCPUS] = "Invalid change to cpuset.cpus",
    + [PERR_PARENT] = "Parent is no longer a valid partition root",
    + [PERR_NOCPUS] = "Parent unable to distribute cpu downstream",
    + [PERR_HOTPLUG] = "No cpu available due to hotplug",
    +};
    +
    struct cpuset {
    struct cgroup_subsys_state css;

    @@ -163,6 +181,9 @@ struct cpuset {

    /* Handle for cpuset.cpus.partition */
    struct cgroup_file partition_file;
    +
    + /* Invalid partition error code, not lock protected */
    + enum prs_errcode prs_err;
    };

    /*
    @@ -275,8 +296,13 @@ static inline int is_partition_root(const struct cpuset *cs)
    static inline void notify_partition_change(struct cpuset *cs,
    int old_prs, int new_prs)
    {
    - if (old_prs != new_prs)
    - cgroup_file_notify(&cs->partition_file);
    + if (old_prs == new_prs)
    + return;
    + cgroup_file_notify(&cs->partition_file);
    +
    + /* Reset prs_err if not invalid */
    + if (new_prs != PRS_ERROR)
    + WRITE_ONCE(cs->prs_err, PERR_NONE);
    }

    static struct cpuset top_cpuset = {
    @@ -1282,6 +1308,9 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
    part_error = partition_is_populated(parent, cpuset) &&
    cpumask_subset(parent->effective_cpus, tmp->addmask) &&
    !cpumask_intersects(tmp->delmask, cpu_active_mask);
    +
    + if ((READ_ONCE(cpuset->prs_err) == PERR_NONE) && part_error)
    + WRITE_ONCE(cpuset->prs_err, PERR_INVCPUS);
    } else {
    /*
    * partcmd_update w/o newmask:
    @@ -1305,6 +1334,9 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
    !parent->nr_subparts_cpus) ||
    (cpumask_equal(parent->effective_cpus, tmp->addmask) &&
    partition_is_populated(parent, cpuset));
    +
    + if (is_partition_root(cpuset) && part_error)
    + WRITE_ONCE(cpuset->prs_err, PERR_NOCPUS);
    }

    if (cmd == partcmd_update) {
    @@ -1478,6 +1510,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
    * When parent is invalid, it has to be too.
    */
    new_prs = PRS_ERROR;
    + WRITE_ONCE(cp->prs_err, PERR_PARENT);
    break;
    }
    }
    @@ -2637,6 +2670,7 @@ static s64 cpuset_read_s64(struct cgroup_subsys_state *css, struct cftype *cft)
    static int sched_partition_show(struct seq_file *seq, void *v)
    {
    struct cpuset *cs = css_cs(seq_css(seq));
    + const char *err;

    switch (cs->partition_root_state) {
    case PRS_ENABLED:
    @@ -2649,7 +2683,11 @@ static int sched_partition_show(struct seq_file *seq, void *v)
    seq_puts(seq, "member\n");
    break;
    case PRS_ERROR:
    - seq_puts(seq, "root invalid\n");
    + err = perr_strings[READ_ONCE(cs->prs_err)];
    + if (err)
    + seq_printf(seq, "root invalid (%s)\n", err);
    + else
    + seq_puts(seq, "root invalid\n");
    break;
    }
    return 0;
    @@ -3256,6 +3294,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
    spin_lock_irq(&callback_lock);
    cs->partition_root_state = PRS_ERROR;
    spin_unlock_irq(&callback_lock);
    + if (parent->partition_root_state == PRS_ERROR)
    + WRITE_ONCE(cs->prs_err, PERR_PARENT);
    + else
    + WRITE_ONCE(cs->prs_err, PERR_HOTPLUG);
    notify_partition_change(cs, old_prs, PRS_ERROR);
    }
    cpuset_force_rebuild();
    --
    2.27.0
    \
     
     \ /
      Last update: 2021-10-18 16:39    [W:4.260 / U:0.196 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site