qemu: ioeventfd for virtio-ccw.
cover qemu: ioeventfd for virtio-ccw.
This patch series makes use of the s390 ioeventfd implementation to speed up virtio-ccw a bit.
We hook up virtio notifications via diagnose 500 as ioeventfds, specifying a subchannel id and virtqueue index combination.
ioeventfds are used by default for all virtio devices; there's an ioeventfd property that can be used to turn ioeventfd usage off for a device (similar to virtio-pci).
A simple dd on a virtio-blk device
dd if=/dev/vda of=/dev/null iflag=direct bs=4k count=10000
is now twice as fast :)
(Patches are against master.)
Cornelia Huck (2):
linux-headers: Update with ioeventfd changes.
virtio-ccw: Wire up ioeventfd.
hw/s390x/css.c | 2 +- hw/s390x/css.h | 1 + hw/s390x/virtio-ccw.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ hw/s390x/virtio-ccw.h | 7 +++ linux-headers/linux/kvm.h | 4 +- target-s390x/cpu.h | 16 +++++++ target-s390x/kvm.c | 27 +++++++++++ 7 files changed, 169 insertions(+), 2 deletions(-)
Signature · 1 line
1.7.12.4
RFC PATCH 1/2 linux-headers: Update with ioeventfd changes.
--- linux-headers/linux/kvm.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
linux-headers/linux/kvm.h +3 -1
@@ -448,12 +448,14 @@ enum { kvm_ioeventfd_flag_nr_datamatch, kvm_ioeventfd_flag_nr_pio, kvm_ioeventfd_flag_nr_deassign, + kvm_ioeventfd_flag_nr_arch, kvm_ioeventfd_flag_nr_max, };#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)#define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio)#define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_ARCH (1 << kvm_ioeventfd_flag_nr_arch)#define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1)
@@ -463,7 +465,7 @@ struct kvm_ioeventfd {__u32 len;/* 1, 2, 4, or 8 bytes */ __s32 fd;__u32 flags; -__u8 pad[36 ]; +__u8 data[36 ];/* for architecture-specific data */ };/* for KVM_ENABLE_CAP */
Signature · 1 line
1.7.12.4
RFC PATCH 2/2 virtio-ccw: Wire up ioeventfd.
In reply to Cornelia HuckOn hosts that support ioeventfd, make use of it for host-to-guest notifications via diagnose 500.
--- hw/s390x/css.c | 2 +- hw/s390x/css.h | 1 + hw/s390x/virtio-ccw.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/s390x/virtio-ccw.h | 7 ++++ target-s390x/cpu.h | 16 +++++++ target-s390x/kvm.c | 27 ++++++++++++ 6 files changed, 166 insertions(+), 1 deletion(-)
hw/s390x/css.c +1 -1
@@ -68,7 +68,7 @@ int css_create_css_image(uint8_t cssid, bool default_image)return 0 ; } -static uint16_t css_build_subchannel_id (SubchDev *sch) +uint16_t css_build_subchannel_id (SubchDev *sch) {if (channel_subsys->max_cssid >0 ) {return (sch->cssid <<8 ) | (1 <<3 ) | (sch->ssid <<1 ) |1 ;
hw/s390x/css.h +1 -0
@@ -90,6 +90,7 @@ bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno);void css_subch_assign (uint8_t cssid,uint8_t ssid,uint16_t schid,uint16_t devno,SubchDev *sch);void css_sch_build_virtual_schib (SubchDev *sch,uint8_t chpid,uint8_t type); +uint16_t css_build_subchannel_id (SubchDev *sch);void css_reset (void );void css_reset_sch (SubchDev *sch);void css_queue_crw (uint8_t rsc,uint8_t erc,int chain,uint16_t rsid);
hw/s390x/virtio-ccw.c +114 -0
217 lines not on this page · raw message
hw/s390x/virtio-ccw.h +7 -0
@@ -66,6 +66,11 @@ typedef struct VirtIOCCWDeviceClass {/* Change here if we want to support more feature bits. */ #define VIRTIO_CCW_FEATURE_SIZE 1 +/* Performance improves when virtqueue kick processing is decoupled from the +* vcpu thread using ioeventfd for some devices. */ +#define VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT 1 +#define VIRTIO_CCW_FLAG_USE_IOEVENTFD (1 << VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT) +struct VirtioCcwDevice {DeviceState parent_obj;SubchDev *sch;
@@ -78,6 +83,8 @@ struct VirtioCcwDevice {virtio_net_conf net;VirtIOSCSIConf scsi;VirtioBusState bus; +bool ioeventfd_started; +uint32_t flags;/* Guest provided values: */ hwaddr indicators;hwaddr indicators2;
target-s390x/cpu.h +16 -0
@@ -1068,6 +1068,7 @@ void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id, uint32_t io_int_word);void kvm_s390_crw_mchk (S390CPU *cpu);void kvm_s390_enable_css_support (S390CPU *cpu); +int kvm_s390_assign_subch_ioeventfd (int fd,uint32_t sch,int vq,bool assign);#else static inline void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id,
@@ -1082,6 +1083,11 @@ static inline void kvm_s390_crw_mchk(S390CPU *cpu)static inline void kvm_s390_enable_css_support (S390CPU *cpu) { } +static inline int kvm_s390_assign_subch_ioeventfd (int fd,uint32_t sch,int vq, +bool assign) +{ +return -ENOSYS ; +}#endif static inline void s390_io_interrupt(S390CPU *cpu,
@@ -1108,4 +1114,14 @@ static inline void s390_crw_mchk(S390CPU *cpu) } } +static inline int s390_assign_subch_ioeventfd (int fd,uint32_t sch_id,int vq, +bool assign) +{ +if (kvm_enabled ()) { +return kvm_s390_assign_subch_ioeventfd (fd, sch_id, vq, assign); + }else { +return -ENOSYS ; + } +} +#endif
target-s390x/kvm.c +27 -0
@@ -847,3 +847,30 @@ void kvm_s390_enable_css_support(S390CPU *cpu) r =kvm_vcpu_ioctl (CPU (cpu),KVM_ENABLE_CAP , &cap);assert (r ==0 ); } + +#define KVM_S390_IOEVENTFD_VIRTIO_CCW_NOTIFY 1 +int kvm_s390_assign_subch_ioeventfd (int fd,uint32_t sch,int vq,bool assign) +{ +struct kvm_ioeventfd kick = { + .flags =KVM_IOEVENTFD_FLAG_ARCH , + .fd = fd, + }; +struct { +uint8_t type; +uint64_t vq; +uint32_t sch; + } QEMU_PACKED payload; + +if (!kvm_check_extension (kvm_state,KVM_CAP_IOEVENTFD )) { +return -ENOSYS ; + } + payload.type =KVM_S390_IOEVENTFD_VIRTIO_CCW_NOTIFY ; + payload.vq = vq; + payload.sch = sch; +memcpy (kick.data, &payload,sizeof (payload)); + +if (!assign) { + kick.flags |=KVM_IOEVENTFD_FLAG_DEASSIGN ; + } +return kvm_vm_ioctl (kvm_state,KVM_IOEVENTFD , &kick); +}
Signature · 1 line
1.7.12.4