All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>, Mike Travis <travis@sgi.com>,
	linux-kernel@vger.kernel.org
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	[thread overview]
Message-ID: <200903041146.22992.rusty@rustcorp.com.au> (raw)
In-Reply-To: <alpine.LFD.2.00.0903031411320.3111@localhost.localdomain>

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
 

      reply	other threads:[~2009-03-04  1:16 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-03  6:05 [PULL] Trivial macros to help cpumask conversion in linux-next: tsk_cpumask and mm_cpumask Rusty Russell
2009-03-03 22:12 ` Linus Torvalds
2009-03-04  1:16   ` Rusty Russell [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200903041146.22992.rusty@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=torvalds@linux-foundation.org \
    --cc=travis@sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.