Lines Matching +full:num +full:- +full:rings

2  * QTest testcase for the vhost-user
7 * See the COPYING file in the top-level directory.
13 #include "libqtest-single.h"
16 #include "qemu/config-file.h"
20 #include "chardev/char-fe.h"
25 #include "libqos/pci-pc.h"
26 #include "libqos/virtio-pci.h"
28 #include "libqos/malloc-pc.h"
30 #include "hw/virtio/virtio-net.h"
32 #include "standard-headers/linux/vhost_types.h"
33 #include "standard-headers/linux/virtio_ids.h"
34 #include "standard-headers/linux/virtio_net.h"
35 #include "standard-headers/linux/virtio_gpio.h"
36 #include "standard-headers/linux/virtio_scmi.h"
43 #define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM," \
44 "mem-path=%s,share=on -numa node,memdev=mem"
45 #define QEMU_CMD_MEMFD " -m %d -object memory-backend-memfd,id=mem,size=%dM," \
46 " -numa node,memdev=mem"
47 #define QEMU_CMD_SHM " -m %d -object memory-backend-shm,id=mem,size=%dM," \
48 " -numa node,memdev=mem"
49 #define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s%s"
50 #define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce=on"
54 /*********** FROM hw/virtio/vhost-user.c *************************************/
135 #define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE)
169 uint64_t rings; member
182 /* VHOST-USER commands. */
207 s->chr_name, s->socket_path, in append_vhost_net_opts()
208 chr_opts, s->chr_name); in append_vhost_net_opts()
213 * block or netdev) so all we need to worry about is the vhost-user
220 s->chr_name, s->socket_path, in append_vhost_gpio_opts()
237 const char *root = init_hugepagefs() ? : server->tmpfs; in append_mem_opts()
249 g_mutex_lock(&s->data_mutex); in wait_for_fds()
252 while (!s->fds_num) { in wait_for_fds()
253 if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) { in wait_for_fds()
255 g_assert(s->fds_num); in wait_for_fds()
261 g_assert_cmpint(s->fds_num, >, 0); in wait_for_fds()
262 g_assert_cmpint(s->fds_num, ==, s->memory.nregions); in wait_for_fds()
264 g_mutex_unlock(&s->data_mutex); in wait_for_fds()
267 for (i = 0; i < s->memory.nregions; ++i) { in wait_for_fds()
268 VhostUserMemoryRegion *reg = &s->memory.regions[i]; in wait_for_fds()
269 if (reg->guest_phys_addr == 0) { in wait_for_fds()
286 g_mutex_lock(&s->data_mutex); in read_guest_mem_server()
289 for (i = 0; i < s->fds_num; i++) { in read_guest_mem_server()
292 if (s->memory.regions[i].guest_phys_addr != 0x0) { in read_guest_mem_server()
296 g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024); in read_guest_mem_server()
298 size = s->memory.regions[i].memory_size + in read_guest_mem_server()
299 s->memory.regions[i].mmap_offset; in read_guest_mem_server()
302 MAP_SHARED, s->fds[i], 0); in read_guest_mem_server()
305 guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); in read_guest_mem_server()
308 uint32_t a = qtest_readb(qts, s->memory.regions[i].guest_phys_addr + j); in read_guest_mem_server()
314 munmap(guest_mem, s->memory.regions[i].memory_size); in read_guest_mem_server()
317 g_mutex_unlock(&s->data_mutex); in read_guest_mem_server()
336 CharBackend *chr = &s->chr; in chr_read()
339 int fd = -1; in chr_read()
341 if (s->test_fail) { in chr_read()
343 /* now switch to non-failure */ in chr_read()
344 s->test_fail = false; in chr_read()
352 g_mutex_lock(&s->data_mutex); in chr_read()
368 g_assert(s->vu_ops->get_features); in chr_read()
374 if (s->test_flags >= TEST_FLAGS_BAD) { in chr_read()
376 s->test_flags = TEST_FLAGS_END; in chr_read()
378 msg.payload.u64 = s->vu_ops->get_features(s); in chr_read()
386 if (s->vu_ops->set_features) { in chr_read()
387 s->vu_ops->set_features(s, chr, &msg); in chr_read()
400 if (s->vu_ops->get_protocol_features) { in chr_read()
401 s->vu_ops->get_protocol_features(s, chr, &msg); in chr_read()
426 * A real vhost-user backend would actually set the size and in chr_read()
431 msg.payload.state.index, msg.payload.state.num); in chr_read()
444 msg.payload.state.num = 0; in chr_read()
448 assert(msg.payload.state.index < s->queues * 2); in chr_read()
449 s->rings &= ~(0x1ULL << msg.payload.state.index); in chr_read()
450 g_cond_broadcast(&s->data_cond); in chr_read()
455 memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory)); in chr_read()
456 s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, in chr_read()
457 G_N_ELEMENTS(s->fds)); in chr_read()
460 g_cond_broadcast(&s->data_cond); in chr_read()
467 qos_printf("call fd: %d, do not set non-blocking\n", fd); in chr_read()
471 * This is a non-blocking eventfd. in chr_read()
473 * so revert it back to non-blocking. in chr_read()
480 if (s->log_fd != -1) { in chr_read()
481 close(s->log_fd); in chr_read()
482 s->log_fd = -1; in chr_read()
484 qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1); in chr_read()
490 g_cond_broadcast(&s->data_cond); in chr_read()
494 assert(msg.payload.state.index < s->queues * 2); in chr_read()
495 s->rings |= 0x1ULL << msg.payload.state.index; in chr_read()
496 g_cond_broadcast(&s->data_cond); in chr_read()
502 msg.payload.u64 = s->queues; in chr_read()
510 * fully functioning vhost-user we would enable/disable the in chr_read()
514 msg.payload.state.num ? "enabled" : "disabled"); in chr_read()
518 qos_printf("vhost-user: un-handled message: %d\n", msg.request); in chr_read()
523 g_mutex_unlock(&s->data_mutex); in chr_read()
577 server->context = g_main_context_new(); in test_server_new()
578 server->loop = g_main_loop_new(server->context, FALSE); in test_server_new()
581 server->thread = g_thread_new(NULL, thread_function, server->loop); in test_server_new()
583 tmpfs = g_dir_make_tmp("vhost-test-XXXXXX", &err); in test_server_new()
586 g_get_tmp_dir(), err->message); in test_server_new()
591 server->tmpfs = g_strdup(tmpfs); in test_server_new()
592 server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name); in test_server_new()
593 server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name); in test_server_new()
594 server->chr_name = g_strdup_printf("chr-%s", name); in test_server_new()
596 g_mutex_init(&server->data_mutex); in test_server_new()
597 g_cond_init(&server->data_cond); in test_server_new()
599 server->log_fd = -1; in test_server_new()
600 server->queues = 1; in test_server_new()
601 server->vu_ops = ops; in test_server_new()
610 if (s->test_flags == TEST_FLAGS_END && in chr_event()
612 s->test_flags = TEST_FLAGS_OK; in chr_event()
619 server->socket_path, opt); in test_server_create_chr()
622 chr = qemu_chr_new(server->chr_name, chr_path, server->context); in test_server_create_chr()
625 qemu_chr_fe_init(&server->chr, chr, &error_abort); in test_server_create_chr()
626 qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read, in test_server_create_chr()
627 chr_event, NULL, server, server->context, true); in test_server_create_chr()
640 g_main_loop_quit(server->loop); in test_server_free()
641 g_thread_join(server->thread); in test_server_free()
646 unlink(server->socket_path); in test_server_free()
647 g_free(server->socket_path); in test_server_free()
649 unlink(server->mig_path); in test_server_free()
650 g_free(server->mig_path); in test_server_free()
652 ret = rmdir(server->tmpfs); in test_server_free()
655 server->tmpfs, strerror(errno)); in test_server_free()
657 g_free(server->tmpfs); in test_server_free()
659 qemu_chr_fe_deinit(&server->chr, true); in test_server_free()
661 for (i = 0; i < server->fds_num; i++) { in test_server_free()
662 close(server->fds[i]); in test_server_free()
665 if (server->log_fd != -1) { in test_server_free()
666 close(server->log_fd); in test_server_free()
669 g_free(server->chr_name); in test_server_free()
671 g_main_loop_unref(server->loop); in test_server_free()
672 g_main_context_unref(server->context); in test_server_free()
673 g_cond_clear(&server->data_cond); in test_server_free()
674 g_mutex_clear(&server->data_mutex); in test_server_free()
682 g_mutex_lock(&s->data_mutex); in wait_for_log_fd()
684 while (s->log_fd == -1) { in wait_for_log_fd()
685 if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) { in wait_for_log_fd()
687 g_assert(s->log_fd != -1); in wait_for_log_fd()
692 g_mutex_unlock(&s->data_mutex); in wait_for_log_fd()
702 for (i = 0; i < s->fds_num; i++) { in write_guest_mem()
705 if (s->memory.regions[i].guest_phys_addr != 0x0) { in write_guest_mem()
709 g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024); in write_guest_mem()
711 size = s->memory.regions[i].memory_size + in write_guest_mem()
712 s->memory.regions[i].mmap_offset; in write_guest_mem()
715 MAP_SHARED, s->fds[i], 0); in write_guest_mem()
718 guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); in write_guest_mem()
724 munmap(guest_mem, s->memory.regions[i].memory_size); in write_guest_mem()
734 for (i = 0; i < s->memory.nregions; ++i) { in get_log_size()
735 VhostUserMemoryRegion *reg = &s->memory.regions[i]; in get_log_size()
736 guint64 last = range_get_last(reg->guest_phys_addr, in get_log_size()
737 reg->memory_size); in get_log_size()
754 gboolean overlap = t->src->rings && t->dest->rings; in test_migrate_source_check()
775 TestServer *server = test_server_new("vhost-user-test", arg); in vhost_user_test_setup()
779 server->vu_ops->append_opts(server, cmd_line, ""); in vhost_user_test_setup()
788 TestServer *server = test_server_new("vhost-user-test", arg); in vhost_user_test_setup_memfd()
792 server->vu_ops->append_opts(server, cmd_line, ""); in vhost_user_test_setup_memfd()
801 TestServer *server = test_server_new("vhost-user-test", arg); in vhost_user_test_setup_shm()
805 server->vu_ops->append_opts(server, cmd_line, ""); in vhost_user_test_setup_shm()
839 dest = test_server_new("dest", s->vu_ops); in test_migrate()
841 uri = g_strdup_printf("%s%s", "unix:", dest->mig_path); in test_migrate()
847 g_string_append_printf(dest_cmdline, " -incoming %s", uri); in test_migrate()
849 dest->vu_ops->append_opts(dest, dest_cmdline, ""); in test_migrate()
850 to = qtest_init(dest_cmdline->str); in test_migrate()
858 ((TestMigrateSource *)source)->src = s; in test_migrate()
859 ((TestMigrateSource *)source)->dest = dest; in test_migrate()
860 g_source_attach(source, s->context); in test_migrate()
864 rsp = qmp("{ 'execute': 'migrate-set-parameters'," in test_migrate()
865 "'arguments': { 'max-bandwidth': 10 } }"); in test_migrate()
875 log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0); in test_migrate()
884 rsp = qmp("{ 'execute': 'migrate-set-parameters'," in test_migrate()
885 "'arguments': { 'max-bandwidth': 0 } }"); in test_migrate()
908 g_mutex_lock(&s->data_mutex); in wait_for_rings_started()
910 while (ctpop64(s->rings) != count) { in wait_for_rings_started()
911 if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) { in wait_for_rings_started()
913 g_assert_cmpint(ctpop64(s->rings), ==, count); in wait_for_rings_started()
918 g_mutex_unlock(&s->data_mutex); in wait_for_rings_started()
923 test_server_create_chr(server, ",reconnect-ms=1000"); in test_server_connect()
931 qemu_chr_fe_disconnect(&s->chr); in reconnect_cb()
954 s->vu_ops->append_opts(s, cmd_line, ",server=on"); in vhost_user_test_setup_reconnect()
973 s->fds_num = 0; in test_reconnect()
974 s->rings = 0; in test_reconnect()
977 g_source_attach(src, s->context); in test_reconnect()
985 TestServer *s = test_server_new("connect-fail", arg); in vhost_user_test_setup_connect_fail()
987 s->test_fail = true; in vhost_user_test_setup_connect_fail()
991 s->vu_ops->append_opts(s, cmd_line, ",server=on"); in vhost_user_test_setup_connect_fail()
1000 TestServer *s = test_server_new("flags-mismatch", arg); in vhost_user_test_setup_flags_mismatch()
1002 s->test_flags = TEST_FLAGS_DISCONNECT; in vhost_user_test_setup_flags_mismatch()
1006 s->vu_ops->append_opts(s, cmd_line, ",server=on"); in vhost_user_test_setup_flags_mismatch()
1027 s->queues = 2; in vhost_user_test_setup_multiqueue()
1029 " -set netdev.hs0.queues=%d" in vhost_user_test_setup_multiqueue()
1030 " -global virtio-net-pci.vectors=%d", in vhost_user_test_setup_multiqueue()
1031 s->queues, s->queues * 2 + 2); in vhost_user_test_setup_multiqueue()
1040 wait_for_rings_started(s, s->queues * 2); in test_multiqueue()
1049 if (s->queues > 1) { in vu_net_get_features()
1059 g_assert(msg->payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES)); in vu_net_set_features()
1060 if (s->test_flags == TEST_FLAGS_DISCONNECT) { in vu_net_set_features()
1062 s->test_flags = TEST_FLAGS_BAD; in vu_net_set_features()
1070 msg->flags |= VHOST_USER_REPLY_MASK; in vu_net_get_protocol_features()
1071 msg->size = sizeof(m.payload.u64); in vu_net_get_protocol_features()
1072 msg->payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD; in vu_net_get_protocol_features()
1073 msg->payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_CROSS_ENDIAN; in vu_net_get_protocol_features()
1074 if (s->queues > 1) { in vu_net_get_protocol_features()
1075 msg->payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; in vu_net_get_protocol_features()
1077 qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size); in vu_net_get_protocol_features()
1080 /* Each VHOST-USER device should have its ops structure defined. */
1101 qos_add_test("vhost-user/read-guest-mem/memfile", in register_vhost_user_test()
1102 "virtio-net", in register_vhost_user_test()
1106 qos_add_test("vhost-user/read-guest-mem/shm", in register_vhost_user_test()
1107 "virtio-net", in register_vhost_user_test()
1112 qos_add_test("vhost-user/read-guest-mem/memfd", in register_vhost_user_test()
1113 "virtio-net", in register_vhost_user_test()
1117 qos_add_test("vhost-user/migrate", in register_vhost_user_test()
1118 "virtio-net", in register_vhost_user_test()
1122 qos_add_test("vhost-user/reconnect", "virtio-net", in register_vhost_user_test()
1126 qos_add_test("vhost-user/connect-fail", "virtio-net", in register_vhost_user_test()
1130 qos_add_test("vhost-user/flags-mismatch", "virtio-net", in register_vhost_user_test()
1135 qos_add_test("vhost-user/multiqueue", in register_vhost_user_test()
1136 "virtio-net", in register_vhost_user_test()
1151 * talking to a read vhost-user daemon.
1157 msg->flags |= VHOST_USER_REPLY_MASK; in vu_gpio_get_protocol_features()
1158 msg->size = sizeof(m.payload.u64); in vu_gpio_get_protocol_features()
1159 msg->payload.u64 = 1ULL << VHOST_USER_PROTOCOL_F_CONFIG; in vu_gpio_get_protocol_features()
1161 qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size); in vu_gpio_get_protocol_features()
1184 qos_add_test("read-guest-mem/memfile", in register_vhost_gpio_test()
1185 "vhost-user-gpio", test_read_guest_mem, &opts); in register_vhost_gpio_test()
1199 msg->flags |= VHOST_USER_REPLY_MASK; in vu_scmi_get_protocol_features()
1200 msg->size = sizeof(m.payload.u64); in vu_scmi_get_protocol_features()
1201 msg->payload.u64 = 1ULL << VHOST_USER_PROTOCOL_F_MQ; in vu_scmi_get_protocol_features()
1203 qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size); in vu_scmi_get_protocol_features()
1226 qos_add_test("scmi/read-guest-mem/memfile", in register_vhost_scmi_test()
1227 "vhost-user-scmi", test_read_guest_mem, &opts); in register_vhost_scmi_test()