From: Ingo Molnar <mingo@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Hansen <dave@sr71.net>,
tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com,
x86@kernel.org, bp@alien8.de, luto@amacapital.net,
torvalds@linux-foundation.org, linux-kernel@vger.kernel.org
Subject: [PATCH] x86/fpu, bug.h: Move CHECK_MEMBER_AT_END_OF() to a generic header and use it in generic code
Date: Fri, 17 Jul 2015 10:43:32 +0200 [thread overview]
Message-ID: <20150717084332.GB16130@gmail.com> (raw)
In-Reply-To: <20150717083947.GA16130@gmail.com>
* Ingo Molnar <mingo@kernel.org> wrote:
>
> * Peter Zijlstra <peterz@infradead.org> wrote:
>
> > On Thu, Jul 16, 2015 at 12:14:37PM -0700, Dave Hansen wrote:
> > > +++ b/arch/x86/kernel/fpu/init.c 2015-07-16 12:02:15.284280976 -0700
> > > @@ -136,6 +136,45 @@ static void __init fpu__init_system_gene
> > > unsigned int xstate_size;
> > > EXPORT_SYMBOL_GPL(xstate_size);
> > >
> > > +#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
> > > + BUILD_BUG_ON((sizeof(TYPE) - \
> > > + offsetof(TYPE, MEMBER) - \
> > > + sizeof(((TYPE *)0)->MEMBER)) > \
> > > + 0) \
> > > +
> > > +/*
> > > + * We append the 'struct fpu' to the task_struct.
> > > + */
> > > +int __weak arch_task_struct_size(void)
> > > +{
> > > + int task_size = sizeof(struct task_struct);
> > > +
> > > + /*
> > > + * Subtract off the static size of the register state.
> > > + * It potentially has a bunch of padding.
> > > + */
> > > + task_size -= sizeof(((struct task_struct *)0)->thread.fpu.state);
> > > +
> > > + /*
> > > + * Add back the dynamically-calculated register state
> > > + * size.
> > > + */
> > > + task_size += xstate_size;
> > > +
> > > + /*
> > > + * We dynamically size 'struct fpu', so we require that
> > > + * it be at the end of 'thread_struct' and that
> > > + * 'thread_struct' be at the end of 'task_struct'. If
> > > + * you hit a compile error here, check the structure to
> > > + * see if something got added to the end.
> > > + */
> > > + CHECK_MEMBER_AT_END_OF(struct fpu, state);
> > > + CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu);
> > > + CHECK_MEMBER_AT_END_OF(struct task_struct, thread);
> > > +
> > > + return task_size;
> > > +}
> >
> > Since you want these invariants true at all times, maybe put the
> > BUILD_BUG_ON() in generic code instead of x86 specific? That way people
> > poking at other archs are less likely to accidentally break your stuff.
>
> Yeah.
The patch below implements this. Only build tested.
Thanks,
Ingo
===============>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/kernel/fpu/init.c | 17 ++---------------
include/linux/bug.h | 4 ++++
kernel/fork.c | 18 ++++++++++++++++++
3 files changed, 24 insertions(+), 15 deletions(-)
Index: tip/arch/x86/kernel/fpu/init.c
===================================================================
--- tip.orig/arch/x86/kernel/fpu/init.c
+++ tip/arch/x86/kernel/fpu/init.c
@@ -136,16 +136,10 @@ static void __init fpu__init_system_gene
unsigned int xstate_size;
EXPORT_SYMBOL_GPL(xstate_size);
-#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
- BUILD_BUG_ON((sizeof(TYPE) - \
- offsetof(TYPE, MEMBER) - \
- sizeof(((TYPE *)0)->MEMBER)) > \
- 0) \
-
/*
* We append the 'struct fpu' to the task_struct.
*/
-int __weak arch_task_struct_size(void)
+int arch_task_struct_size(void)
{
int task_size = sizeof(struct task_struct);
@@ -161,16 +155,9 @@ int __weak arch_task_struct_size(void)
*/
task_size += xstate_size;
- /*
- * We dynamically size 'struct fpu', so we require that
- * it be at the end of 'thread_struct' and that
- * 'thread_struct' be at the end of 'task_struct'. If
- * you hit a compile error here, check the structure to
- * see if something got added to the end.
- */
+ /* Build time FPU structure layout debug checks: */
CHECK_MEMBER_AT_END_OF(struct fpu, state);
CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu);
- CHECK_MEMBER_AT_END_OF(struct task_struct, thread);
return task_size;
}
Index: tip/include/linux/bug.h
===================================================================
--- tip.orig/include/linux/bug.h
+++ tip/include/linux/bug.h
@@ -85,6 +85,10 @@ struct pt_regs;
#endif /* __CHECKER__ */
+/* Enforce that 'MEMBER' is the last field of 'TYPE': */
+#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
+ BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER))
+
#ifdef CONFIG_GENERIC_BUG
#include <asm-generic/bug.h>
Index: tip/kernel/fork.c
===================================================================
--- tip.orig/kernel/fork.c
+++ tip/kernel/fork.c
@@ -287,8 +287,26 @@ static void set_max_threads(unsigned int
max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
}
+#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
+ BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER))
+
+/*
+ * This function can be overridden by the architecture to support dynamic sizing
+ * of the task_struct:
+ */
int __weak arch_task_struct_size(void)
{
+ /*
+ * Build-time checks for structure layout constraints:
+ *
+ * On some architectures we dynamically size 'struct thread_struct',
+ * so we require that it be at the end of 'task_struct'.
+ *
+ * If you hit a compile error here, check the structure to
+ * see if something got added to the end.
+ */
+ CHECK_MEMBER_AT_END_OF(struct task_struct, thread);
+
return sizeof(struct task_struct);
}
next prev parent reply other threads:[~2015-07-17 8:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-16 19:14 [RFC][PATCH] x86, fpu: dynamically allocate 'struct fpu' Dave Hansen
2015-07-16 19:25 ` Andy Lutomirski
2015-07-16 21:29 ` Dave Hansen
2015-07-17 8:45 ` Ingo Molnar
2015-07-17 9:31 ` [PATCH] x86/fpu, sched: Introduce CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT and use it on x86 Ingo Molnar
2015-07-16 22:35 ` [RFC][PATCH] x86, fpu: dynamically allocate 'struct fpu' Peter Zijlstra
2015-07-17 8:39 ` Ingo Molnar
2015-07-17 8:43 ` Ingo Molnar [this message]
2015-07-16 22:42 ` H. Peter Anvin
2015-07-16 22:57 ` Andy Lutomirski
2015-07-18 3:40 ` Ingo Molnar
2015-07-17 8:23 ` Ingo Molnar
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=20150717084332.GB16130@gmail.com \
--to=mingo@kernel.org \
--cc=bp@alien8.de \
--cc=dave@sr71.net \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=x86@kernel.org \
/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.