• David Howells's avatar
    MN10300: Fix the PERCPU() alignment to allow for workqueues · 52605627
    David Howells authored
    In the MN10300 arch, we occasionally see an assertion being tripped in
    alloc_cwqs() at the following line:
    
            /* just in case, make sure it's actually aligned */
      --->  BUG_ON(!IS_ALIGNED(wq->cpu_wq.v, align));
            return wq->cpu_wq.v ? 0 : -ENOMEM;
    
    The values are:
    
            wa->cpu_wq.v => 0x902776e0
            align => 0x100
    
    and align is calculated by the following:
    
            const size_t align = max_t(size_t, 1 << WORK_STRUCT_FLAG_BITS,
                                       __alignof__(unsigned long long));
    
    This is because the pointer in question (wq->cpu_wq.v) loses some of its
    lower bits to control flags, and so the object it points to must be
    sufficiently aligned to avoid the need to use those bits for pointing to
    things.
    
    Currently, 4 control bits and 4 colour bits are used in normal
    circumstances, plus a debugging bit if debugging is set.  This requires
    the cpu_workqueue_struct struct to be at least 256 bytes aligned (or 512
    bytes aligned with debugging).
    
    PERCPU() alignment on MN13000, however, is only 32 bytes as set in
    vmlinux.lds.S.  So we set this to PAGE_SIZE (4096) to match most other
    arches and stick a comment in alloc_cwqs() for anyone else who triggers
    the assertion.
    Reported-by: default avatarAkira Takeuchi <takeuchi.akr@jp.panasonic.com>
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Acked-by: default avatarMark Salter <msalter@redhat.com>
    Cc: Tejun Heo <tj@kernel.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    52605627
vmlinux.lds.S 2.07 KB