Skip to content

Commit b90ca8b

Browse files
willdeaconPeter Zijlstra
authored andcommitted
sched: Introduce task_struct::user_cpus_ptr to track requested affinity
In preparation for saving and restoring the user-requested CPU affinity mask of a task, add a new cpumask_t pointer to 'struct task_struct'. If the pointer is non-NULL, then the mask is copied across fork() and freed on task exit. Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Valentin Schneider <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 234a503 commit b90ca8b

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

include/linux/sched.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ struct task_struct {
748748
unsigned int policy;
749749
int nr_cpus_allowed;
750750
const cpumask_t *cpus_ptr;
751+
cpumask_t *user_cpus_ptr;
751752
cpumask_t cpus_mask;
752753
void *migration_pending;
753754
#ifdef CONFIG_SMP
@@ -1706,6 +1707,8 @@ extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_cpus_
17061707
#ifdef CONFIG_SMP
17071708
extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask);
17081709
extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
1710+
extern int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src, int node);
1711+
extern void release_user_cpus_ptr(struct task_struct *p);
17091712
#else
17101713
static inline void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
17111714
{
@@ -1716,6 +1719,16 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, const struct cpuma
17161719
return -EINVAL;
17171720
return 0;
17181721
}
1722+
static inline int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src, int node)
1723+
{
1724+
if (src->user_cpus_ptr)
1725+
return -EINVAL;
1726+
return 0;
1727+
}
1728+
static inline void release_user_cpus_ptr(struct task_struct *p)
1729+
{
1730+
WARN_ON(p->user_cpus_ptr);
1731+
}
17191732
#endif
17201733

17211734
extern int yield_to(struct task_struct *p, bool preempt);

init/init_task.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct task_struct init_task
8080
.normal_prio = MAX_PRIO - 20,
8181
.policy = SCHED_NORMAL,
8282
.cpus_ptr = &init_task.cpus_mask,
83+
.user_cpus_ptr = NULL,
8384
.cpus_mask = CPU_MASK_ALL,
8485
.nr_cpus_allowed= NR_CPUS,
8586
.mm = NULL,

kernel/fork.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ void put_task_stack(struct task_struct *tsk)
446446

447447
void free_task(struct task_struct *tsk)
448448
{
449+
release_user_cpus_ptr(tsk);
449450
scs_release(tsk);
450451

451452
#ifndef CONFIG_THREAD_INFO_IN_TASK
@@ -919,6 +920,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
919920
#endif
920921
if (orig->cpus_ptr == &orig->cpus_mask)
921922
tsk->cpus_ptr = &tsk->cpus_mask;
923+
dup_user_cpus_ptr(tsk, orig, node);
922924

923925
/*
924926
* One for the user space visible state that goes away when reaped.

kernel/sched/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,26 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
24802480
__do_set_cpus_allowed(p, new_mask, 0);
24812481
}
24822482

2483+
int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src,
2484+
int node)
2485+
{
2486+
if (!src->user_cpus_ptr)
2487+
return 0;
2488+
2489+
dst->user_cpus_ptr = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
2490+
if (!dst->user_cpus_ptr)
2491+
return -ENOMEM;
2492+
2493+
cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
2494+
return 0;
2495+
}
2496+
2497+
void release_user_cpus_ptr(struct task_struct *p)
2498+
{
2499+
kfree(p->user_cpus_ptr);
2500+
p->user_cpus_ptr = NULL;
2501+
}
2502+
24832503
/*
24842504
* This function is wildly self concurrent; here be dragons.
24852505
*

0 commit comments

Comments
 (0)