All Products
Search
Document Center

Alibaba Cloud Linux:Using Shared Memory Communication (SMC)

Last Updated:Apr 01, 2026

Shared Memory Communication (SMC) replaces TCP sockets with Remote Direct Memory Access (RDMA)-backed SMC sockets transparently, reducing latency and increasing throughput for applications without code changes. This guide covers enabling SMC-R on Alibaba Cloud Elastic Compute Service (ECS) and Container Service for Kubernetes (ACK), fine-tuning the acceleration scope with Berkeley Packet Filter (BPF) policies, and configuring SMC parameters.

How it works

During the TCP connection handshake, both peers exchange a special TCP option to advertise SMC support. If negotiation succeeds, subsequent data travels over RDMA. If either peer does not support SMC, or if negotiation fails for any reason, the connection falls back to TCP automatically — no application change is required.

Choose a socket conversion method

Two approaches convert existing TCP socket applications to SMC sockets:

MethodScopeHow it worksUse when
Net namespace-levelAll qualifying TCP sockets in a net namespaceKernel intercepts new socket() calls and converts themYou control the full environment and want SMC for all services in a namespace
Process-levelA single process and its childrensmc_run uses LD_PRELOAD to intercept socket() in glibcYou want SMC for one specific service without affecting others

Both methods convert sockets that match all three conditions:

  • family = AF_INET

  • type = SOCK_STREAM

  • protocol = IPPROTO_IP(0) or IPPROTO_TCP(6)

Process-level conversion via smc_run requires glibc. It does not work for statically linked binaries or applications that bypass glibc.

Use SMC in Alibaba Cloud ECS

Prerequisites

Before you begin, ensure that you have:

Important
  • Alibaba Cloud eRDMA devices and SMC do not support IPv6 addresses. Applications using IPv6 fall back to TCP. See Troubleshoot SMC.

  • Starting from kernel version ANCK 5.10.134-17.3, SMC supports IPv4-mapped IPv6 addresses.

Set up SMC

1. Load the SMC kernel modules.

sudo modprobe smc
sudo modprobe smc_diag

Run dmesg to confirm the modules loaded:

smc: smc: load SMC module with reserve_mode
NET: Registered protocol family 43
smc: netns <netns ID> reserved ports [65500 ~ 65515] for eRDMA OOB
smc: adding ib device erdma_0 with port count 1
smc:    ib device erdma_0 port 1 has pnetid

To unload SMC when no longer needed:

sudo rmmod smc_diag
sudo rmmod smc

2. Install the O&M toolsets.

sudo yum install -y smc-tools
sudo yum install -y aliyun-smc-extensions

Enable net namespace-level socket conversion

This method converts all qualifying TCP sockets created after the sysctl is set. Existing sockets are not affected.

The following figure shows the conversion process.

image
  1. Enable transparent socket conversion for the current net namespace:

    sudo sysctl net.smc.tcp2smc=1

    The default value is 0 (disabled).

  2. Start your TCP socket application normally:

    ./<foo>

    Replace <foo> with your application name. The application's TCP sockets are transparently converted to SMC sockets and handled by the SMC-R stack. See How it works for the fallback behavior.

  3. (Optional) Disable conversion for the current net namespace. New TCP sockets revert to TCP, but existing converted SMC sockets are affected:

    sudo sysctl net.smc.tcp2smc=0

Enable process-level socket conversion

This method applies to a single process and its child processes using smc_run from the smc-tools toolset.

The following figure shows the conversion process.

image

Prefix your application's executable with smc_run:

smc_run ./<foo>

Replace <foo> with your process name. The TCP sockets created by the process are transparently converted to SMC sockets. See How it works for the fallback behavior.

Control SMC negotiation with BPF policies

Net namespace-level and process-level conversion apply SMC broadly. For finer control — for example, enabling SMC only on port 6379 (Redis) while keeping port 8080 on TCP — use smc-ebpf to set BPF-based policies.

The typical workflow is:

  1. Configure and load BPF policies.

  2. Enable SMC at the net namespace or process level as described above.

By default, SMC sockets always initiate and respond to the SMC TCP option. BPF policies let you override this behavior per port or per server IPv4 address.

Install smc-ebpf

smc-ebpf is included in smc-tools. Verify the installation:

smc-ebpf policy help

A successful response lists the available subcommands:

smc-ebpf policy help
 Usage: smc-ebpf policy COMMAND [OPTIONS]
        smc-ebpf policy load [OPTIONS]    load policy
    --init                                load policy with pre-defination config
        smc-ebpf policy stop              stop policy
        smc-ebpf policy unload            unload policy
        smc-ebpf policy init              init policy with default config
        smc-ebpf policy clear             clear all policy config
        smc-ebpf policy dump              display all policy config
        smc-ebpf policy config [OPTIONS]  config policy
        smc-ebpf policy delete [OPTIONS]  delete policy
    --ip [IPv4]                           target IPv4 address
    --port                                target port
    --mode [auto|disable|enable]          target mode
 Examples:
    smc-ebpf policy load
    #disable port 80 to use smc
    smc-ebpf policy config --port 80 --mode disable
    #delete ip xxx.xxx.x.x/24 policy
    smc-ebpf policy delete --ip xxx.xxx.x.x --mask 24

Load smc-ebpf

sudo smc-ebpf policy load
Warning
  • Load smc-ebpf before creating the connections you want to control. Policies do not apply to connections created before loading.

  • Policies are global and cannot be scoped to individual net namespaces or containers.

  • smc-ebpf features are experimental and may change in future releases.

A successful load outputs:

# sudo smc-ebpf policy load
Registered smc_sock_negotiator_ops anolis_smc id xxx

If the output differs, troubleshoot as follows:

  • Confirm the kernel version is ANCK 5.10.134-016 or later: uname -r

  • Confirm you have permission to load BPF programs. Containers may lack the required capability — check with your environment provider.

Port policies

Port policies control whether SMC negotiation is used based on the connection's port.

Default behavior: After loading smc-ebpf, any port without a matching policy is prohibited from using SMC negotiation.

To change the default to allow SMC for unmatched ports:

sudo smc-ebpf policy config --port 0 --mode enable

To reset the default back to prohibit:

sudo smc-ebpf policy config --port 0 --mode disable

Example 1: Allow only port 80, block all others

# Allow port 80
sudo smc-ebpf policy config --port 80 --mode enable

# Verify
sudo smc-ebpf policy dump

Expected output:

# sudo smc-ebpf policy dump
[{
        "key": 80,
        "value": {
            "mode": 2,
            [Other fields that ordinary users do not need to pay attention to]
        }
    }
]

"key": 80 is the port. "mode": 2 means SMC negotiation is allowed; "mode": 0 means prohibited.

To remove the policy:

sudo smc-ebpf policy delete --port 80

Example 2: Block only port 80, allow all others

# Change default: allow SMC for unmatched ports
sudo smc-ebpf policy config --port 0 --mode enable
# Block port 80
sudo smc-ebpf policy config --port 80 --mode disable

IPv4 address policies

IPv4 address policies apply to client sockets only. They control whether the client uses SMC negotiation when connecting to a specific server IP address. Server socket behavior is unaffected.

All port policies and IPv4 address policies are evaluated with a logical AND. SMC negotiation is used only when every matching policy allows it.

Default behavior: After loading smc-ebpf, any server IP without a matching policy is allowed for SMC negotiation.

To change the default to block SMC for unmatched IPs:

sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable

To reset the default back to allow:

sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode enable

Example 1: Allow SMC only to 192.168.2.0/24, block all other destinations

# Block unmatched IPs
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
# Allow 192.168.2.0/24
sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode enable

# Verify
sudo smc-ebpf policy dump

Expected output:

# sudo smc-ebpf policy dump
key:     0.0.0.0/32           value:   "denied"
key:     192.168.2.0/24       value:   "pass"

"pass" = SMC allowed; "denied" = SMC prohibited.

To remove these policies:

sudo smc-ebpf policy delete --ip 192.168.2.0 --mask 24
sudo smc-ebpf policy delete --ip 0.0.0.0 --mask 32

Example 2: Block SMC only to 192.168.2.0/24, allow all other destinations

sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode disable

No further configuration is needed. The default allows SMC for all other server IPs.

Clear all policies

sudo smc-ebpf policy clear

This deletes all configured policies and restores the default state: SMC negotiation is prohibited for all ports (port default: prohibit) and allowed for all IPv4 addresses (IP default: allow). Because port and IP policies are ANDed, all connections end up prohibited from using SMC negotiation.

Use SMC in Alibaba Cloud ACK

In Container Service for Kubernetes (ACK), enable SMC using the ACK eRDMA Controller component. eRDMA Controller manages and schedules ERIs and provides network capabilities for pods. See Use SMC-R to accelerate application networking.

BPF-based fine-grained policies for enabling SMC are also available on ACK nodes, using the same smc-ebpf workflow described above.

Parameters

The SMC stack exposes configuration parameters through sysfs and smc-tools.

Sysfs parameters

ParameterDefaultValid valuesKernel versionWhen to change
net.smc.autocorking_size6553504294967295; 0 = disabled5.10.112-11 and laterIncrease for small-packet bandwidth scenarios. Set to 0 for pipeline scenarios where autocorking delays are unacceptable.
net.smc.autosplit_size13107232768–5368709125.10.134-18+; 5.10.134-17.3+ (17 series); 5.10.134-16.5+ (16 series)Decrease for large-packet latency scenarios. Packets exceeding 1.3x this value are split for batch transmission.
net.smc.experiment_vendor_options4294967295 (0xFFFFFFFF)5.10.134-16 and laterKeep the default.
net.smc.global_mem[25%, 50%, 75% of system memory]5.10.134-18+; 5.10.134-17.3+; 5.10.134-16.5+Tune global_mem[2] based on expected memory usage. When SMC buffer sizes reach global_mem[2], new connections fall back to TCP system-wide.
net.smc.limit_smc_hs10 = no fallback; 1 = fall back to TCP5.10.134-18+; 5.10.134-17.3+; 5.10.134-16.5+Keep at 1. Set to 0 only if you want to prevent fallback under high connection pressure.
net.smc.mem[25%, 50%, 75% of system memory]5.10.134-18+; 5.10.134-17.3+; 5.10.134-16.5+Tune mem[2] based on expected namespace-level memory usage. When SMC buffer sizes reach mem[2] in the net namespace, new connections in that namespace fall back to TCP.
net.smc.rmem262144SMC-R: 16384–536870912; SMC-D: 16384–10485765.10.134-14 and laterIncrease when Rx/Buffer full metrics are high. Increase the peer's rmem when Tx/Buffer full(remote) or Tx/Buffer too small(remote) is high. Decrease when memory is constrained and performance is unaffected. See SMC monitoring.
net.smc.wmem262144SMC-R: 16384–536870912; SMC-D: 16384–10485765.10.134-14 and laterIncrease when Tx/Buffer full or Tx/Buffer too small metrics are high. Decrease when memory is constrained and performance is unaffected. See SMC monitoring.
net.smc.smcr_buf_type20 = physically contiguous; 1 = virtually contiguous; 2 = physically contiguous preferred, fall back to virtually contiguous5.10.134-12 and laterKeep the default. Takes effect for SMC connections on new link groups only.
net.smc.smcr_max_conns_per_lgr321–255 (5.10.134-18+, 5.10.134-17.3+, 5.10.134-16.5+); 16–255 (other versions)5.10.134-16.1 and laterReduce for high-throughput scenarios where each connection needs more RDMA bandwidth. Do not increase.
net.smc.smcr_max_links_per_lgr11 or 25.10.134-16.1 and laterKeep the default.
net.smc.smcr_testlink_time300–2147483647 (seconds); 0 = disabled5.10.134-13 and laterKeep the default. Controls heartbeat interval for RDMA reliable connections in SMC-R.
net.smc.tcp2smc00 = disabled; 1 = enabled5.10.134-16 and laterSet to 1 to enable transparent TCP-to-SMC conversion in the net namespace. Set to 0 to disable.

Configure EIDs

Enterprise ID (EID) is a concept in the SMCv2 protocol. Only systems sharing the same EID can communicate over SMCv2; otherwise they fall back to TCP. A system supports up to eight EIDs.

image

Alibaba Cloud Linux 3 eRDMA devices require the SMCv2 protocol. All Alibaba Cloud Linux 3 nodes ship with the EID SMCV2-DEFAULT-UEID, so nodes can communicate over SMCv2 without any manual EID configuration.

EID format: up to 32 characters, uppercase letters, digits, hyphens (-), and periods (.); must start with a letter or digit; no consecutive periods.

To view, add, or remove EIDs:

# View existing EIDs
smcr ueid show

# Add an EID
sudo smcr ueid add <EID>

# Remove an EID
sudo smcr ueid del <EID>

Use EIDs to prevent cross-zone SMC-R communication

SMC-R performs best within the same availability zone. To restrict SMC-R to same-zone traffic and automatically fall back to TCP for cross-zone traffic, set the zone ID as the EID.

Method 1: Step-by-step configuration

# Fetch the zone ID from instance metadata and convert to uppercase
ZONE_ID=$(curl -s -m 1 100.100.100.200/latest/meta-data/zone-id | tr "[:lower:]" "[:upper:]")

# Add the zone ID as an EID
sudo smcr ueid add $ZONE_ID

# Remove the default EID
smcr ueid | grep SMCV2-DEFAULT-UEID > /dev/null && sudo smcr ueid del SMCV2-DEFAULT-UEID

Method 2: One-click setup with aliyun-smc-extensions

The aliyunsmc-ueid service adds the zone ID as an EID and removes the default EID automatically.

sudo systemctl start aliyunsmc-ueid

Because EID configuration is not persistent across reboots, enable the service to start automatically at boot:

sudo systemctl enable aliyunsmc-ueid

Configure PNET IDs

When TCP traffic is converted to SMC-R, the SMC-R stack routes traffic through the Elastic RDMA Interface (ERI) associated with the Ethernet interface carrying that traffic.

This association works automatically if eRDMA is enabled directly on the Ethernet interface. If the ERI is associated with a different Ethernet interface, use a physical-network identifier (PNET ID) to link them manually.

Example: A node has eth0 and eth1. eRDMA is enabled on eth0, which is associated with erdma_0.

  • TCP traffic on eth0 — SMC-R detects erdma_0 automatically. No PNET ID needed.

  • TCP traffic on eth1 — SMC-R cannot find an ERI and falls back to TCP. Associate eth1 with erdma_0 via a PNET ID to enable RDMA on eth1 traffic.

image

PNET ID format: up to 16 characters, uppercase letters and digits only, no spaces.

To associate an Ethernet interface and an ERI with a PNET ID:

# Assign the PNET ID to the Ethernet interface
sudo smc_pnet -a <PNET ID> -I <eth_interface>

# Assign the same PNET ID to the ERI
sudo smc_pnet -a <PNET ID> -D <rdma_interface>

To view configured PNET IDs:

sudo smc_pnet

Sample output:

# sudo smc_pnet
00163E0CD751 n/a erdma_0 1
00163E0CD751 eth1 n/a 255

PNET ID 00163E0CD751 links erdma_0 and eth1. TCP traffic through eth1 is now accelerated over erdma_0 when SMC-R is enabled.

For reference on checking and enabling eRDMA on an Ethernet interface:

Use PNET IDs for pods sharing host ERIs

In self-managed container environments where multiple pods share one or more host ERIs, assign the same PNET ID to both the pod's virtual Ethernet interface (vEth) and the host ERI. This lets the kernel detect the host ERI and use RDMA to accelerate pod traffic.

image
# Assign the PNET ID to the vEth in the pod's net namespace
sudo ip netns exec <pod netns> smc_pnet -a <PNET ID> -I eth0

# Assign the same PNET ID to the host ERI
sudo smc_pnet -a <PNET ID> -D erdma_0

Use case: Redis on ECS with SMC

This example sets up SMC-R acceleration for Redis on two ECS instances — one as the Redis server and one as the client — with BPF policies scoped to port 6379 and the server's vSwitch CIDR.

1. Create two ECS instances (one Redis server, one Redis client). See Create an instance on the Custom Launch tab.

2. Load the SMC kernel modules on both instances:

sudo modprobe smc
sudo modprobe smc_diag

3. Install Redis on both instances:

sudo yum install redis -y

4. Configure zone-based EIDs on both instances to prevent cross-zone SMC-R communication:

sudo systemctl start aliyunsmc-ueid

5. Configure BPF policies on both instances to limit SMC to Redis traffic only:

# Load smc-ebpf
sudo smc-ebpf policy load

# Allow SMC only on port 6379
sudo smc-ebpf policy config --port 6379 --mode enable

# Block SMC for unmatched server IPs, then allow the vSwitch CIDR
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
cidr=$(curl -s -m 1 100.100.100.200/latest/meta-data/vswitch-cidr-block)
sudo smc-ebpf policy config --ip \
  $(echo ${cidr} | awk -F'/' '{print $1}') --mask \
  $(echo ${cidr} | awk -F'/' '{print $2}') --mode enable

6. Enable transparent socket conversion on both instances:

sudo sysctl -w net.smc.tcp2smc=1

7. Start Redis on the server. Replace <IP> with the private IP of the server's primary Elastic Network Interface (ENI):

redis-server --bind <IP> --port 6379 --protected-mode no --save

8. Connect or run a benchmark from the client. Replace <IP> with the Redis server's private IP:

# Connect interactively
redis-cli -h <IP> -p 6379

# Run a stress test
redis-benchmark -h <IP> -p 6379 -n 1000000 -t set -c 100

What's next