diff --git a/src/client.cpp b/src/client.cpp index 13a3a1b7..35688275 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -588,9 +588,9 @@ int Client 0 && - sock_set_rate_limit(ifd, s_user_params.rate_limit)) { - log_err("[fd=%d] failed setting rate limit on address %s\n", ifd, - inet_ntoa(g_fds_array[ifd]->server_addr.sin_addr)); + sock_set_rate_limit(ifd, s_user_params)) { + log_err("[fd=%d] failed setting rate limit on address %s\n", + ifd, inet_ntoa(g_fds_array[ifd]->server_addr.sin_addr)); rc = SOCKPERF_ERR_SOCKET; break; } diff --git a/src/common.cpp b/src/common.cpp index 37fe998c..a6739a35 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -212,10 +212,26 @@ int read_int_from_sys_file(const char *path) { return retVal; } - -int sock_set_rate_limit(int fd, uint32_t rate_limit) { +int sock_set_rate_limit(int fd, user_params_t ¶ms) { int rc = SOCKPERF_ERR_NONE; - if (setsockopt(fd, SOL_SOCKET, SO_MAX_PACING_RATE, &rate_limit, sizeof(rate_limit)) < 0) { +#ifdef USING_VMA_EXTRA_API + vma_rate_limit_t limit; + uint16_t packet_size_incl_hdr = s_user_params.msg_size + ETH_HEADER_LEN + + IP_HEADER_LEN; + if (s_user_params.sock_type == SOCK_STREAM) { + packet_size_incl_hdr += TCP_HEADER_LEN; + } else { + packet_size_incl_hdr += UDP_HEADER_LEN; + } + limit.rate = params.rate_limit; + limit.max_burst_sz = packet_size_incl_hdr * DEFAULT_RATE_BURST; + limit.typical_pkt_sz = packet_size_incl_hdr; + int ret = setsockopt(fd, SOL_SOCKET, SO_MAX_PACING_RATE, &limit, sizeof(limit)); +#else + int ret = setsockopt(fd, SOL_SOCKET, SO_MAX_PACING_RATE, + ¶ms.rate_limit, sizeof(params.rate_limit)); +#endif + if (ret < 0) { log_err("setsockopt(SO_MAX_PACING_RATE), set rate-limit failed. " "It could be that this option is not supported in your system"); rc = SOCKPERF_ERR_SOCKET; diff --git a/src/common.h b/src/common.h index a58a7099..6171a031 100644 --- a/src/common.h +++ b/src/common.h @@ -325,7 +325,5 @@ static inline int msg_sendto(int fd, uint8_t *buf, int nbytes, return ret; } - -int sock_set_rate_limit(int fd, uint32_t rate_limit); - +int sock_set_rate_limit(int fd, user_params_t ¶ms); #endif /* COMMON_H_ */ diff --git a/src/defs.h b/src/defs.h index 9b1db915..2914bff2 100644 --- a/src/defs.h +++ b/src/defs.h @@ -164,6 +164,11 @@ extern const int MAX_FDS_NUM; #ifndef SO_MAX_PACING_RATE #define SO_MAX_PACING_RATE 47 #endif +#define DEFAULT_RATE_BURST (30) +#define ETH_HEADER_LEN (14) +#define IP_HEADER_LEN (20) +#define UDP_HEADER_LEN (8) +#define TCP_HEADER_LEN (20) /* Used by offload libraries to do egress path warm-up of caches. It is not in use by kernel. WARNING: it will actually end this packet on the wire. diff --git a/src/server.cpp b/src/server.cpp index 7e9541fe..46fbf2f3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -100,7 +100,7 @@ int ServerBase::initBeforeLoop() { * with the rest of the setsockopt */ if (s_user_params.rate_limit > 0 && - sock_set_rate_limit(ifd, s_user_params.rate_limit)) { + sock_set_rate_limit(ifd, s_user_params)) { log_err("[fd=%d] failed setting rate limit, %s\n", ifd, inet_ntoa(p_bind_addr->sin_addr)); rc = SOCKPERF_ERR_SOCKET;