lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <eabacc6f-c7fb-ff33-26d1-271537fb4760@inria.fr>
Date:   Wed, 22 Mar 2023 11:00:41 +0100 (CET)
From:   Julia Lawall <julia.lawall@...ia.fr>
To:     Alex Elder <elder@...e.org>
cc:     Menna Mahmoud <eng.mennamahmoud.mm@...il.com>,
        gregkh@...uxfoundation.org, outreachy@...ts.linux.dev,
        johan@...nel.org, elder@...nel.org, linux-kernel@...r.kernel.org,
        linux-staging@...ts.linux.dev
Subject: Re: [PATCH v2] staging: greybus: use inline function for macros

Greg raised the question of whether the inline function is really as
efficient as a macro.

I tried the following definitions:

#define to_gbphy_dev(d) container_of(d, struct gbphy_device, dev)

static inline struct gbphy_device *extra_to_gbphy_dev(const struct device *_dev)
{
       return container_of(_dev, struct gbphy_device, dev);
}

And the following uses:

ssize_t macro_protocol_id_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
{
        struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);

        return sprintf(buf, "%c macro 0x%02x\n", *buf, gbphy_dev->cport_desc->protocol_id);
}
ssize_t extra_protocol_id_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
        struct gbphy_device *gbphy_dev = extra_to_gbphy_dev(dev);

        return sprintf(buf, "extra 0x%02x %c\n", gbphy_dev->cport_desc->protocol_id, *buf);
}

They are a little bit different to avoid too much compiler optimization.

After doing make drivers/staging/greybus/gbphy.s, I get similar looking
code in both cases:

Macro version:

        .type   macro_protocol_id_show, @function
macro_protocol_id_show:
        endbr64
1:      call    __fentry__
        .section __mcount_loc, "a",@progbits
        .quad 1b
        .previous
        pushq   %rbp    #
        movq    %rdx, %rbp      # tmp96, buf
        pushq   %rbx    #
# drivers/staging/greybus/gbphy.c:40: {
        movq    %rdi, %rbx      # tmp95, dev
# drivers/staging/greybus/gbphy.c:43:   return sprintf(buf, "%c macro 0x%02x\n", *buf, gbphy_dev->cport_desc->protocol_id);
        call    __sanitizer_cov_trace_pc        #
# drivers/staging/greybus/gbphy.c:43:   return sprintf(buf, "%c macro 0x%02x\n", *buf, gbphy_dev->cport_desc->protocol_id);
        movq    -32(%rbx), %rax # MEM[(struct gbphy_device *)dev_7(D) + -40B].cport_desc, MEM[(struct gbphy_device *)dev_7(D) + -40B].cport_desc
# drivers/staging/greybus/gbphy.c:43:   return sprintf(buf, "%c macro 0x%02x\n", *buf, gbphy_dev->cport_desc->protocol_id);
        movzbl  0(%rbp), %edx   # *buf_9(D), *buf_9(D)
        movq    %rbp, %rdi      # buf,
        movq    $.LC18, %rsi    #,
        movzbl  3(%rax), %ecx   # _1->protocol_id, _1->protocol_id
        call    sprintf #
# drivers/staging/greybus/gbphy.c:44: }
        movl    $13, %eax       #,
        popq    %rbx    #
        popq    %rbp    #
        jmp     __x86_return_thunk
        .size   macro_protocol_id_show, .-macro_protocol_id_show

Function version:

        .type   extra_protocol_id_show, @function
extra_protocol_id_show:
        endbr64
1:      call    __fentry__
        .section __mcount_loc, "a",@progbits
        .quad 1b
        .previous
        pushq   %rbp    #
        movq    %rdx, %rbp      # tmp96, buf
        pushq   %rbx    #
# drivers/staging/greybus/gbphy.c:47: {
        movq    %rdi, %rbx      # tmp95, dev
# drivers/staging/greybus/gbphy.c:50:   return sprintf(buf, "extra 0x%02x %c\n", gbphy_dev->cport_desc->protocol_id, *buf);
        call    __sanitizer_cov_trace_pc        #
# drivers/staging/greybus/gbphy.c:50:   return sprintf(buf, "extra 0x%02x %c\n", gbphy_dev->cport_desc->protocol_id, *buf);
        movq    -32(%rbx), %rax # MEM[(struct gbphy_device *)dev_8(D) + -40B].cport_desc, MEM[(struct gbphy_device *)dev_8(D) + -40B].cport_desc
# drivers/staging/greybus/gbphy.c:50:   return sprintf(buf, "extra 0x%02x %c\n", gbphy_dev->cport_desc->protocol_id, *buf);
        movzbl  0(%rbp), %ecx   # *buf_9(D), *buf_9(D)
        movq    %rbp, %rdi      # buf,
        movq    $.LC19, %rsi    #,
        movzbl  3(%rax), %edx   # _3->protocol_id, _3->protocol_id
        call    sprintf #
# drivers/staging/greybus/gbphy.c:51: }
        movl    $13, %eax       #,
        popq    %rbx    #
        popq    %rbp    #
        jmp     __x86_return_thunk
        .size   extra_protocol_id_show, .-extra_protocol_id_show

Both seem to access the memory directly.  Maybe the example is too simple,
and the compiler is more likely to optimize aggressively?

julia

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ