qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

vhost+postcopy: Transmit 'listen' to slave

Notify the vhost-user slave on reception of the 'postcopy-listen'
event from the source.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Dr. David Alan Gilbert and committed by
Michael S. Tsirkin
6864a7b5 f82c1116

+77
+19
contrib/libvhost-user/libvhost-user.c
··· 98 98 REQ(VHOST_USER_GET_CONFIG), 99 99 REQ(VHOST_USER_SET_CONFIG), 100 100 REQ(VHOST_USER_POSTCOPY_ADVISE), 101 + REQ(VHOST_USER_POSTCOPY_LISTEN), 101 102 REQ(VHOST_USER_MAX), 102 103 }; 103 104 #undef REQ ··· 932 933 } 933 934 934 935 static bool 936 + vu_set_postcopy_listen(VuDev *dev, VhostUserMsg *vmsg) 937 + { 938 + vmsg->payload.u64 = -1; 939 + vmsg->size = sizeof(vmsg->payload.u64); 940 + 941 + if (dev->nregions) { 942 + vu_panic(dev, "Regions already registered at postcopy-listen"); 943 + return true; 944 + } 945 + dev->postcopy_listening = true; 946 + 947 + vmsg->flags = VHOST_USER_VERSION | VHOST_USER_REPLY_MASK; 948 + vmsg->payload.u64 = 0; /* Success */ 949 + return true; 950 + } 951 + static bool 935 952 vu_process_message(VuDev *dev, VhostUserMsg *vmsg) 936 953 { 937 954 int do_reply = 0; ··· 1004 1021 break; 1005 1022 case VHOST_USER_POSTCOPY_ADVISE: 1006 1023 return vu_set_postcopy_advise(dev, vmsg); 1024 + case VHOST_USER_POSTCOPY_LISTEN: 1025 + return vu_set_postcopy_listen(dev, vmsg); 1007 1026 default: 1008 1027 vmsg_close_fds(vmsg); 1009 1028 vu_panic(dev, "Unhandled request: %d", vmsg->request);
+2
contrib/libvhost-user/libvhost-user.h
··· 86 86 VHOST_USER_CREATE_CRYPTO_SESSION = 26, 87 87 VHOST_USER_CLOSE_CRYPTO_SESSION = 27, 88 88 VHOST_USER_POSTCOPY_ADVISE = 28, 89 + VHOST_USER_POSTCOPY_LISTEN = 29, 89 90 VHOST_USER_MAX 90 91 } VhostUserRequest; 91 92 ··· 285 286 286 287 /* Postcopy data */ 287 288 int postcopy_ufd; 289 + bool postcopy_listening; 288 290 }; 289 291 290 292 typedef struct VuVirtqElement {
+11
docs/interop/vhost-user.txt
··· 709 709 the slave must open a userfaultfd for later use. 710 710 Note that at this stage the migration is still in precopy mode. 711 711 712 + * VHOST_USER_POSTCOPY_LISTEN 713 + Id: 29 714 + Master payload: N/A 715 + 716 + Master advises slave that a transition to postcopy mode has happened. 717 + The slave must ensure that shared memory is registered with userfaultfd 718 + to cause faulting of non-present pages. 719 + 720 + This is always sent sometime after a VHOST_USER_POSTCOPY_ADVISE, and 721 + thus only when VHOST_USER_PROTOCOL_F_PAGEFAULT is supported. 722 + 712 723 Slave message types 713 724 ------------------- 714 725
+3
hw/virtio/trace-events
··· 6 6 vhost_region_add_section_abut(const char *name, uint64_t new_size) "%s: 0x%"PRIx64 7 7 vhost_section(const char *name, int r) "%s:%d" 8 8 9 + # hw/virtio/vhost-user.c 10 + vhost_user_postcopy_listen(void) "" 11 + 9 12 # hw/virtio/virtio.c 10 13 virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u" 11 14 virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
+34
hw/virtio/vhost-user.c
··· 20 20 #include "sysemu/cryptodev.h" 21 21 #include "migration/migration.h" 22 22 #include "migration/postcopy-ram.h" 23 + #include "trace.h" 23 24 24 25 #include <sys/ioctl.h> 25 26 #include <sys/socket.h> ··· 79 80 VHOST_USER_CREATE_CRYPTO_SESSION = 26, 80 81 VHOST_USER_CLOSE_CRYPTO_SESSION = 27, 81 82 VHOST_USER_POSTCOPY_ADVISE = 28, 83 + VHOST_USER_POSTCOPY_LISTEN = 29, 82 84 VHOST_USER_MAX 83 85 } VhostUserRequest; 84 86 ··· 172 174 int slave_fd; 173 175 NotifierWithReturn postcopy_notifier; 174 176 struct PostCopyFD postcopy_fd; 177 + /* True once we've entered postcopy_listen */ 178 + bool postcopy_listen; 175 179 }; 176 180 177 181 static bool ioeventfd_enabled(void) ··· 858 862 return 0; 859 863 } 860 864 865 + /* 866 + * Called at the switch to postcopy on reception of the 'listen' command. 867 + */ 868 + static int vhost_user_postcopy_listen(struct vhost_dev *dev, Error **errp) 869 + { 870 + struct vhost_user *u = dev->opaque; 871 + int ret; 872 + VhostUserMsg msg = { 873 + .hdr.request = VHOST_USER_POSTCOPY_LISTEN, 874 + .hdr.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK, 875 + }; 876 + u->postcopy_listen = true; 877 + trace_vhost_user_postcopy_listen(); 878 + if (vhost_user_write(dev, &msg, NULL, 0) < 0) { 879 + error_setg(errp, "Failed to send postcopy_listen to vhost"); 880 + return -1; 881 + } 882 + 883 + ret = process_message_reply(dev, &msg); 884 + if (ret) { 885 + error_setg(errp, "Failed to receive reply to postcopy_listen"); 886 + return ret; 887 + } 888 + 889 + return 0; 890 + } 891 + 861 892 static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier, 862 893 void *opaque) 863 894 { ··· 879 910 880 911 case POSTCOPY_NOTIFY_INBOUND_ADVISE: 881 912 return vhost_user_postcopy_advise(dev, pnd->errp); 913 + 914 + case POSTCOPY_NOTIFY_INBOUND_LISTEN: 915 + return vhost_user_postcopy_listen(dev, pnd->errp); 882 916 883 917 default: 884 918 /* We ignore notifications we don't know */
+1
migration/postcopy-ram.h
··· 131 131 enum PostcopyNotifyReason { 132 132 POSTCOPY_NOTIFY_PROBE = 0, 133 133 POSTCOPY_NOTIFY_INBOUND_ADVISE, 134 + POSTCOPY_NOTIFY_INBOUND_LISTEN, 134 135 }; 135 136 136 137 struct PostcopyNotifyData {
+7
migration/savevm.c
··· 1618 1618 { 1619 1619 PostcopyState ps = postcopy_state_set(POSTCOPY_INCOMING_LISTENING); 1620 1620 trace_loadvm_postcopy_handle_listen(); 1621 + Error *local_err = NULL; 1622 + 1621 1623 if (ps != POSTCOPY_INCOMING_ADVISE && ps != POSTCOPY_INCOMING_DISCARD) { 1622 1624 error_report("CMD_POSTCOPY_LISTEN in wrong postcopy state (%d)", ps); 1623 1625 return -1; ··· 1641 1643 if (postcopy_ram_enable_notify(mis)) { 1642 1644 return -1; 1643 1645 } 1646 + } 1647 + 1648 + if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_LISTEN, &local_err)) { 1649 + error_report_err(local_err); 1650 + return -1; 1644 1651 } 1645 1652 1646 1653 if (mis->have_listen_thread) {