Skip to content

mm/mempool: Reuse same-size blocks in realloc - #21037

Open
anchao wants to merge 1 commit into
apache:masterfrom
anchao:26102710
Open

anchao wants to merge 1 commit into
apache:masterfrom
anchao:26102710

Conversation

@anchao

@anchao anchao commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Optimize mempool_multiple_realloc() by returning the original block when
the requested size still fits in the current multiple mempool block.

The previous implementation always allocated a new block, copied data, and
freed the old block even when the new size stayed within the same pool size
class. This change adds an in-place fast path for normal mempool blocks.

Details

The fast path is used only when:

  • the requested size is non-zero
  • the requested size is no larger than the current pool block size
  • the old pointer is the base address of the mempool block

The base-address check keeps existing behavior for interior pointers such as
mempool_multiple_memalign() results, where the available tail space may be
smaller than the full pool block.

Benefits

  • Avoids unnecessary allocation
  • Avoids unnecessary data copy
  • Avoids unnecessary free/requeue work
  • Reduces lock and allocator churn for same-size-class reallocations

Testing

sim/nsh

Return the original block when a multiple mempool realloc request still
fits in the current pool block.  This avoids unnecessary allocation, copy,
and free work for same size class reallocations.

Signed-off-by: chao an <anchao.archer@bytedance.com>
@github-actions github-actions Bot added Area: Memory Management Memory Management issues Size: XS The size of the change in this PR is very small labels Oct 27, 2026
@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

(((FAR char *)kasan_clear_tag(oldblk) -
((FAR char *)kasan_clear_tag(dict->addr) +
mpool->minpoolsize)) % MEMPOOL_REALBLOCKSIZE(dict->pool));
if (size > 0 && size <= dict->pool->blocksize && blkbase == oldblk)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why need check blkbase == oldblk

@casaroli casaroli left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The red check is at lines 731 and 750, outside this change. #21035 fixes them: rebase after it merges.

(((FAR char *)kasan_clear_tag(oldblk) -
((FAR char *)kasan_clear_tag(dict->addr) +
mpool->minpoolsize)) % MEMPOOL_REALBLOCKSIZE(dict->pool));
if (size > 0 && size <= dict->pool->blocksize && blkbase == oldblk)

@casaroli casaroli Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This also keeps the block when the size shrinks to a smaller pool: realloc(p, 16) on a 512-byte block now keeps the 512-byte block, where before the data moved to the 16-byte pool.

Fix: reuse the block only when mempool_multiple_find(mpool, size) == dict->pool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Memory Management Memory Management issues Size: XS The size of the change in this PR is very small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants