1

I was using perf top to profile a process which running on arm-linux, and the result shown like below:

 4.27%  [vectors]             [.] 0x00000fc4                      
 3.84%  [kernel]              [k] _raw_spin_unlock_irqrestore     
 2.30%  [kernel]              [k] _raw_spin_unlock_irq            
 1.94%  libc-2.20.so          [.] 0x0007c35c                      
 1.91%  [vectors]             [.] 0x00000fd8                      
 1.56%  libGLESv2.so.1.9.6.0  [.] 0x0003a5e0                      
 1.34%  libGLESv2.so.1.9.6.0  [.] 0x0003a5cc                      
 0.91%  [omapdrm_pvr]         [k] _SegmentListInsert              
 0.87%  libpthread-2.20.so    [.] 0x0000aee4                      
 0.82%  libc-2.20.so          [.] 0x00075464                      
 0.76%  libc-2.20.so          [.] 0x0007767c                      
 0.48%  libpthread-2.20.so    [.] 0x000094dc                      
 0.46%  libv8.so.4            [.] 0x0017a058                      
 0.46%  libGLESv2.so.1.9.6.0  [.] 0x0003a420                      
 0.43%  [kernel]              [k] do_nanosleep                    
 0.41%  [kernel]              [k] __copy_from_user                
 0.40%  libc-2.20.so          [.] 0x0007d8a4                      
 0.40%  libpthread-2.20.so    [.] 0x00009480                      
 0.39%  [kernel]              [k] do_vfp                          
 0.39%  librender_engine.so   [.] 0x004d3ff8 

I am wondering what [vectros] may stand for? as I know, it's not a kernel module, however, 0x00000fc4 is a low-end address which should never be used, besides that, 0x00000fc4 seems like the address of arm exception vectors.

any comment is welcomed.

Leonardo Physh
  • 1,443
  • 2
  • 9
  • 12
  • Interrupt handlers seems plausible, even likely. Especially if your workload was interrupt-heavy, which I think is the case based on `_raw_spin_unlock_irq` having significant time. – Peter Cordes Jul 13 '18 at 08:29

1 Answers1

2

This [vectors] is for arm memory range of vectors page, the name is defined in aarch32_setup_vectors_page function of arch/arm64/kernel/vdso.c

#define AARCH32_VECTORS_BASE    0xffff0000
....

int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
{
...
    unsigned long addr = AARCH32_VECTORS_BASE;
    static const struct vm_special_mapping spec = {
        .name   = "[vectors]",
        .pages  = vectors_page,
    };
    ...
    current->mm->context.vdso = (void *)addr;

    /* Map vectors page at the high address. */
    ret = _install_special_mapping(mm, addr, PAGE_SIZE,
                       VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC,
                       &spec);
    ...
}

and in arch_vma_name of arch/arm/kernel/process.c

/*
 * The vectors page is always readable from user space for the
 * atomic helpers. Insert it into the gate_vma so that it is visible
 * through ptrace and /proc/<pid>/mem.
 */
static struct vm_area_struct gate_vma = {
    .vm_start   = 0xffff0000,
    .vm_end     = 0xffff0000 + PAGE_SIZE,
    .vm_flags   = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
};
...

const char *arch_vma_name(struct vm_area_struct *vma)
{
    return is_gate_vma(vma) ? "[vectors]" : NULL;
}

I'm not sure that perf will show correct address for profiling samples in this area, it may be offset inside the section...

Another question about arm's vector page: Vectors page mapping in linux for ARM

"The Exception Vector Table" on arm32 is mapped to 0xffff0000, according to https://doar-e.github.io/blog/2014/04/30/corrupting-arm-evt/ You may check output of cat /proc/self/maps on the platform and dump the page from 0xffff0000 offset with gdb x/1024wx 0xffff0000.

Presentation about newer vdso on arm64 https://blog.linuxplumbersconf.org/2016/ocw/system/presentations/3711/original/LPC_vDSO.pdf

osgx
  • 90,338
  • 53
  • 357
  • 513
  • 1
    I dumped the memory out, it turns out that 0xffff0fc4 was an entry of a loop. --- (gdb) x/1024ih 0xffff0fc0 0xffff0fc0: dmb ish 0xffff0fc4: ldrex r3, [r2] 0xffff0fc8: subs r3, r3, r0 0xffff0fcc: strexeq r3, r1, [r2] 0xffff0fd0: teqeq r3, #1 0xffff0fd4: beq 0xffff0fc4 --- It's more likely that 00000fc4 was the offset inside the section. – Leonardo Physh Jul 16 '18 at 07:30
  • @LeonardoPhysh, thanks! Yes, perf can consider this mapping like it is some file mapped, and will show offsets. Comments says "atomic helpers", and `ldrex` is atomic, so this code may be implementation of some atomic synchronization primitive of [LL/SC style](https://en.wikipedia.org/wiki/Load-link/store-conditional). Check multithread synchronization of the program, and hardware features of your CPU. – osgx Jul 16 '18 at 22:57