Messages in this thread | | | From | Nicholas Mc Guire <> | Subject | [PATCH 0/3 V2] time: use __builtin_constant_p() in msecs_to_jiffies | Date | Sun, 12 Apr 2015 14:13:32 +0200 |
| |
In the overall kernel source there currently are 2544 msecs_to_jiffies 126 usecs_to_jiffies and a few places that are using var * HZ / 1000 constructs which are not always safe (no check of corner cases) and should be switched to msecs_to_jiffies (roughly 25 left). Allowing gcc to fold constants for these calls that in most cases are passing in constants (roughly 95%) has some potential to improve performance (and should save a few bytes).
size impact is marginal and for Powerpc it is actually a slight increase.
As the changes to the top level Kbuild will impact every architecture this is probably not enough - but I think suitable for a first review
Once this is clean a patch for usecs_to_jiffies will be provided as well
The patch set: 0001 moves timeconst.h from kernel/time/ to include/generated/ and makes it available early enough so that the build can use the constants for msecs_to_jiffies 0002 rename msecs_to_jiffies() to __msecs_to_jiffies() move the common HZ range specific #ifdef'ed code into a inline helper and #ifdef the variant to use. This allows to re-use the helpers in both the const and non-const variant of msecs_to_jiffies() modified msecs_to_jiffies() to checks for constant via call to __builtin_constant_p() and call __msecs_to_jiffies() if it can't determine that the argument is constant. 0003 documentation update and reformatting to kernel-doc format for msecs_to_jiffies() and __msecs_to_jiffies() - for the helpers its left as comments.
Verification:
kernel configs tested are defconfigs with e.g. make x86_64_defconfig + CONFIG_TEST_LKM=m, GCONFIG_HZ_300=y. CONFIG_HZ=300
check kernel/softirq.c #define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) used in __do_softirq() is folded into a single addq $1, %rax conversely kernel/sched/core.c:sched_rr_handler() is not constant and is a full call __msecs_to_jiffies
added the test-case proposed by Joe Perches <joe@perches.com> into lib/test_module.c:test_module_init() <snip> unsigned int m; for (m = 10; m < 200; m += 10) pr_info("msecs_to_jiffies(%u) is %lu\n", m, msecs_to_jiffies(m)); pr_info("msecs_to_jiffies(%u) is %lu\n", 10, msecs_to_jiffies(10)); pr_info("msecs_to_jiffies(%u) is %lu\n", 100, msecs_to_jiffies(100)); pr_info("msecs_to_jiffies(%u) is %lu\n", 1000, msecs_to_jiffies(1000)); <snip>
without the patch applied: test_module_init: pushq %rbp # movq %rsp, %rbp #, pushq %rbx # movl $10, %ebx #, m pushq %rcx # .L2: movl %ebx, %edi # m, call msecs_to_jiffies # movl %ebx, %esi # m, movq %rax, %rdx # D.14503, movq $.LC0, %rdi #, xorl %eax, %eax # addl $10, %ebx #, m call printk # cmpl $200, %ebx #, m jne .L2 #, movl $10, %edi #, <--- msecs_to_jiffies(10) call msecs_to_jiffies # <--- runtime conversion movl $10, %esi #, movq %rax, %rdx # D.14504, movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movl $100, %edi #, call msecs_to_jiffies # movl $100, %esi #, movq %rax, %rdx # D.14505, movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movl $1000, %edi #, call msecs_to_jiffies # movl $1000, %esi #, movq %rax, %rdx # D.14506, movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movq $.LC1, %rdi #, xorl %eax, %eax # call printk # popq %rdx # popq %rbx # xorl %eax, %eax # popq %rbp # ret
with the patch applied: test_module_init: pushq %rbp # movq %rsp, %rbp #, pushq %rbx # movl $10, %ebx #, m pushq %rcx # .L2: movl %ebx, %edi # m, call __msecs_to_jiffies # movl %ebx, %esi # m, movq %rax, %rdx # D.14545, movq $.LC0, %rdi #, xorl %eax, %eax # addl $10, %ebx #, m call printk # cmpl $200, %ebx #, m jne .L2 #, movl $3, %edx #, <--- msecs_to_jiffies(10) == 3 jiffies movl $10, %esi #, <--- const 10 passed to printk movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movl $30, %edx #, movl $100, %esi #, movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movl $300, %edx #, movl $1000, %esi #, movq $.LC0, %rdi #, xorl %eax, %eax # call printk # movq $.LC1, %rdi #, xorl %eax, %eax # call printk # popq %rdx # popq %rbx # xorl %eax, %eax # popq %rbp # ret
| |