Home / Alt manpages / chmem(8)

  • chmem(8)
  • Admin command
  • linux

Hot-Add or Remove Linux Memory with chmem

You need to hand a VM more RAM without a reboot, or pull a block out before a hot-unplug, and chmem does both. This guide uses lsmem to find the right memory block, then walks through a controlled online or offline change. It takes 10 to 15 minutes, and longer if an offline request fails and needs investigating.

Warning

This is a host-level operation. It can change the memory available to workloads, and it can fail if the kernel cannot migrate or release pages.

  • Which build. The examples describe util-linux chmem: the package man page is from util-linux 2.39.3 and the system package reports 2.39.3-9ubuntu6.6.
  • Mind your PATH. This shell also has a separate Homebrew chmem 2.41.3 earlier in PATH. Use /usr/sbin/chmem for the Ubuntu package this guide covers.

1. Inspect the memory layout

Start with a read-only inventory. The output gives you the address range, current state, block numbers, zones and the memory block size.

$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
RANGE                                  SIZE  STATE  BLOCK  ZONES
0x0000000000000000-0x0000000007ffffff  128M online      0  None
0x0000000008000000-0x00000000cfffffff  3.1G online   1-25  DMA32
0x0000000100000000-0x000000082fffffff 28.8G online 32-261  Normal

Memory block size:                128M
Total online memory:               32G
Total offline memory:               0B

Your ranges will differ, so do not copy these addresses into a production command. Pick a range or block from your own lsmem output. The requested size or address range must be aligned to the reported Linux memory block size.

Checkpoint

You have written down the exact range, block numbers, state and zone before changing anything. That record is the basis for verification and for an undo attempt.

2. Choose online or offline carefully

  • Online makes currently unavailable memory usable.
  • Offline removes memory from normal allocation, commonly before a virtual machine hot-unplug.
  • Both need elevated privileges and both can affect running services.

Taking memory offline is not the same as deleting its contents. Linux first has to move or release pages, and it can refuse when pages cannot be migrated. Bringing memory online can also fail on a virtual machine when the hypervisor has none left to provide.

Warning

Do not run an offline command against a guessed range, and do not test it on a busy host just to see what happens. A successful operation reduces the memory available to applications until you bring the same blocks online again.

3. Enable memory by size

--enable takes a size in MiB by default. Add M or G to make the unit obvious. The documented units use powers of 1024, so 2g means 2 GiB.

$ sudo /usr/sbin/chmem --enable 1024
$ sudo /usr/sbin/chmem --enable 2g

These are examples, not commands to run without checking capacity. When enabling, the program starts with the lowest memory block numbers. If the request can only be partly completed, chmem reports the amount actually changed and exits with status 64.

For a real change, replace SIZE with a size that matches the block layout you inspected:

$ sudo /usr/sbin/chmem --enable SIZE

Verify the result with the same inventory command:

$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES

Look for the relevant block or range to show online. Also check the command status immediately after chmem:

$ printf 'chmem exit status: %s\n' "$?"
chmem exit status: 0

4. Disable a known address range

Use the hexadecimal range printed by lsmem to target a physical address range. The end address is the address of the last byte, not a length.

$ sudo /usr/sbin/chmem --disable 0xSTART-0xEND

Replace both placeholders with one complete, aligned range from your own output, and do not leave the literal placeholders in the command. When disabling, chmem starts with the highest memory block numbers, which matters when a size request spans several blocks.

Check the state after the command:

$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES
$ printf 'chmem exit status: %s\n' "$?"

The exit codes:

  • 0 means success.
  • 1 means failure.
  • 64 means partial success. Read the command's message and compare the actual states in lsmem, and do not treat a partial result as though the whole range changed.

5. Target memory blocks directly

If your change is expressed in block numbers, add --blocks. It accepts a single block or an inclusive first-to-last range.

$ sudo /usr/sbin/chmem --blocks --disable BLOCK
$ sudo /usr/sbin/chmem --blocks --disable FIRST-LAST

For example, --blocks --disable 10 requests block 10, matching the form in the installed manual. Confirm the number exists in your current lsmem output first. A block number is not a byte address, so never mix it with the address-range form.

To undo a successful block-offline operation, enable the same block:

$ sudo /usr/sbin/chmem --blocks --enable BLOCK
$ lsmem -o RANGE,SIZE,STATE,BLOCK,ZONES

Recovery

Undo is not guaranteed, because online and offline operations can fail for environmental reasons. If a service is degraded, restore the memory state if you can, then check its logs and the kernel log before repeating the request.

6. Select a memory zone only when needed

Use --zone when you need a particular valid zone and lsmem -o +ZONES shows the range supports it. When bringing memory online, chmem prefers the Movable zone when available. Movable memory is easier to offline again, but it is restricted to migratable pages rather than arbitrary kernel allocations.

$ lsmem -o RANGE,SIZE,STATE,BLOCK,+ZONES
$ sudo /usr/sbin/chmem --enable --zone Movable SIZE

Do not assume every machine offers every zone. The installed command advertises DMA, DMA32, Normal, Highmem, Movable and Device, but the valid choices for a particular range come from that machine's lsmem output. A zone option selects placement. It does not create a zone or override the kernel's suitability checks.

Common traps

  • Wrong unit: an unqualified number is MiB, not bytes or GiB. Use 2g when you mean 2 GiB.
  • Unaligned request: compare the size or range with the memory block size before using sudo.
  • Wrong executable: command -v chmem may find another util-linux build first. Check chmem --version, or call /usr/sbin/chmem for the Ubuntu package.
  • Lost status: save $? immediately. Running lsmem first replaces chmem's exit status.
  • Assumed completion: a partial-success status is not success for the full request. Verify each affected block.

Done means

  • The starting point is recorded. You have the original range, block, state and zone.
  • Alignment was right. Your size or range matched the machine's memory block alignment.
  • The action fitted the job. You used the correct online or offline command with appropriate privilege.
  • Status came first. You checked chmem's exit status immediately, then ran lsmem.
  • You can reverse it. You know the exact inverse command if the host needs its previous memory state restored.