showgids.sh 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/bin/bash

black='\E[30;50m'
red='\E[31;50m'
green='\E[32;50m'
yellow='\E[33;50m'
blue='\E[34;50m'
magenta='\E[35;50m'
cyan='\E[36;50m'
white='\E[37;50m'
bold='\033[1m'

gid_count=0

# cecho (color echo) prints text in color.
# first parameter should be the desired color followed by text
function cecho() {
echo -en $1
shift
echo -n $*
tput sgr0
}

# becho (color echo) prints text in bold.
becho() {
echo -en $bold
echo -n $*
tput sgr0
}

function print_gids() {
dev=$1
port=$2

for gf in /sys/class/infiniband/$dev/ports/$port/gids/*; do
gid=$(cat $gf)
if [ $gid = 0000:0000:0000:0000:0000:0000:0000:0000 ]; then
continue
fi

echo -e $(basename $gf) "\t" $gid
done
}

echo -e "DEV\tPORT\tINDEX\tGID\t\t\t\t\tIPv4 \t\tVER\tDEV"
echo -e "---\t----\t-----\t---\t\t\t\t\t------------ \t---\t---"

DEVS=$1

if [ -z "$DEVS" ]; then
DEVS=$(ls /sys/class/infiniband/)
fi

for d in $DEVS; do
for p in $(ls /sys/class/infiniband/$d/ports/); do
for g in $(ls /sys/class/infiniband/$d/ports/$p/gids/); do
gid=$(cat /sys/class/infiniband/$d/ports/$p/gids/$g)
if [ $gid = 0000:0000:0000:0000:0000:0000:0000:0000 ]; then
continue
fi

if [ $gid = fe80:0000:0000:0000:0000:0000:0000:0000 ]; then
continue
fi

_ndev=$(cat /sys/class/infiniband/$d/ports/$p/gid_attrs/ndevs/$g 2>/dev/null)
__type=$(cat /sys/class/infiniband/$d/ports/$p/gid_attrs/types/$g 2>/dev/null)
_type=$(echo $__type | grep -o "[Vv].*")

if [ $(echo $gid | cut -d ":" -f -1) = "0000" ]; then
ipv4=$(printf "%d.%d.%d.%d" 0x${gid:30:2} 0x${gid:32:2} 0x${gid:35:2} 0x${gid:37:2})
echo -e "$d\t$p\t$g\t$gid\t$ipv4 \t$_type\t$_ndev"
else
echo -e "$d\t$p\t$g\t$gid\t\t\t$_type\t$_ndev"
fi

gid_count=$(expr 1 + $gid_count)
done #g (gid)
done #p (port)
done #d (dev)

echo n_gids_found=$gid_count

查看需要使用的 rdma 网卡

本机器有一块双端口物理 rdma 网卡,其中 mlx5_0, mlx5_1 是它的两个物理端口:

1
2
3
4
5
6
7
8
9
10
11
12
$ ./showgids.sh
DEV PORT INDEX GID IPv4 VER DEV
--- ---- ----- --- ------------ --- ---
mlx5_0 1 0 fe80:0000:0000:0000:0e42:a1ff:fe59:44d8 v1 ens7f0
mlx5_0 1 1 fe80:0000:0000:0000:0e42:a1ff:fe59:44d8 v2 ens7f0
mlx5_0 1 2 0000:0000:0000:0000:0000:ffff:0b0b:0bc5 33.33.33.197 v1 ens7f0
mlx5_0 1 3 0000:0000:0000:0000:0000:ffff:0b0b:0bc5 33.33.33.197 v2 ens7f0
mlx5_1 1 0 fe80:0000:0000:0000:0e42:a1ff:fe59:44d9 v1 ens7f1
mlx5_1 1 1 fe80:0000:0000:0000:0e42:a1ff:fe59:44d9 v2 ens7f1
mlx5_1 1 2 0000:0000:0000:0000:0000:ffff:0c0c:0cc5 44.44.44.197 v1 ens7f1
mlx5_1 1 3 0000:0000:0000:0000:0000:ffff:0c0c:0cc5 44.44.44.197 v2 ens7f1
n_gids_found=8

这里显示的信息在下面 ceph 的 rdma 参数中需要用到。

dev,port、index、gid 的关系,可以参考如下链接:

ibv_query_gid()

修改 vstart 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--- a/src/vstart.sh
+++ b/src/vstart.sh
@@ -618,6 +618,19 @@ prepare_conf() {
debug asok assert abort = true
$(format_conf "${msgr_conf}")
$(format_conf "${extra_conf}")
+
+ms_bind_ipv4 = true
+ms_bind_ipv6 = false
+
+ms_type = async+rdma
+ms_public_type = async+rdma
+ms_cluster_type = async+rdma
+
+#ms_async_rdma_local_gid = ::ffff:33.33.33.197
+#ms_async_rdma_roce_ver = 2
+
+ms_async_rdma_device_name = mlx5_0
+ms_async_rdma_port_num = 1
+ms_async_rdma_gid_idx = 3

注意,其中如下两个 rdma 相关的选项不需要:

1
2
ms_async_rdma_local_gid
ms_async_rdma_roce_ver

这两个选项仅适用于老的 libibverbs 库,现在 rdma 用户态库都是使用上游 rdma-core,因此这两个选项实际上已没有存在的意义。

另外 ms_async_rdma_gid_idx 使用 1 或者 3 都可以(当然不能是 0 或 2,因为我们需要使用 RoCE v2),使用 1 还是 3 只是 RoCE v2 的网络层(UDP/IP)IP 地址选择的区别,每一个 IP 地址对应一个 gid(IPv6 是直接映射,IPv4有一个肉眼可见的映射规则),因此选择 gid index 就是选择 IP 地址对应的 index(二层组网可能没什么区别,但是三层组网就会影响这个选择了)。

ms_bind_ipv4/ipv6 与 rdma 的使用无关,只是为了简化服务端 Messenger 的行为,ms_typems_public_type/ms_cluster_type 有冗余,但是无关紧要。

注意这些新增的参数需要添加到 fsid 所在的 [global] section 下面,放到其它位置,会导致 mon 仍然使用 async+posix 协议栈,而不是我们所期望的 async+rdma 协议栈,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[global]
fsid = $(uuidgen)
osd failsafe full ratio = .99
mon osd full ratio = .99
mon osd nearfull ratio = .99
mon osd backfillfull ratio = .99
mon_max_pg_per_osd = ${MON_MAX_PG_PER_OSD:-1000}
erasure code dir = $EC_PATH
plugin dir = $CEPH_LIB
filestore fd cache size = 32
run dir = $CEPH_OUT_DIR
crash dir = $CEPH_OUT_DIR
enable experimental unrecoverable data corrupting features = *
osd_crush_chooseleaf_type = 0
debug asok assert abort = true
$(format_conf "${msgr_conf}")
$(format_conf "${extra_conf}")

ms_bind_ipv4 = true
ms_bind_ipv6 = false
ms_type = async+rdma
ms_public_type = async+rdma
ms_cluster_type = async+rdma

#ms_async_rdma_local_gid = ::ffff:33.33.33.197
#ms_async_rdma_roce_ver = 2

ms_async_rdma_device_name = mlx5_0
ms_async_rdma_port_num = 1
ms_async_rdma_gid_idx = 3

修改 ulimit 参数

1
2
3
# vi /etc/security/limits.conf
* hard memlock unlimited
* soft memlock unlimited

修改之后记得退出终端并重新登录使得配置生效。

指定地址运行 vstart

1
$ ../src/vstart.sh -n -b -i 33.33.33.197 --msgr2

其中 33.33.33.197 即 RDMA 网卡配置的 IP 地址,使用 --msgr2 也与 rdma 的使用无关,只是为了简化服务端 Messenger 的行为。

参考资料

Migration to RDMA-Core

https://docs.mellanox.com/display/rdmacore50

Understanding show_gids Script

https://community.mellanox.com/s/article/understanding-show-gids-script

RDMA杂谈

https://www.zhihu.com/column/c_1231181516811390976