← Documents Documentation/infiniband/user_mad.rst GitHub 원문 ↗

Linux 6.18.37 · InfiniBand

Userspace MAD access

UMAD 에이전트 등록, RMPP 송수신, transaction ID, P_Key 인덱스 ABI와 IsSM 장치를 설명합니다.

Source pathDocumentation/infiniband/user_mad.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

user_mad.rst:1-166

Userspace MAD 인터페이스는 포트별 `umad`·`issm` 장치, ioctl 기반 에이전트 등록, RMPP를 포함한 read/write 데이터 경로를 제공합니다. 하위 transaction ID는 사용자가 소유하고 상위 절반은 커널이 예약하며, P_Key 헤더 배치는 호환 ioctl로 선택하고 IsSM bit는 `issm` 파일의 열림 수명으로 관리합니다.

문서 개요
항목내용
SourceDocumentation/infiniband/user_mad.rst
분량166 source lines
장치`umad`, `issm`
대형 MADRMPP, `ENOSPC`와 `mad.length`
호환성`pkey_index`, ABI version 6

원문 분량과 핵심 적용 대상을 요약합니다.

핵심 흐름
포트 장치와 에이전트 등록RMPP 수신 버퍼 크기 조정MAD 송신과 transaction ID 매칭P_Key 헤더 ABI 선택IsSM bit와 udev 장치 노드 관리

문서의 주요 동작 순서를 압축해 보여 줍니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ====================
2 Userspace MAD access
3 ====================
4
5 Device files
6 ============
7
8 Each port of each InfiniBand device has a "umad" device and an
9 "issm" device attached. For example, a two-port HCA will have two
10 umad devices and two issm devices, while a switch will have one
11 device of each type (for switch port 0).
12
13 Creating MAD agents
14 ===================
15
16 A MAD agent can be created by filling in a struct ib_user_mad_reg_req
17 and then calling the IB_USER_MAD_REGISTER_AGENT ioctl on a file
18 descriptor for the appropriate device file. If the registration
19 request succeeds, a 32-bit id will be returned in the structure.
20 For example::
21
22 struct ib_user_mad_reg_req req = { /* ... */ };
23 ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req);
24 if (!ret)
25 my_agent = req.id;
26 else
27 perror("agent register");
28
29 Agents can be unregistered with the IB_USER_MAD_UNREGISTER_AGENT
30 ioctl. Also, all agents registered through a file descriptor will
31 be unregistered when the descriptor is closed.
32
33 2014
34 a new registration ioctl is now provided which allows additional
35 fields to be provided during registration.
36 Users of this registration call are implicitly setting the use of
37 pkey_index (see below).
38
39 Receiving MADs
40 ==============
41
42 MADs are received using read(). The receive side now supports
43 RMPP. The buffer passed to read() must be at least one
44 struct ib_user_mad + 256 bytes. For example:
45
46 If the buffer passed is not large enough to hold the received
47 MAD (RMPP), the errno is set to ENOSPC and the length of the
48 buffer needed is set in mad.length.
49
50 Example for normal MAD (non RMPP) reads::
51
52 struct ib_user_mad *mad;
53 mad = malloc(sizeof *mad + 256);
54 ret = read(fd, mad, sizeof *mad + 256);
55 if (ret != sizeof mad + 256) {
56 perror("read");
57 free(mad);
58 }
59
60 Example for RMPP reads::
61
62 struct ib_user_mad *mad;
63 mad = malloc(sizeof *mad + 256);
64 ret = read(fd, mad, sizeof *mad + 256);
65 if (ret == -ENOSPC)) {
66 length = mad.length;
67 free(mad);
68 mad = malloc(sizeof *mad + length);
69 ret = read(fd, mad, sizeof *mad + length);
70 }
71 if (ret < 0) {
72 perror("read");
73 free(mad);
74 }
75
76 In addition to the actual MAD contents, the other struct ib_user_mad
77 fields will be filled in with information on the received MAD. For
78 example, the remote LID will be in mad.lid.
79
80 If a send times out, a receive will be generated with mad.status set
81 to ETIMEDOUT. Otherwise when a MAD has been successfully received,
82 mad.status will be 0.
83
84 poll()/select() may be used to wait until a MAD can be read.
85
86 Sending MADs
87 ============
88
89 MADs are sent using write(). The agent ID for sending should be
90 filled into the id field of the MAD, the destination LID should be
91 filled into the lid field, and so on. The send side does support
92 RMPP so arbitrary length MAD can be sent. For example::
93
94 struct ib_user_mad *mad;
95
96 mad = malloc(sizeof *mad + mad_length);
97
98 /* fill in mad->data */
99
100 mad->hdr.id = my_agent; /* req.id from agent registration */
101 mad->hdr.lid = my_dest; /* in network byte order... */
102 /* etc. */
103
104 ret = write(fd, &mad, sizeof *mad + mad_length);
105 if (ret != sizeof *mad + mad_length)
106 perror("write");
107
108 Transaction IDs
109 ===============
110
111 Users of the umad devices can use the lower 32 bits of the
112 transaction ID field (that is, the least significant half of the
113 field in network byte order) in MADs being sent to match
114 request/response pairs. The upper 32 bits are reserved for use by
115 the kernel and will be overwritten before a MAD is sent.
116
117 P_Key Index Handling
118 ====================
119
120 The old ib_umad interface did not allow setting the P_Key index for
121 MADs that are sent and did not provide a way for obtaining the P_Key
122 index of received MADs. A new layout for struct ib_user_mad_hdr
123 with a pkey_index member has been defined; however, to preserve binary
124 compatibility with older applications, this new layout will not be used
125 unless one of IB_USER_MAD_ENABLE_PKEY or IB_USER_MAD_REGISTER_AGENT2 ioctl's
126 are called before a file descriptor is used for anything else.
127
128 In September 2008, the IB_USER_MAD_ABI_VERSION will be incremented
129 to 6, the new layout of struct ib_user_mad_hdr will be used by
130 default, and the IB_USER_MAD_ENABLE_PKEY ioctl will be removed.
131
132 Setting IsSM Capability Bit
133 ===========================
134
135 To set the IsSM capability bit for a port, simply open the
136 corresponding issm device file. If the IsSM bit is already set,
137 then the open call will block until the bit is cleared (or return
138 immediately with errno set to EAGAIN if the O_NONBLOCK flag is
139 passed to open()). The IsSM bit will be cleared when the issm file
140 is closed. No read, write or other operations can be performed on
141 the issm file.
142
143 /dev files
144 ==========
145
146 To create the appropriate character device files automatically with
147 udev, a rule like::
148
149 KERNEL=="umad*", NAME="infiniband/%k"
150 KERNEL=="issm*", NAME="infiniband/%k"
151
152 can be used. This will create device nodes named::
153
154 /dev/infiniband/umad0
155 /dev/infiniband/issm0
156
157 for the first port, and so on. The InfiniBand device and port
158 associated with these devices can be determined from the files::
159
160 /sys/class/infiniband_mad/umad0/ibdev
161 /sys/class/infiniband_mad/umad0/port
162
163 and::
164
165 /sys/class/infiniband_mad/issm0/ibdev
166 /sys/class/infiniband_mad/issm0/port
167

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

UMAD·ISSM 장치와 MAD 에이전트 등록

1-38

각 InfiniBand 장치의 포트에는 `umad` 장치와 `issm` 장치가 하나씩 연결됩니다. 2포트 HCA에는 각각 두 개가 생기고, 스위치는 스위치 포트 0에 대해 각 유형 하나씩을 갖습니다.

MAD 에이전트를 만들려면 `struct ib_user_mad_reg_req`를 채운 뒤 적절한 장치 파일 디스크립터에 `IB_USER_MAD_REGISTER_AGENT` ioctl을 호출합니다. 등록이 성공하면 구조체에 32비트 에이전트 ID가 반환됩니다.

struct ib_user_mad_reg_req req = { /* ... */ };
ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req);
if (!ret)
        my_agent = req.id;
else
        perror("agent register");

에이전트는 `IB_USER_MAD_UNREGISTER_AGENT` ioctl로 등록 해제할 수 있습니다. 파일 디스크립터를 닫으면 그 디스크립터를 통해 등록한 모든 에이전트도 자동으로 등록 해제됩니다.

2014년에 추가된 새 등록 ioctl은 등록 시 부가 필드를 전달할 수 있게 했습니다. 이 등록 호출을 사용하는 사용자는 아래에서 설명하는 `pkey_index` 사용도 암묵적으로 활성화합니다.

포트별 userspace MAD 장치
장치생성 단위주요 용도
`umad`각 HCA 포트, 스위치 포트 0Userspace MAD 송수신과 에이전트
`issm`각 HCA 포트, 스위치 포트 0IsSM capability bit 소유

장치 유형과 생성 단위, 기본 용도를 구분합니다.

MAD 에이전트 수명 주기
대상 `umad` 장치 파일 열기`ib_user_mad_reg_req` 구성`IB_USER_MAD_REGISTER_AGENT` 또는 새 등록 ioctl 호출성공 시 32비트 `req.id` 보관ioctl로 명시 해제하거나 파일 디스크립터 닫기디스크립터에 등록된 모든 에이전트 정리

등록 요청부터 자동 정리까지의 흐름입니다.

====================
Userspace MAD access
====================

Device files
============

  Each port of each InfiniBand device has a "umad" device and an
  "issm" device attached.  For example, a two-port HCA will have two
  umad devices and two issm devices, while a switch will have one
  device of each type (for switch port 0).

Creating MAD agents
===================

  A MAD agent can be created by filling in a struct ib_user_mad_reg_req
  and then calling the IB_USER_MAD_REGISTER_AGENT ioctl on a file
  descriptor for the appropriate device file.  If the registration
  request succeeds, a 32-bit id will be returned in the structure.
  For example::

        struct ib_user_mad_reg_req req = { /* ... */ };
        ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req);
        if (!ret)
                my_agent = req.id;
        else
                perror("agent register");

  Agents can be unregistered with the IB_USER_MAD_UNREGISTER_AGENT
  ioctl.  Also, all agents registered through a file descriptor will
  be unregistered when the descriptor is closed.

  2014
       a new registration ioctl is now provided which allows additional
       fields to be provided during registration.
       Users of this registration call are implicitly setting the use of
       pkey_index (see below).

MAD 수신, RMPP 재할당과 상태 처리

39-85

MAD는 `read()`로 수신하며 수신 측은 RMPP를 지원합니다. `read()`에 넘기는 버퍼는 최소한 `struct ib_user_mad + 256`바이트여야 합니다.

받은 RMPP MAD가 버퍼보다 크면 오류 번호가 `ENOSPC`로 설정되고 필요한 버퍼 길이가 `mad.length`에 기록됩니다. 호출자는 이 길이에 맞춰 버퍼를 다시 할당한 뒤 `read()`를 재시도합니다.

mad = malloc(sizeof *mad + 256);
ret = read(fd, mad, sizeof *mad + 256);
if (ret == -ENOSPC) {
        length = mad.length;
        free(mad);
        mad = malloc(sizeof *mad + length);
        ret = read(fd, mad, sizeof *mad + length);
}

실제 MAD 내용과 함께 `struct ib_user_mad`의 나머지 필드에도 수신 정보가 채워집니다. 예를 들어 원격 LID는 `mad.lid`에서 얻습니다.

송신 타임아웃이 발생하면 `mad.status=ETIMEDOUT`인 수신 이벤트가 생성됩니다. MAD를 정상적으로 받으면 `mad.status`는 0입니다. 읽을 MAD가 생길 때까지 `poll()` 또는 `select()`로 기다릴 수 있습니다.

MAD 수신 결과
상황반환·상태호출자 동작
일반 MAD`struct ib_user_mad + 256`에 수신내용과 헤더 필드 처리
큰 RMPP MAD`ENOSPC`, `mad.length`에 필요 크기버퍼 재할당 후 다시 `read()`
송신 타임아웃 통지`mad.status=ETIMEDOUT`실패 요청 처리
정상 수신`mad.status=0``mad.lid` 등 메타데이터 사용
대기`poll()` 또는 `select()`읽기 가능 시점까지 블록

버퍼 크기와 전송 상태에 따라 확인할 필드를 정리합니다.

RMPP MAD 수신 버퍼 확장
`sizeof(struct ib_user_mad) + 256` 버퍼 할당`read()` 호출`ENOSPC`가 아니면 정상 MAD 처리`ENOSPC`이면 `mad.length` 읽기기존 버퍼 해제 후 필요한 길이로 재할당`read()` 재호출하고 status·LID·데이터 처리

작은 초기 버퍼로 길이를 알아낸 뒤 정확한 크기로 다시 읽는 절차입니다.

Receiving MADs
==============

  MADs are received using read().  The receive side now supports
  RMPP. The buffer passed to read() must be at least one
  struct ib_user_mad + 256 bytes. For example:

  If the buffer passed is not large enough to hold the received
  MAD (RMPP), the errno is set to ENOSPC and the length of the
  buffer needed is set in mad.length.

  Example for normal MAD (non RMPP) reads::

        struct ib_user_mad *mad;
        mad = malloc(sizeof *mad + 256);
        ret = read(fd, mad, sizeof *mad + 256);
        if (ret != sizeof mad + 256) {
                perror("read");
                free(mad);
        }

  Example for RMPP reads::

        struct ib_user_mad *mad;
        mad = malloc(sizeof *mad + 256);
        ret = read(fd, mad, sizeof *mad + 256);
        if (ret == -ENOSPC)) {
                length = mad.length;
                free(mad);
                mad = malloc(sizeof *mad + length);
                ret = read(fd, mad, sizeof *mad + length);
        }
        if (ret < 0) {
                perror("read");
                free(mad);
        }

  In addition to the actual MAD contents, the other struct ib_user_mad
  fields will be filled in with information on the received MAD.  For
  example, the remote LID will be in mad.lid.

  If a send times out, a receive will be generated with mad.status set
  to ETIMEDOUT.  Otherwise when a MAD has been successfully received,
  mad.status will be 0.

  poll()/select() may be used to wait until a MAD can be read.

MAD 송신과 Transaction ID 소유 범위

86-116

MAD는 `write()`로 보냅니다. 송신 에이전트 ID는 MAD의 `id` 필드에, 목적지 LID는 `lid` 필드에 넣고 다른 주소 정보도 대응 필드에 채웁니다. 송신 측도 RMPP를 지원하므로 임의 길이의 MAD를 보낼 수 있습니다.

mad = malloc(sizeof *mad + mad_length);
mad->hdr.id  = my_agent;
mad->hdr.lid = my_dest;
ret = write(fd, &mad, sizeof *mad + mad_length);

`umad` 장치 사용자는 송신 MAD의 transaction ID 하위 32비트, 즉 네트워크 바이트 순서에서 덜 중요한 절반을 요청과 응답의 짝을 맞추는 데 사용할 수 있습니다. 상위 32비트는 커널용으로 예약되어 있으며 MAD를 보내기 전에 커널이 덮어씁니다.

MAD 송신 필드와 소유권
항목사용자 또는 커널 동작
`mad->hdr.id`등록에서 받은 `req.id` 설정
`mad->hdr.lid`목적지 LID를 네트워크 바이트 순서로 설정
데이터 길이RMPP로 임의 길이 지원
Transaction ID 하위 32비트사용자가 request/response 매칭에 사용
Transaction ID 상위 32비트커널 예약, 송신 전 덮어쓰기

사용자가 채우는 값과 커널이 예약한 transaction ID 범위를 구분합니다.

Userspace MAD 송신
`sizeof(*mad) + mad_length` 버퍼 할당MAD 데이터와 등록 에이전트 ID 구성목적지 LID 및 주소 필드 구성하위 32비트 transaction ID로 요청 식별`write()`로 전체 구조체와 데이터 송신반환 길이가 전체 길이인지 확인

에이전트와 목적지를 지정하고 길이 전체를 기록하는 순서입니다.

Sending MADs
============

  MADs are sent using write().  The agent ID for sending should be
  filled into the id field of the MAD, the destination LID should be
  filled into the lid field, and so on.  The send side does support
  RMPP so arbitrary length MAD can be sent. For example::

        struct ib_user_mad *mad;

        mad = malloc(sizeof *mad + mad_length);

        /* fill in mad->data */

        mad->hdr.id  = my_agent;        /* req.id from agent registration */
        mad->hdr.lid = my_dest;                /* in network byte order... */
        /* etc. */

        ret = write(fd, &mad, sizeof *mad + mad_length);
        if (ret != sizeof *mad + mad_length)
                perror("write");

Transaction IDs
===============

  Users of the umad devices can use the lower 32 bits of the
  transaction ID field (that is, the least significant half of the
  field in network byte order) in MADs being sent to match
  request/response pairs.  The upper 32 bits are reserved for use by
  the kernel and will be overwritten before a MAD is sent.

P_Key 인덱스 ABI와 IsSM capability bit

117-142

이전 `ib_umad` 인터페이스는 송신 MAD의 P_Key 인덱스를 설정할 수 없었고 수신 MAD의 P_Key 인덱스를 알아낼 방법도 없었습니다. 이를 위해 `pkey_index` 멤버가 있는 새 `struct ib_user_mad_hdr` 배치가 정의되었습니다.

기존 애플리케이션과의 바이너리 호환성을 지키기 위해, 파일 디스크립터를 다른 용도로 사용하기 전에 `IB_USER_MAD_ENABLE_PKEY` 또는 `IB_USER_MAD_REGISTER_AGENT2` ioctl 가운데 하나를 호출해야 새 헤더 배치가 사용됩니다.

문서에 기록된 전환 계획에 따르면 2008년 9월 `IB_USER_MAD_ABI_VERSION`을 6으로 올리고 새 `ib_user_mad_hdr` 배치를 기본값으로 사용하며 `IB_USER_MAD_ENABLE_PKEY` ioctl을 제거합니다.

포트의 IsSM capability bit를 설정하려면 대응 `issm` 장치 파일을 열기만 하면 됩니다. 비트가 이미 설정되어 있으면 비트가 지워질 때까지 `open()`이 블록됩니다. `O_NONBLOCK`을 사용하면 즉시 실패하고 `errno=EAGAIN`이 됩니다.

`issm` 파일을 닫으면 IsSM 비트가 지워집니다. 이 파일에서는 read, write 또는 다른 연산을 수행할 수 없습니다.

P_Key 인덱스 헤더 활성화
항목동작
이전 `ib_umad`송신·수신 P_Key index 지원 없음
새 헤더`struct ib_user_mad_hdr.pkey_index` 포함
명시 활성화첫 사용 전 `IB_USER_MAD_ENABLE_PKEY`
등록과 동시 활성화`IB_USER_MAD_REGISTER_AGENT2`
문서상 ABI 전환`IB_USER_MAD_ABI_VERSION=6`, 새 배치 기본값

이전 ABI와 새 헤더 배치의 선택 조건입니다.

IsSM 장치 열기 의미
연산결과
`open(issm)`IsSM bit 설정
비트가 이미 설정됨비트가 지워질 때까지 블록
`open(..., O_NONBLOCK)`즉시 실패, `errno=EAGAIN`
`close(issm)`IsSM bit 지움
`read`/`write`지원하지 않음

블로킹 모드, 비블로킹 모드, 닫기 동작을 구분합니다.

IsSM bit 소유 수명
대응 포트의 `issm` 장치 선택장치 열기 시 기존 IsSM 소유 확인비어 있으면 bit 설정하고 파일 디스크립터 획득이미 설정되어 있으면 블록하거나 `EAGAIN` 반환파일 디스크립터를 닫을 때 bit 해제

`issm` 파일 디스크립터의 열림 상태가 capability bit 소유를 표현합니다.

P_Key Index Handling
====================

  The old ib_umad interface did not allow setting the P_Key index for
  MADs that are sent and did not provide a way for obtaining the P_Key
  index of received MADs.  A new layout for struct ib_user_mad_hdr
  with a pkey_index member has been defined; however, to preserve binary
  compatibility with older applications, this new layout will not be used
  unless one of IB_USER_MAD_ENABLE_PKEY or IB_USER_MAD_REGISTER_AGENT2 ioctl's
  are called before a file descriptor is used for anything else.

  In September 2008, the IB_USER_MAD_ABI_VERSION will be incremented
  to 6, the new layout of struct ib_user_mad_hdr will be used by
  default, and the IB_USER_MAD_ENABLE_PKEY ioctl will be removed.

Setting IsSM Capability Bit
===========================

  To set the IsSM capability bit for a port, simply open the
  corresponding issm device file.  If the IsSM bit is already set,
  then the open call will block until the bit is cleared (or return
  immediately with errno set to EAGAIN if the O_NONBLOCK flag is
  passed to open()).  The IsSM bit will be cleared when the issm file
  is closed.  No read, write or other operations can be performed on
  the issm file.

udev 장치 노드와 포트 매핑 sysfs

143-166

적절한 문자 장치 파일을 udev로 자동 생성하려면 `umad*`와 `issm*` 커널 장치 이름을 `infiniband/%k`로 배치하는 규칙을 사용할 수 있습니다.

KERNEL=="umad*", NAME="infiniband/%k"
KERNEL=="issm*", NAME="infiniband/%k"

첫 포트에는 `/dev/infiniband/umad0`과 `/dev/infiniband/issm0` 장치 노드가 생성되고 이후 포트도 같은 방식으로 번호가 증가합니다.

각 장치가 연결된 InfiniBand 장치와 포트는 `/sys/class/infiniband_mad/<device>/ibdev` 및 `port` 파일에서 확인합니다. `umad0`과 `issm0` 모두 같은 형식의 매핑 파일을 제공합니다.

Userspace MAD 장치와 매핑
대상경로
UMAD 장치 노드`/dev/infiniband/umad0`
ISSM 장치 노드`/dev/infiniband/issm0`
UMAD IB 장치`/sys/class/infiniband_mad/umad0/ibdev`
UMAD 포트`/sys/class/infiniband_mad/umad0/port`
ISSM IB 장치`/sys/class/infiniband_mad/issm0/ibdev`
ISSM 포트`/sys/class/infiniband_mad/issm0/port`

첫 포트의 장치 노드 및 연결 정보를 찾는 sysfs 파일입니다.

장치 노드에서 IB 포트 찾기
udev가 `umad*`와 `issm*` 이벤트 수신`/dev/infiniband/%k` 장치 노드 생성장치 번호에 맞는 `/sys/class/infiniband_mad` 디렉터리 선택`ibdev` 파일에서 InfiniBand 장치 이름 확인`port` 파일에서 포트 번호 확인

udev가 만든 노드를 실제 InfiniBand 장치와 포트에 대응시키는 절차입니다.

/dev files
==========

  To create the appropriate character device files automatically with
  udev, a rule like::

    KERNEL=="umad*", NAME="infiniband/%k"
    KERNEL=="issm*", NAME="infiniband/%k"

  can be used.  This will create device nodes named::

    /dev/infiniband/umad0
    /dev/infiniband/issm0

  for the first port, and so on.  The InfiniBand device and port
  associated with these devices can be determined from the files::

    /sys/class/infiniband_mad/umad0/ibdev
    /sys/class/infiniband_mad/umad0/port

  and::

    /sys/class/infiniband_mad/issm0/ibdev
    /sys/class/infiniband_mad/issm0/port