Skip to content

Commit 720abae

Browse files
kiryltorvalds
authored andcommitted
rcu: force alignment on struct callback_head/rcu_head
Make struct callback_head aligned to size of pointer. On most architectures it happens naturally due ABI requirements, but some architectures (like CRIS) have weird ABI and we need to ask it explicitly. The alignment is required to guarantee that bits 0 and 1 of @next will be clear under normal conditions -- as long as we use call_rcu(), call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback. This guarantee is important for few reasons: - future call_rcu_lazy() will make use of lower bits in the pointer; - the structure shares storage spacer in struct page with @compound_head, which encode PageTail() in bit 0. The guarantee is needed to avoid false-positive PageTail(). False postive PageTail() caused crash on crisv32[1]. It happend due misaligned task_struct->rcu, which was byte-aligned. [1] http://lkml.kernel.org/r/55FAEA67.9000102@roeck-us.net Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reported-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Mikael Starvik <starvik@axis.com> Cc: Jesper Nilsson <jesper.nilsson@axis.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 262d8a8 commit 720abae

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

include/linux/types.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,25 @@ struct ustat {
205205
* struct callback_head - callback structure for use with RCU and task_work
206206
* @next: next update requests in a list
207207
* @func: actual update function to call after the grace period.
208+
*
209+
* The struct is aligned to size of pointer. On most architectures it happens
210+
* naturally due ABI requirements, but some architectures (like CRIS) have
211+
* weird ABI and we need to ask it explicitly.
212+
*
213+
* The alignment is required to guarantee that bits 0 and 1 of @next will be
214+
* clear under normal conditions -- as long as we use call_rcu(),
215+
* call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback.
216+
*
217+
* This guarantee is important for few reasons:
218+
* - future call_rcu_lazy() will make use of lower bits in the pointer;
219+
* - the structure shares storage spacer in struct page with @compound_head,
220+
* which encode PageTail() in bit 0. The guarantee is needed to avoid
221+
* false-positive PageTail().
208222
*/
209223
struct callback_head {
210224
struct callback_head *next;
211225
void (*func)(struct callback_head *head);
212-
};
226+
} __attribute__((aligned(sizeof(void *))));
213227
#define rcu_head callback_head
214228

215229
typedef void (*rcu_callback_t)(struct rcu_head *head);

0 commit comments

Comments
 (0)