• Kevin Brodsky's avatar
    arm64: Refactor vDSO time functions · b33f491f
    Kevin Brodsky authored
    Time functions are directly implemented in assembly in arm64, and it
    is desirable to keep it this way for performance reasons (everything
    fits in registers, so that the stack is not used at all). However, the
    current implementation is quite difficult to read and understand (even
    considering it's assembly).  Additionally, due to the structure of
    __kernel_clock_gettime, which heavily uses conditional branches to
    share code between the different clocks, it is difficult to support a
    new clock without making the branches even harder to follow.
    
    This commit completely refactors the structure of clock_gettime (and
    gettimeofday along the way) while keeping exactly the same algorithms.
    We no longer try to share code; instead, macros provide common
    operations. This new approach comes with a number of advantages:
    - In clock_gettime, clock implementations are no longer interspersed,
      making them much more readable. Additionally, macros only use
      registers passed as arguments or reserved with .req, this way it is
      easy to make sure that registers are properly allocated. To avoid a
      large number of branches in a given execution path, a jump table is
      used; a normal execution uses 3 unconditional branches.
    - __do_get_tspec has been replaced with 2 macros (get_ts_clock_mono,
      get_clock_shifted_nsec) and explicit loading of data from the vDSO
      page. Consequently, clock_gettime and gettimeofday are now leaf
      functions, and saving x30 (lr) is no longer necessary.
    - Variables protected by tb_seq_count are now loaded all at once,
      allowing to merge the seqcnt_read macro into seqcnt_check.
    - For CLOCK_REALTIME_COARSE, removed an unused load of the wall to
      monotonic timespec.
    - For CLOCK_MONOTONIC_COARSE, removed a few shift instructions.
    
    Obviously, the downside of sharing less code is an increase in code
    size. However since the vDSO has its own code page, this does not
    really matter, as long as the size of the DSO remains below 4 kB. For
    now this should be all right:
                        Before  After
      vdso.so size (B)  2776    3000
    Signed-off-by: default avatarKevin Brodsky <kevin.brodsky@arm.com>
    Reviewed-by: default avatarDave Martin <dave.martin@arm.com>
    Acked-by: default avatarWill Deacon <will.deacon@arm.com>
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    b33f491f
gettimeofday.S 6.92 KB