Skip to content

Commit 542e893

Browse files
Arseniy Krasnovdavem330
authored andcommitted
vsock/test: two tests to check credit update logic
Both tests are almost same, only differs in two 'if' conditions, so implemented in a single function. Tests check, that credit update message is sent: 1) During setting SO_RCVLOWAT value of the socket. 2) When number of 'rx_bytes' become smaller than SO_RCVLOWAT value. Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0fe1798 commit 542e893

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

tools/testing/vsock/vsock_test.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,171 @@ static void test_double_bind_connect_client(const struct test_opts *opts)
12321232
}
12331233
}
12341234

1235+
#define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1236+
/* This define is the same as in 'include/linux/virtio_vsock.h':
1237+
* it is used to decide when to send credit update message during
1238+
* reading from rx queue of a socket. Value and its usage in
1239+
* kernel is important for this test.
1240+
*/
1241+
#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1242+
1243+
static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1244+
{
1245+
size_t buf_size;
1246+
void *buf;
1247+
int fd;
1248+
1249+
fd = vsock_stream_connect(opts->peer_cid, 1234);
1250+
if (fd < 0) {
1251+
perror("connect");
1252+
exit(EXIT_FAILURE);
1253+
}
1254+
1255+
/* Send 1 byte more than peer's buffer size. */
1256+
buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1257+
1258+
buf = malloc(buf_size);
1259+
if (!buf) {
1260+
perror("malloc");
1261+
exit(EXIT_FAILURE);
1262+
}
1263+
1264+
/* Wait until peer sets needed buffer size. */
1265+
recv_byte(fd, 1, 0);
1266+
1267+
if (send(fd, buf, buf_size, 0) != buf_size) {
1268+
perror("send failed");
1269+
exit(EXIT_FAILURE);
1270+
}
1271+
1272+
free(buf);
1273+
close(fd);
1274+
}
1275+
1276+
static void test_stream_credit_update_test(const struct test_opts *opts,
1277+
bool low_rx_bytes_test)
1278+
{
1279+
size_t recv_buf_size;
1280+
struct pollfd fds;
1281+
size_t buf_size;
1282+
void *buf;
1283+
int fd;
1284+
1285+
fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
1286+
if (fd < 0) {
1287+
perror("accept");
1288+
exit(EXIT_FAILURE);
1289+
}
1290+
1291+
buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1292+
1293+
if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1294+
&buf_size, sizeof(buf_size))) {
1295+
perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1296+
exit(EXIT_FAILURE);
1297+
}
1298+
1299+
if (low_rx_bytes_test) {
1300+
/* Set new SO_RCVLOWAT here. This enables sending credit
1301+
* update when number of bytes if our rx queue become <
1302+
* SO_RCVLOWAT value.
1303+
*/
1304+
recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1305+
1306+
if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1307+
&recv_buf_size, sizeof(recv_buf_size))) {
1308+
perror("setsockopt(SO_RCVLOWAT)");
1309+
exit(EXIT_FAILURE);
1310+
}
1311+
}
1312+
1313+
/* Send one dummy byte here, because 'setsockopt()' above also
1314+
* sends special packet which tells sender to update our buffer
1315+
* size. This 'send_byte()' will serialize such packet with data
1316+
* reads in a loop below. Sender starts transmission only when
1317+
* it receives this single byte.
1318+
*/
1319+
send_byte(fd, 1, 0);
1320+
1321+
buf = malloc(buf_size);
1322+
if (!buf) {
1323+
perror("malloc");
1324+
exit(EXIT_FAILURE);
1325+
}
1326+
1327+
/* Wait until there will be 128KB of data in rx queue. */
1328+
while (1) {
1329+
ssize_t res;
1330+
1331+
res = recv(fd, buf, buf_size, MSG_PEEK);
1332+
if (res == buf_size)
1333+
break;
1334+
1335+
if (res <= 0) {
1336+
fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1337+
exit(EXIT_FAILURE);
1338+
}
1339+
}
1340+
1341+
/* There is 128KB of data in the socket's rx queue, dequeue first
1342+
* 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1343+
* Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1344+
*/
1345+
recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1346+
recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1347+
1348+
if (!low_rx_bytes_test) {
1349+
recv_buf_size++;
1350+
1351+
/* Updating SO_RCVLOWAT will send credit update. */
1352+
if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
1353+
&recv_buf_size, sizeof(recv_buf_size))) {
1354+
perror("setsockopt(SO_RCVLOWAT)");
1355+
exit(EXIT_FAILURE);
1356+
}
1357+
}
1358+
1359+
fds.fd = fd;
1360+
fds.events = POLLIN | POLLRDNORM | POLLERR |
1361+
POLLRDHUP | POLLHUP;
1362+
1363+
/* This 'poll()' will return once we receive last byte
1364+
* sent by client.
1365+
*/
1366+
if (poll(&fds, 1, -1) < 0) {
1367+
perror("poll");
1368+
exit(EXIT_FAILURE);
1369+
}
1370+
1371+
if (fds.revents & POLLERR) {
1372+
fprintf(stderr, "'poll()' error\n");
1373+
exit(EXIT_FAILURE);
1374+
}
1375+
1376+
if (fds.revents & (POLLIN | POLLRDNORM)) {
1377+
recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1378+
} else {
1379+
/* These flags must be set, as there is at
1380+
* least 64KB of data ready to read.
1381+
*/
1382+
fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1383+
exit(EXIT_FAILURE);
1384+
}
1385+
1386+
free(buf);
1387+
close(fd);
1388+
}
1389+
1390+
static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1391+
{
1392+
test_stream_credit_update_test(opts, true);
1393+
}
1394+
1395+
static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1396+
{
1397+
test_stream_credit_update_test(opts, false);
1398+
}
1399+
12351400
static struct test_case test_cases[] = {
12361401
{
12371402
.name = "SOCK_STREAM connection reset",
@@ -1342,6 +1507,16 @@ static struct test_case test_cases[] = {
13421507
.run_client = test_double_bind_connect_client,
13431508
.run_server = test_double_bind_connect_server,
13441509
},
1510+
{
1511+
.name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
1512+
.run_client = test_stream_rcvlowat_def_cred_upd_client,
1513+
.run_server = test_stream_cred_upd_on_set_rcvlowat,
1514+
},
1515+
{
1516+
.name = "SOCK_STREAM virtio credit update + low rx_bytes",
1517+
.run_client = test_stream_rcvlowat_def_cred_upd_client,
1518+
.run_server = test_stream_cred_upd_on_low_rx_bytes,
1519+
},
13451520
{},
13461521
};
13471522

0 commit comments

Comments
 (0)