Messages in this thread Patch in this message | | | From | Rusty Russell <> | Subject | Re: [PULL] Trivial macros to help cpumask conversion in linux-next: tsk_cpumask and mm_cpumask | Date | Wed, 4 Mar 2009 11:46:22 +1030 |
| |
On Wednesday 04 March 2009 08:42:09 Linus Torvalds wrote: > > On Tue, 3 Mar 2009, Rusty Russell wrote: > > > > Rusty Russell (2): > > cpumask: tsk_cpumask for accessing the struct task_struct's cpus_allowed. > > cpumask: mm_cpumask for accessing the struct mm_struct's cpu_vm_mask. > > I really want to know the _reason_ for things like this, not just a > trivial patch that adds a stupid macro "for the future".
Sorry, should have been more explicit.
cpumask_t -> cpumask_var_t breaks all the users (since it looks like a pointer). So I decided wrappers were in order while I feed the conversion patches via all the arch maintainers & linux-next.
(In fact, we probably want to use a dangling bitmap in these cases, rather than a double alloc for CONFIG_CPUMASK_OFFSTACK=y, tho various places use sizeof(struct task_struct) making this a little nasty).
Not that we *really* care about the size of these structs; but it does allow us to make 'struct cpumask' undefined for CONFIG_CPUMASK_OFFSTACK=y so noone can accidentally create one on the stack, or use *mask1 = *mask2.
FYI, here's the final conversion patch:
cpumask: convert task_struct cpus_allowed to dangling bitmap.
Rather than use the standard [] or [0] array, I truncate the struct when CONFIG_CPUMASK_OFFSTACK=y. This avoids complications with INIT_TASK and sizeof(struct task_struct).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> --- include/linux/init_task.h | 2 +- include/linux/sched.h | 7 +++++-- kernel/fork.c | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/include/linux/init_task.h b/include/linux/init_task.h --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -136,7 +136,7 @@ extern struct cred init_cred; .static_prio = MAX_PRIO-20, \ .normal_prio = MAX_PRIO-20, \ .policy = SCHED_NORMAL, \ - .cpus_allowed = CPU_MASK_ALL, \ + .cpus_allowed = CPU_BITS_ALL, \ .mm = NULL, \ .active_mm = &init_mm, \ .se = { \ diff --git a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1135,7 +1135,6 @@ struct task_struct { #endif unsigned int policy; - cpumask_t cpus_allowed; #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; @@ -1400,10 +1399,14 @@ struct task_struct { /* state flags for use by tracers */ unsigned long trace; #endif + + /* This has to go at the end: if CONFIG_CPUMASK_OFFSTACK=y, only + * nr_cpu_ids bits will actually be allocated. */ + DECLARE_BITMAP(cpus_allowed, CONFIG_NR_CPUS); }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ -#define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) +#define tsk_cpumask(tsk) (to_cpumask((tsk)->cpus_allowed)) /* * Priority of a process goes from 0..MAX_PRIO-1, valid RT diff --git a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c +++ b/kernel/fork.c @@ -173,9 +173,25 @@ void __init fork_init(unsigned long memp #ifndef ARCH_MIN_TASKALIGN #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES #endif + unsigned int task_size; + +#ifdef CONFIG_CPUMASK_OFFSTACK + /* + * Restrict task_struct allocations so cpus_allowed is only + * nr_cpu_ids long. cpus_allowed must be a NR_CPUS bitmap at + * end for this to work. + */ + BUILD_BUG_ON(offsetof(struct task_struct, cpus_allowed) + + BITS_TO_LONGS(CONFIG_NR_CPUS)*sizeof(long) + != sizeof(struct task_struct)); + task_size = offsetof(struct task_struct, cpus_allowed) + + BITS_TO_LONGS(nr_cpu_ids) * sizeof(long); +#else + task_size = sizeof(struct task_struct); +#endif /* create a slab on which task_structs can be allocated */ task_struct_cachep = - kmem_cache_create("task_struct", sizeof(struct task_struct), + kmem_cache_create("task_struct", task_size, ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); #endif
| |