X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fmheap.c;h=0c72c888498a053a42d85885b0d67adb3b16011a;hb=9c949e72a473195c10a1c1caf503db9467c93f9a;hp=fceca95ff7dab4f42ab51bbe1fcd1b1fb6e4b90b;hpb=7e12d949a346d2e69afb7a8029c0099b5f131b25;p=vpp.git diff --git a/src/vppinfra/mheap.c b/src/vppinfra/mheap.c index fceca95ff7d..0c72c888498 100644 --- a/src/vppinfra/mheap.c +++ b/src/vppinfra/mheap.c @@ -663,12 +663,28 @@ mheap_get_aligned (void *v, return v; } - /* Round requested size. */ + /* + * Round requested size. + * + * Step 1: round up to the minimum object size. + * Step 2: round up to a multiple of the user data size (e.g. 4) + * Step 3: if non-trivial alignment requested, round up + * so that the object precisely fills a chunk + * as big as the alignment request. + * + * Step 3 prevents the code from going into "bin search hyperspace": + * looking at a huge number of fractional remainder chunks, none of which + * will satisfy the alignment constraint. This fixes an allocator + * performance issue when one requests a large number of 16 byte objects + * aligned to 64 bytes, to name one variation on the theme. + */ n_user_data_bytes = clib_max (n_user_data_bytes, MHEAP_MIN_USER_DATA_BYTES); n_user_data_bytes = round_pow2 (n_user_data_bytes, STRUCT_SIZE_OF (mheap_elt_t, user_data[0])); - + if (align > MHEAP_ELT_OVERHEAD_BYTES) + n_user_data_bytes = clib_max (n_user_data_bytes, + align - MHEAP_ELT_OVERHEAD_BYTES); if (!v) v = mheap_alloc (0, 64 << 20);