cpuset: add helpers for cpus read and cpuset_mutex locks

cpuset: add helpers for cpus_read_lock and cpuset_mutex locks.

Replace repetitive locking patterns with new helpers:
- cpuset_full_lock()
- cpuset_full_unlock()

This makes the code cleaner and ensures consistent lock ordering.

Signed-off-by: Chen Ridong <chenridong@huawei.com>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Chen Ridong 2025-08-25 03:23:52 +00:00 committed by Tejun Heo
parent ada00d5162
commit 2c98144fc8
3 changed files with 40 additions and 34 deletions

View File

@ -276,6 +276,8 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs, int turning_on)
ssize_t cpuset_write_resmask(struct kernfs_open_file *of, ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off); char *buf, size_t nbytes, loff_t off);
int cpuset_common_seq_show(struct seq_file *sf, void *v); int cpuset_common_seq_show(struct seq_file *sf, void *v);
void cpuset_full_lock(void);
void cpuset_full_unlock(void);
/* /*
* cpuset-v1.c * cpuset-v1.c

View File

@ -169,8 +169,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private; cpuset_filetype_t type = cft->private;
int retval = -ENODEV; int retval = -ENODEV;
cpus_read_lock(); cpuset_full_lock();
cpuset_lock();
if (!is_cpuset_online(cs)) if (!is_cpuset_online(cs))
goto out_unlock; goto out_unlock;
@ -184,8 +183,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
break; break;
} }
out_unlock: out_unlock:
cpuset_unlock(); cpuset_full_unlock();
cpus_read_unlock();
return retval; return retval;
} }
@ -454,8 +452,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private; cpuset_filetype_t type = cft->private;
int retval = 0; int retval = 0;
cpus_read_lock(); cpuset_full_lock();
cpuset_lock();
if (!is_cpuset_online(cs)) { if (!is_cpuset_online(cs)) {
retval = -ENODEV; retval = -ENODEV;
goto out_unlock; goto out_unlock;
@ -498,8 +495,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
break; break;
} }
out_unlock: out_unlock:
cpuset_unlock(); cpuset_full_unlock();
cpus_read_unlock();
return retval; return retval;
} }

View File

@ -250,6 +250,12 @@ static struct cpuset top_cpuset = {
static DEFINE_MUTEX(cpuset_mutex); static DEFINE_MUTEX(cpuset_mutex);
/**
* cpuset_lock - Acquire the global cpuset mutex
*
* This locks the global cpuset mutex to prevent modifications to cpuset
* hierarchy and configurations. This helper is not enough to make modification.
*/
void cpuset_lock(void) void cpuset_lock(void)
{ {
mutex_lock(&cpuset_mutex); mutex_lock(&cpuset_mutex);
@ -260,6 +266,24 @@ void cpuset_unlock(void)
mutex_unlock(&cpuset_mutex); mutex_unlock(&cpuset_mutex);
} }
/**
* cpuset_full_lock - Acquire full protection for cpuset modification
*
* Takes both CPU hotplug read lock (cpus_read_lock()) and cpuset mutex
* to safely modify cpuset data.
*/
void cpuset_full_lock(void)
{
cpus_read_lock();
mutex_lock(&cpuset_mutex);
}
void cpuset_full_unlock(void)
{
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
}
static DEFINE_SPINLOCK(callback_lock); static DEFINE_SPINLOCK(callback_lock);
void cpuset_callback_lock_irq(void) void cpuset_callback_lock_irq(void)
@ -3234,8 +3258,7 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
int retval = -ENODEV; int retval = -ENODEV;
buf = strstrip(buf); buf = strstrip(buf);
cpus_read_lock(); cpuset_full_lock();
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) if (!is_cpuset_online(cs))
goto out_unlock; goto out_unlock;
@ -3264,8 +3287,7 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
if (force_sd_rebuild) if (force_sd_rebuild)
rebuild_sched_domains_locked(); rebuild_sched_domains_locked();
out_unlock: out_unlock:
mutex_unlock(&cpuset_mutex); cpuset_full_unlock();
cpus_read_unlock();
flush_workqueue(cpuset_migrate_mm_wq); flush_workqueue(cpuset_migrate_mm_wq);
return retval ?: nbytes; return retval ?: nbytes;
} }
@ -3368,12 +3390,10 @@ static ssize_t cpuset_partition_write(struct kernfs_open_file *of, char *buf,
else else
return -EINVAL; return -EINVAL;
cpus_read_lock(); cpuset_full_lock();
mutex_lock(&cpuset_mutex);
if (is_cpuset_online(cs)) if (is_cpuset_online(cs))
retval = update_prstate(cs, val); retval = update_prstate(cs, val);
mutex_unlock(&cpuset_mutex); cpuset_full_unlock();
cpus_read_unlock();
return retval ?: nbytes; return retval ?: nbytes;
} }
@ -3498,9 +3518,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
if (!parent) if (!parent)
return 0; return 0;
cpus_read_lock(); cpuset_full_lock();
mutex_lock(&cpuset_mutex);
if (is_spread_page(parent)) if (is_spread_page(parent))
set_bit(CS_SPREAD_PAGE, &cs->flags); set_bit(CS_SPREAD_PAGE, &cs->flags);
if (is_spread_slab(parent)) if (is_spread_slab(parent))
@ -3552,8 +3570,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
cpumask_copy(cs->effective_cpus, parent->cpus_allowed); cpumask_copy(cs->effective_cpus, parent->cpus_allowed);
spin_unlock_irq(&callback_lock); spin_unlock_irq(&callback_lock);
out_unlock: out_unlock:
mutex_unlock(&cpuset_mutex); cpuset_full_unlock();
cpus_read_unlock();
return 0; return 0;
} }
@ -3568,16 +3585,12 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
{ {
struct cpuset *cs = css_cs(css); struct cpuset *cs = css_cs(css);
cpus_read_lock(); cpuset_full_lock();
mutex_lock(&cpuset_mutex);
if (!cpuset_v2() && is_sched_load_balance(cs)) if (!cpuset_v2() && is_sched_load_balance(cs))
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
cpuset_dec(); cpuset_dec();
cpuset_full_unlock();
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
} }
/* /*
@ -3589,16 +3602,11 @@ static void cpuset_css_killed(struct cgroup_subsys_state *css)
{ {
struct cpuset *cs = css_cs(css); struct cpuset *cs = css_cs(css);
cpus_read_lock(); cpuset_full_lock();
mutex_lock(&cpuset_mutex);
/* Reset valid partition back to member */ /* Reset valid partition back to member */
if (is_partition_valid(cs)) if (is_partition_valid(cs))
update_prstate(cs, PRS_MEMBER); update_prstate(cs, PRS_MEMBER);
cpuset_full_unlock();
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
} }
static void cpuset_css_free(struct cgroup_subsys_state *css) static void cpuset_css_free(struct cgroup_subsys_state *css)