Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Some memory optimizations #15250

Merged

Conversation

ton31337
Copy link
Member

@ton31337 ton31337 commented Jan 29, 2024

Some low-hanging fruits to optimize the memory, especially for attr, nlri data structures. Looks like we can safe ~100Mb of memory easily for 2 BGP full tables.

```
struct bgp_notify {
	uint8_t                    code;                 /*     0     1 */
	uint8_t                    subcode;              /*     1     1 */
	bgp_size_t                 length;               /*     2     2 */
	_Bool                      hard_reset;           /*     4     1 */

	/* XXX 3 bytes hole, try to pack */

	char *                     data;                 /*     8     8 */
	uint8_t *                  raw_data;             /*    16     8 */

	/* size: 24, cachelines: 1, members: 6 */
	/* sum members: 21, holes: 1, sum holes: 3 */
	/* last cacheline: 24 bytes */
};   /* saved 16 bytes! */
```

Signed-off-by: Donatas Abraitis <[email protected]>
```
struct bgp_nlri {
	uint16_t                   afi;                  /*     0     2 */
	uint8_t                    safi;                 /*     2     1 */

	/* XXX 1 byte hole, try to pack */

	bgp_size_t                 length;               /*     4     2 */

	/* XXX 2 bytes hole, try to pack */

	uint8_t *                  nlri;                 /*     8     8 */

	/* size: 16, cachelines: 1, members: 4 */
	/* sum members: 13, holes: 2, sum holes: 3 */
	/* last cacheline: 16 bytes */
};   /* saved 8 bytes! */
```

Signed-off-by: Donatas Abraitis <[email protected]>
```
struct attr {
	struct aspath *            aspath;               /*     0     8 */
	struct community *         community;            /*     8     8 */
	long unsigned int          refcnt;               /*    16     8 */
	_uint64_t                  flag;                 /*    24     8 */
	struct in_addr             nexthop;              /*    32     4 */
	uint32_t                   med;                  /*    36     4 */
	uint32_t                   local_pref;           /*    40     4 */
	ifindex_t                  nh_ifindex;           /*    44     4 */
	uint8_t                    origin;               /*    48     1 */
	uint8_t                    es_flags;             /*    49     1 */
	uint8_t                    router_flag;          /*    50     1 */
	uint8_t                    default_gw;           /*    51     1 */
	enum pta_type              pmsi_tnl_type;        /*    52     4 */
	uint32_t                   rmap_change_flags;    /*    56     4 */
	struct in6_addr            mp_nexthop_global;    /*    60    16 */
	/* --- cacheline 1 boundary (64 bytes) was 12 bytes ago --- */
	struct in6_addr            mp_nexthop_local;     /*    76    16 */
	ifindex_t                  nh_lla_ifindex;       /*    92     4 */
	struct ecommunity *        ecommunity;           /*    96     8 */
	struct ecommunity *        ipv6_ecommunity;      /*   104     8 */
	struct lcommunity *        lcommunity;           /*   112     8 */
	struct cluster_list *      cluster1;             /*   120     8 */
	/* --- cacheline 2 boundary (128 bytes) --- */
	struct transit *           transit;              /*   128     8 */
	struct in_addr             mp_nexthop_global_in; /*   136     4 */
	struct in_addr             aggregator_addr;      /*   140     4 */
	struct in_addr             originator_id;        /*   144     4 */
	uint32_t                   weight;               /*   148     4 */
	as_t                       aggregator_as;        /*   152     4 */
	uint8_t                    mp_nexthop_len;       /*   156     1 */
	uint8_t                    mp_nexthop_prefer_global; /*   157     1 */
	uint8_t                    sticky;               /*   158     1 */
	uint8_t                    distance;             /*   159     1 */
	uint16_t                   encap_tunneltype;     /*   160     2 */
	uint8_t                    df_alg;               /*   162     1 */

	/* XXX 1 byte hole, try to pack */

	route_tag_t                tag;                  /*   164     4 */
	uint32_t                   label_index;          /*   168     4 */
	mpls_label_t               label;                /*   172     4 */
	struct bgp_attr_srv6_vpn * srv6_vpn;             /*   176     8 */
	struct bgp_attr_srv6_l3vpn * srv6_l3vpn;         /*   184     8 */
	/* --- cacheline 3 boundary (192 bytes) --- */
	struct bgp_attr_encap_subtlv * encap_subtlvs;    /*   192     8 */
	struct bgp_attr_encap_subtlv * vnc_subtlvs;      /*   200     8 */
	struct bgp_route_evpn      evpn_overlay;         /*   208    36 */
	uint32_t                   mm_seqnum;            /*   244     4 */
	uint32_t                   mm_sync_seqnum;       /*   248     4 */
	struct ethaddr             rmac;                 /*   252     6 */
	/* --- cacheline 4 boundary (256 bytes) was 2 bytes ago --- */
	uint16_t                   df_pref;              /*   258     2 */
	uint32_t                   rmap_table_id;        /*   260     4 */
	uint32_t                   link_bw;              /*   264     4 */
	esi_t                      esi;                  /*   268    10 */

	/* XXX 2 bytes hole, try to pack */

	uint32_t                   srte_color;           /*   280     4 */
	uint32_t                   otc;                  /*   284     4 */
	enum nexthop_types_t       nh_type;              /*   288     4 */
	enum blackhole_type        bh_type;              /*   292     4 */
	_uint64_t                  aigp_metric;          /*   296     8 */

	/* size: 304, cachelines: 5, members: 53 */
	/* sum members: 301, holes: 2, sum holes: 3 */
	/* last cacheline: 48 bytes */
};   /* saved 16 bytes! */
```

Signed-off-by: Donatas Abraitis <[email protected]>
```
struct bgp_static {
        int                        backdoor;             /*     0     4 */
        uint32_t                   label_index;          /*     4     4 */
        uint8_t                    valid;                /*     8     1 */

        /* XXX 1 byte hole, try to pack */

        uint16_t                   encap_tunneltype;     /*    10     2 */
        uint32_t                   igpmetric;            /*    12     4 */
        struct in_addr             igpnexthop;           /*    16     4 */
        uint32_t                   atomic;               /*    20     4 */
        struct {
                char *             name;                 /*    24     8 */
                struct route_map * map;                  /*    32     8 */
        } rmap;                                          /*    24    16 */
        struct prefix_rd           prd __attribute__((__aligned__(8))); /*    40    16 */
        char *                     prd_pretty;           /*    56     8 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        mpls_label_t               label;                /*    64     4 */

        /* XXX 4 bytes hole, try to pack */

        esi_t *                    eth_s_id;             /*    72     8 */
        struct ethaddr *           router_mac;           /*    80     8 */
        struct prefix              gatewayIp __attribute__((__aligned__(8))); /*    88    56 */

        /* size: 144, cachelines: 3, members: 14 */
        /* sum members: 139, holes: 2, sum holes: 5 */
        /* forced alignments: 2 */
        /* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));   /* saved 8 bytes! */
```

Signed-off-by: Donatas Abraitis <[email protected]>
```
struct bgp_aggregate {
        uint8_t                    summary_only;         /*     0     1 */
        uint8_t                    as_set;               /*     1     1 */
        uint8_t                    origin;               /*     2     1 */
        _Bool                      med_mismatched;       /*     3     1 */
        _Bool                      med_initialized;      /*     4     1 */
        _Bool                      match_med;            /*     5     1 */

        /* XXX 2 bytes hole, try to pack */

        struct {
                char *             name;                 /*     8     8 */
                struct route_map * map;                  /*    16     8 */
        } rmap;                                          /*     8    16 */
        long unsigned int          count;                /*    24     8 */
        long unsigned int          incomplete_origin_count; /*    32     8 */
        long unsigned int          egp_origin_count;     /*    40     8 */
        struct hash *              community_hash;       /*    48     8 */
        struct hash *              ecommunity_hash;      /*    56     8 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        struct hash *              lcommunity_hash;      /*    64     8 */
        struct hash *              aspath_hash;          /*    72     8 */
        struct community *         community;            /*    80     8 */
        struct ecommunity *        ecommunity;           /*    88     8 */
        struct lcommunity *        lcommunity;           /*    96     8 */
        struct aspath *            aspath;               /*   104     8 */
        safi_t                     safi;                 /*   112     4 */
        uint32_t                   med_matched_value;    /*   116     4 */
        char *                     suppress_map_name;    /*   120     8 */
        /* --- cacheline 2 boundary (128 bytes) --- */
        struct route_map *         suppress_map;         /*   128     8 */

        /* size: 136, cachelines: 3, members: 22 */
        /* sum members: 134, holes: 1, sum holes: 2 */
        /* last cacheline: 8 bytes */
};
```

Signed-off-by: Donatas Abraitis <[email protected]>
```
struct bgp_damp_config {
        unsigned int               suppress_value;       /*     0     4 */
        unsigned int               reuse_limit;          /*     4     4 */
        time_t                     max_suppress_time;    /*     8     8 */
        time_t                     half_life;            /*    16     8 */
        unsigned int               reuse_list_size;      /*    24     4 */
        unsigned int               reuse_index_size;     /*    28     4 */
        unsigned int               ceiling;              /*    32     4 */
        unsigned int               decay_rate_per_tick;  /*    36     4 */
        unsigned int               decay_array_size;     /*    40     4 */
        unsigned int               reuse_scale_factor;   /*    44     4 */
        double                     scale_factor;         /*    48     8 */
        double *                   decay_array;          /*    56     8 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        int *                      reuse_index;          /*    64     8 */
        struct bgp_damp_info * *   reuse_list;           /*    72     8 */
        int                        reuse_offset;         /*    80     4 */
        safi_t                     safi;                 /*    84     4 */
        struct bgp_damp_info *     no_reuse_list;        /*    88     8 */
        struct event *             t_reuse;              /*    96     8 */
        afi_t                      afi;                  /*   104     4 */

        /* size: 112, cachelines: 2, members: 19 */
        /* padding: 4 */
        /* last cacheline: 48 bytes */
};   /* saved 8 bytes! */
```

Signed-off-by: Donatas Abraitis <[email protected]>
@ton31337 ton31337 force-pushed the fix/memory_optimizations branch from f47b436 to 4885674 Compare January 30, 2024 06:13
Copy link
Member

@riw777 riw777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, waiting on freeze

@donaldsharp donaldsharp merged commit d633a81 into FRRouting:master Jan 30, 2024
9 checks passed
@donaldsharp
Copy link
Member

2 feeds saved me 100mb of bgpd size.

@ton31337 ton31337 deleted the fix/memory_optimizations branch January 30, 2024 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants