[ovs-dev] [PATCH branch-2.7 10/25] datapath: netns: make struct pernet_operations::id unsigned int.

Jarno Rajahalme jarno at ovn.org
Wed Mar 15 23:31:14 UTC 2017


From: Alexey Dobriyan <adobriyan at gmail.com>

Upstream commit:
    commit c7d03a00b56fc23c3a01a8353789ad257363e281
    Author: Alexey Dobriyan <adobriyan at gmail.com>
    Date:   Thu Nov 17 04:58:21 2016 +0300

    netns: make struct pernet_operations::id unsigned int

    Make struct pernet_operations::id unsigned.

    There are 2 reasons to do so:

    1)
    This field is really an index into an zero based array and
    thus is unsigned entity. Using negative value is out-of-bound
    access by definition.

    2)
    On x86_64 unsigned 32-bit data which are mixed with pointers
    via array indexing or offsets added or subtracted to pointers
    are preffered to signed 32-bit data.

    "int" being used as an array index needs to be sign-extended
    to 64-bit before being used.

            void f(long *p, int i)
            {
                    g(p[i]);
            }

      roughly translates to

            movsx   rsi, esi
            mov     rdi, [rsi+...]
            call    g

    MOVSX is 3 byte instruction which isn't necessary if the variable is
    unsigned because x86_64 is zero extending by default.

    Now, there is net_generic() function which, you guessed it right, uses
    "int" as an array index:

            static inline void *net_generic(const struct net *net, int id)
            {
                    ...
                    ptr = ng->ptr[id - 1];
                    ...
            }

    And this function is used a lot, so those sign extensions add up.

    Patch snipes ~1730 bytes on allyesconfig kernel (without all junk
    messing with code generation):

            add/remove: 0/0 grow/shrink: 70/598 up/down: 396/-2126 (-1730)

    Unfortunately some functions actually grow bigger.
    This is a semmingly random artefact of code generation with register
    allocator being used differently. gcc decides that some variable
    needs to live in new r8+ registers and every access now requires REX
    prefix. Or it is shifted into r12, so [r12+0] addressing mode has to be
    used which is longer than [r8]

    However, overall balance is in negative direction:

            add/remove: 0/0 grow/shrink: 70/598 up/down: 396/-2126 (-1730)
            function                                     old     new   delta
            nfsd4_lock                                  3886    3959     +73
            tipc_link_build_proto_msg                   1096    1140     +44
            mac80211_hwsim_new_radio                    2776    2808     +32
            tipc_mon_rcv                                1032    1058     +26
            svcauth_gss_legacy_init                     1413    1429     +16
            tipc_bcbase_select_primary                   379     392     +13
            nfsd4_exchange_id                           1247    1260     +13
            nfsd4_setclientid_confirm                    782     793     +11
                    ...
            put_client_renew_locked                      494     480     -14
            ip_set_sockfn_get                            730     716     -14
            geneve_sock_add                              829     813     -16
            nfsd4_sequence_done                          721     703     -18
            nlmclnt_lookup_host                          708     686     -22
            nfsd4_lockt                                 1085    1063     -22
            nfs_get_client                              1077    1050     -27
            tcf_bpf_init                                1106    1076     -30
            nfsd4_encode_fattr                          5997    5930     -67
            Total: Before=154856051, After=154854321, chg -0.00%

    Signed-off-by: Alexey Dobriyan <adobriyan at gmail.com>
    Signed-off-by: David S. Miller <davem at davemloft.net>

[Committer notes]

It looks like changing the type of this doesn't affect the build on older
kernels, so we can just make the change. I didn't go through all of the
compat code to update the net_id variables there as none of that code should
be enabled on kernels with this patch.

Upstream: c7d03a00b56f ("netns: make struct pernet_operations::id unsigned int")
Signed-off-by: Joe Stringer <joe at ovn.org>
Acked-by: Jarno Rajahalme <jarno at ovn.org>
Signed-off-by: Jarno Rajahalme <jarno at ovn.org>
---
 datapath/datapath.c | 2 +-
 datapath/datapath.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 64cd781..78fcc1c 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -61,7 +61,7 @@
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
 
-int ovs_net_id __read_mostly;
+unsigned int ovs_net_id __read_mostly;
 
 static struct genl_family dp_packet_genl_family;
 static struct genl_family dp_flow_genl_family;
diff --git a/datapath/datapath.h b/datapath/datapath.h
index 22bbaac..5e5c1c4 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -145,7 +145,7 @@ struct ovs_net {
 	bool xt_label;
 };
 
-extern int ovs_net_id;
+extern unsigned int ovs_net_id;
 void ovs_lock(void);
 void ovs_unlock(void);
 
-- 
2.1.4



More information about the dev mailing list