Skip to content

Commit a1a89ce

Browse files
committed
prov/udp: detect and use MTU to set max_msg_size and inject_size
For each interface detected by the udp provider, determine the MTU of the interface, and use that value to set the max_msg_size field of the fi_ep_attr and fi_tx_attr values of the fi_info element. When the MTU cannot be determined, the MTU value assumed by previous code versions (1500) is used. Signed-off-by: Martin Pokorny <[email protected]>
1 parent f236201 commit a1a89ce

File tree

11 files changed

+126
-17
lines changed

11 files changed

+126
-17
lines changed

include/freebsd/osd.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ static inline size_t ofi_ifaddr_get_speed(struct ifaddrs *ifa)
7676
return 0;
7777
}
7878

79+
static inline int ofi_ifaddr_get_mtu(const struct ifaddrs *ifa)
80+
{
81+
return -1;
82+
}
83+
7984
static inline ssize_t ofi_process_vm_readv(pid_t pid,
8085
const struct iovec *local_iov,
8186
unsigned long liovcnt,
@@ -185,5 +190,3 @@ ofi_recvv_socket(SOCKET fd, const struct iovec *iov, size_t cnt, int flags)
185190
}
186191

187192
#endif /* _FREEBSD_OSD_H_ */
188-
189-

include/linux/osd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ static inline int ofi_hugepage_enabled(void)
9292

9393
size_t ofi_ifaddr_get_speed(struct ifaddrs *ifa);
9494

95+
int ofi_ifaddr_get_mtu(const struct ifaddrs *ifa);
96+
9597
#ifndef __NR_process_vm_readv
9698
# define __NR_process_vm_readv 310
9799
#endif

include/osx/osd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ static inline size_t ofi_ifaddr_get_speed(struct ifaddrs *ifa)
9999
return 0;
100100
}
101101

102+
static inline int ofi_ifaddr_get_mtu(const struct ifaddrs *ifa)
103+
{
104+
return -1;
105+
}
106+
102107
static inline int ofi_hugepage_enabled(void)
103108
{
104109
return 0;

include/windows/ifaddrs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ struct ifaddrs {
3434

3535
char ad_name[16];
3636
size_t speed;
37+
int mtu;
3738
};
3839

3940
int getifaddrs(struct ifaddrs **ifap);
4041
void freeifaddrs(struct ifaddrs *ifa);
41-

include/windows/osd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,8 @@ static inline int ofi_is_loopback_addr(struct sockaddr *addr) {
10061006

10071007
size_t ofi_ifaddr_get_speed(struct ifaddrs *ifa);
10081008

1009+
int ofi_ifaddr_get_mtu(const struct ifaddrs *ifa);
1010+
10091011
#define file2unix_time 10000000i64
10101012
#define win2unix_epoch 116444736000000000i64
10111013
#define CLOCK_REALTIME 0

man/fi_udp.7.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ receiving datagram messages over an unreliable endpoint.
4141

4242
# LIMITATIONS
4343

44-
The UDP provider has hard-coded maximums for supported queue sizes and data
45-
transfers. These values are reflected in the related fabric attribute
46-
structures
44+
The UDP provider has a hard-coded maximum for supported queue sizes.
45+
This value is reflected in the related fabric attribute structures.
4746

4847
EPs must be bound to both RX and TX CQs.
4948

@@ -53,7 +52,10 @@ No support for counters.
5352

5453
# RUNTIME PARAMETERS
5554

56-
No runtime parameters are currently defined.
55+
The UDP provider checks for the following environment variables -
56+
57+
*FI_UDP_IFACE*
58+
: An string value that specifies the name of the interface.
5759

5860
# SEE ALSO
5961

prov/udp/src/udpx.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,22 @@
6363
#ifndef _UDPX_H_
6464
#define _UDPX_H_
6565

66-
6766
extern struct fi_provider udpx_prov;
6867
extern struct util_prov udpx_util_prov;
6968
extern struct fi_info udpx_info;
7069

71-
7270
int udpx_fabric(struct fi_fabric_attr *attr, struct fid_fabric **fabric,
7371
void *context);
7472
int udpx_domain_open(struct fid_fabric *fabric, struct fi_info *info,
7573
struct fid_domain **dom, void *context);
7674
int udpx_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
7775
struct fid_eq **eq, void *context);
78-
76+
int udpx_util_prov_init(uint32_t version, const char *node, const char *service,
77+
uint64_t flags);
7978

8079
#define UDPX_FLAG_MULTI_RECV 1
8180
#define UDPX_IOV_LIMIT 4
81+
#define UDPX_MTU 1500
8282

8383
struct udpx_ep_entry {
8484
void *context;
@@ -88,6 +88,8 @@ struct udpx_ep_entry {
8888
uint8_t resv[sizeof(size_t) - 2];
8989
};
9090

91+
#define UDPX_MAX_MSG_SIZE(mtu) ((mtu) - 28)
92+
9193
OFI_DECLARE_CIRQUE(struct udpx_ep_entry, udpx_rx_cirq);
9294

9395
struct udpx_ep;

prov/udp/src/udpx_attr.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@
3131
*/
3232

3333
#include "udpx.h"
34+
#include "ofi_osd.h"
3435

3536
#define UDPX_TX_CAPS (OFI_TX_MSG_CAPS | FI_MULTICAST)
3637
#define UDPX_RX_CAPS (FI_SOURCE | OFI_RX_MSG_CAPS)
3738
#define UDPX_DOMAIN_CAPS (FI_LOCAL_COMM | FI_REMOTE_COMM)
3839

3940
struct fi_tx_attr udpx_tx_attr = {
4041
.caps = UDPX_TX_CAPS,
41-
.inject_size = 1472,
42+
.inject_size = UDPX_MAX_MSG_SIZE(UDPX_MTU),
4243
.size = 1024,
4344
.iov_limit = UDPX_IOV_LIMIT
4445
};
@@ -53,7 +54,7 @@ struct fi_ep_attr udpx_ep_attr = {
5354
.type = FI_EP_DGRAM,
5455
.protocol = FI_PROTO_UDP,
5556
.protocol_version = 0,
56-
.max_msg_size = 1472,
57+
.max_msg_size = UDPX_MAX_MSG_SIZE(UDPX_MTU),
5758
.tx_ctx_cnt = 1,
5859
.rx_ctx_cnt = 1
5960
};
@@ -93,6 +94,39 @@ struct fi_info udpx_info = {
9394

9495
struct util_prov udpx_util_prov = {
9596
.prov = &udpx_prov,
96-
.info = &udpx_info,
97-
.flags = 0,
97+
.info = NULL,
98+
.flags = 0,
9899
};
100+
101+
static int detect_mtu(const struct fi_info* info) {
102+
103+
struct ifaddrs ifaddrs;
104+
ifaddrs.ifa_next = NULL;
105+
ifaddrs.ifa_flags = 0;
106+
ifaddrs.ifa_netmask = NULL;
107+
ifaddrs.ifa_name = info->domain_attr->name;
108+
ifaddrs.ifa_addr = info->src_addr;
109+
return ofi_ifaddr_get_mtu(&ifaddrs);
110+
}
111+
112+
int udpx_util_prov_init(uint32_t version, const char *node, const char *service,
113+
uint64_t flags) {
114+
115+
struct fi_info* cur;
116+
struct fi_info* info;
117+
int max_msg_size;
118+
if (udpx_util_prov.info == NULL) {
119+
udpx_util_prov.info = &udpx_info;
120+
info = fi_allocinfo();
121+
ofi_ip_getinfo(&udpx_util_prov, version, node, service, flags,
122+
NULL, &info);
123+
for (cur = info; cur; cur = cur->next) {
124+
max_msg_size = UDPX_MAX_MSG_SIZE(detect_mtu(cur));
125+
if (max_msg_size > 0) {
126+
cur->tx_attr->inject_size = max_msg_size;
127+
cur->ep_attr->max_msg_size = max_msg_size;
128+
}
129+
}
130+
udpx_util_prov.info = info;
131+
}
132+
}

prov/udp/src/udpx_init.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,26 @@
3737

3838
#include <sys/types.h>
3939

40+
static ofi_mutex_t init_lock;
4041

4142
static int udpx_getinfo(uint32_t version, const char *node, const char *service,
4243
uint64_t flags, const struct fi_info *hints,
4344
struct fi_info **info)
4445
{
45-
return ofi_ip_getinfo(&udpx_util_prov, version, node, service, flags,
46-
hints, info);
46+
ofi_mutex_lock(&init_lock);
47+
udpx_util_prov_init(version, node, service, flags);
48+
ofi_mutex_unlock(&init_lock);
49+
return util_getinfo(&udpx_util_prov, version, node, service, flags,
50+
hints, info);
4751
}
4852

4953
static void udpx_fini(void)
5054
{
51-
/* yawn */
55+
if (udpx_util_prov.info != NULL)
56+
fi_freeinfo(udpx_util_prov.info);
5257
}
5358

59+
5460
struct fi_provider udpx_prov = {
5561
.name = "udp",
5662
.version = OFI_VERSION_DEF_PROV,
@@ -65,5 +71,6 @@ UDP_INI
6571
fi_param_define(&udpx_prov, "iface", FI_PARAM_STRING,
6672
"Specify interface name");
6773

74+
ofi_mutex_init(&init_lock);
6875
return &udpx_prov;
6976
}

src/linux/osd.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,49 @@ size_t ofi_ifaddr_get_speed(struct ifaddrs *ifa)
257257
}
258258

259259
#endif /* HAVE_ETHTOOL */
260+
261+
int ofi_ifaddr_get_mtu(const struct ifaddrs *ifa)
262+
{
263+
FILE *fd;
264+
char *line = NULL;
265+
size_t len = 0;
266+
char *mtu_filename_prefix = "/sys/class/net/";
267+
char *mtu_filename_suffix = "/mtu";
268+
char *mtu_filename;
269+
int mtu;
270+
/* IF_NAMESIZE includes NULL-terminated symbol */
271+
size_t filename_len = strlen(mtu_filename_prefix) +
272+
strlen(mtu_filename_prefix) +
273+
IF_NAMESIZE;
274+
275+
mtu_filename = calloc(1, filename_len);
276+
if (!mtu_filename)
277+
return 0;
278+
279+
snprintf(mtu_filename, filename_len, "%s%s%s",
280+
mtu_filename_prefix, ifa->ifa_name, mtu_filename_suffix);
281+
282+
fd = fopen(mtu_filename, "r");
283+
if (!fd)
284+
goto err1;
285+
286+
if (getline(&line, &len, fd) == -1) {
287+
goto err2;
288+
}
289+
290+
if (sscanf(line, "%d", &mtu) != 1)
291+
goto err3;
292+
293+
free(line);
294+
fclose(fd);
295+
free(mtu_filename);
296+
297+
return mtu;
298+
err3:
299+
free(line);
300+
err2:
301+
fclose(fd);
302+
err1:
303+
free(mtu_filename);
304+
return 0;
305+
}

0 commit comments

Comments
 (0)