wake iothread on virtio kick / flush_coalesced_mmio smp_wmb
cover wake iothread on virtio kick / flush_coalesced_mmio smp_wmb
See individual patches for details.
PATCH 1/2 virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
VIRTIO_PCI_QUEUE_NOTIFY is used to inform availability of new buffers, so wakeup the iothread to process that information immediately.
hw/virtio-pci.c +1 -0
@@ -204,6 +204,7 @@ static void virtio_ioport_write(void *opbreak ;case VIRTIO_PCI_QUEUE_NOTIFY :virtio_queue_notify (vdev, val); +qemu_notify_event ();break ;case VIRTIO_PCI_STATUS : vdev->status = val &0xFF ;
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 11 lines · Marcelo Tosatti
VIRTIO_PCI_QUEUE_NOTIFYis used to inform availability of new buffers, so wakeup the iothread to process that information immediately.Reported-by Amit Shah<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Index:
qemu/hw/virtio-pci.c
===================================================================
hw/virtio-pci.c static void virtio_ioport_write(void *op · line 209
Quoted 6 lines
hw/virtio-pci.c +1
-0@@ -204,6 +204,7 @@ static void virtio_ioport_write(void *opbreak ;case VIRTIO_PCI_QUEUE_NOTIFY :virtio_queue_notify (vdev, val); +qemu_notify_event ();break ;
virtio_queue_notify() will call ->handle_output(), which should either do what's needed to be done, or wake up some iothread itself.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 7 lines · Avi Kivity
Quoted 6 lines · Marcelo Tosatti
VIRTIO_PCI_QUEUE_NOTIFYis used to inform availability of new buffers, so wakeup the iothread to process that information immediately.Reported-by Amit Shah<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>
Quoted 13 lines
hw/virtio-pci.c static void virtio_ioport_write(void *op · line 208
Quoted 10 lines
Index:
qemu/hw/virtio-pci.c
===================================================================hw/virtio-pci.c +1
-0@@ -204,6 +204,7 @@ static void virtio_ioport_write(void *opbreak ;case VIRTIO_PCI_QUEUE_NOTIFY :virtio_queue_notify (vdev, val); +qemu_notify_event ();break ;
virtio_queue_notify()will call ->handle_output(), which should either do what's needed to be done, or wake up some iothread itself.
kick is used to inform either output processing, in which case ->handle_output() does what its supposed to.
But its also used to inform availability of new buffers, which is common to all virtio devices. So what is the point pushing this to ->handle_output?
Are you concerned about spurious wakeups?
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 24 lines · Marcelo Tosatti
Quoted 8 lines · Avi Kivity
Quoted 6 lines · Marcelo Tosatti
VIRTIO_PCI_QUEUE_NOTIFYis used to inform availability of new buffers, so wakeup the iothread to process that information immediately.Reported-by Amit Shah<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Quoted 14 lines
hw/virtio-pci.c static void virtio_ioport_write(void *op · line 209
Quoted 11 lines
Index:
qemu/hw/virtio-pci.c
===================================================================hw/virtio-pci.c +1
-0@@ -204,6 +204,7 @@ static void virtio_ioport_write(void *opbreak ;case VIRTIO_PCI_QUEUE_NOTIFY :virtio_queue_notify (vdev, val); +qemu_notify_event ();break ;
virtio_queue_notify()will call ->handle_output(), which should either do what's needed to be done, or wake up some iothread itself.
Quoted 7 lines
kick is used to inform either output processing, in which case ->handle_output() does what its supposed to.
But its also used to inform availability of new buffers, which is common to all virtio devices. So what is the point pushing this to ->handle_output?
I don't understand what this means. ->handle_output() _is_ informing the device model of new buffers. What more is needed?
Quoted 2 lines
Are you concerned about spurious wakeups?
Yes. Also, qemu_notify_event() is an undirected notification (wakes up all iothreads, and all devices), whereas ->handle_output() is directed (wakes up exactly what is needed).
What's the underlying problem? A new input buffer has become available, and we need to re-poll the incoming file descriptor? If so, that's best done from ->handle_output() (either by waking the iothread or calling read() itself and perhaps receiving -EAGAIN).
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 33 lines · Avi Kivity
Quoted 20 lines · Marcelo Tosatti
Quoted 7 lines · Avi Kivity
Quoted 6 lines · Marcelo Tosatti
VIRTIO_PCI_QUEUE_NOTIFYis used to inform availability of new buffers, so wakeup the iothread to process that information immediately.Reported-by Amit Shah<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Quoted 12 lines
hw/virtio-pci.c static void virtio_ioport_write(void *op · line 208
Quoted 10 lines
Index:
qemu/hw/virtio-pci.c
===================================================================hw/virtio-pci.c +1
-0@@ -204,6 +204,7 @@ static void virtio_ioport_write(void *opbreak ;case VIRTIO_PCI_QUEUE_NOTIFY :virtio_queue_notify (vdev, val); +qemu_notify_event ();break ;
virtio_queue_notify()will call ->handle_output(), which should either do what's needed to be done, or wake up some iothread itself.Quoted 6 lines
kick is used to inform either output processing, in which case ->handle_output() does what its supposed to.
But its also used to inform availability of new buffers, which is common to all virtio devices. So what is the point pushing this to ->handle_output?
I don't understand what this means. ->handle_output() _is_ informing the device model of new buffers. What more is needed?
Quoted 1 line
Are you concerned about spurious wakeups?
Quoted 8 lines
Yes. Also,
qemu_notify_event()is an undirected notification (wakes up all iothreads, and all devices), whereas ->handle_output() is directed (wakes up exactly what is needed).What's the underlying problem? A new input buffer has become available, and we need to re-poll the incoming file descriptor? If so, that's best done from ->handle_output() (either by waking the iothread or calling
read()itself and perhaps receiving-EAGAIN).
Yes. Sure, perhaps calling read() itself is appropriate, and i see your point that >handle_output contains more context for a smarter decision.
But one can argue thats an improvement on top of a dumb wakeup.
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 11 lines · Marcelo Tosatti
Quoted 11 lines
Quoted 2 lines
Are you concerned about spurious wakeups?
Yes. Also,
qemu_notify_event()is an undirected notification (wakes up all iothreads, and all devices), whereas ->handle_output() is directed (wakes up exactly what is needed).What's the underlying problem? A new input buffer has become available, and we need to re-poll the incoming file descriptor? If so, that's best done from ->handle_output() (either by waking the iothread or calling
read()itself and perhaps receiving-EAGAIN).
Quoted 6 lines
Yes. Sure, perhaps calling
read()itself is appropriate, and i see your point that>handle_output contains more context for a smarter decision.But one can argue thats an improvement on top of a dumb wakeup.
Spurious calls to qemu_notify_event() also make it difficult to tell when it's actually necessary to call qemu_notify_event() vs. when it's just something that doesn't hurt.
Regards,
Anthony Liguori
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 10 lines · Anthony Liguori
Quoted 9 lines · Marcelo Tosatti
Quoted 9 lines
Quoted 1 line
Are you concerned about spurious wakeups?
Yes. Also,
qemu_notify_event()is an undirected notification (wakes up all iothreads, and all devices), whereas ->handle_output() is directed (wakes up exactly what is needed).What's the underlying problem? A new input buffer has become available, and we need to re-poll the incoming file descriptor? If so, that's best done from ->handle_output() (either by waking the iothread or calling
read()itself and perhaps receiving-EAGAIN).
Quoted 7 lines
Quoted 5 lines
Yes. Sure, perhaps calling
read()itself is appropriate, and i see your point that>handle_output contains more context for a smarter decision.But one can argue thats an improvement on top of a dumb wakeup.
Spurious calls to
qemu_notify_event()also make it difficult to tell when it's actually necessary to callqemu_notify_event()vs. when it's just something that doesn't hurt.
One improvement in this area would be to add a context parameter (which eventually resolves to the underlying thread). Currently we'd ignore it since we have just one iothread, but it would serve to document what's being polled, and later direct the wakeup to the correct thread.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 15 lines · Avi Kivity
Quoted 14 lines · Anthony Liguori
Quoted 13 lines · Marcelo Tosatti
Quoted 9 lines
Quoted 1 line
Are you concerned about spurious wakeups?
Yes. Also,
qemu_notify_event()is an undirected notification (wakes up all iothreads, and all devices), whereas ->handle_output() is directed (wakes up exactly what is needed).What's the underlying problem? A new input buffer has become available, and we need to re-poll the incoming file descriptor? If so, that's best done from ->handle_output() (either by waking the iothread or calling
read()itself and perhaps receiving-EAGAIN).Yes. Sure, perhaps calling
read()itself is appropriate, and i see your point that>handle_output contains more context for a smarter decision.
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
But one can argue thats an improvement on top of a dumb wakeup.
Spurious calls to
qemu_notify_event()also make it difficult to tell when it's actually necessary to callqemu_notify_event()vs. when it's just something that doesn't hurt.One improvement in this area would be to add a context parameter (which eventually resolves to the underlying thread). Currently we'd ignore it since we have just one iothread, but it would serve to document what's being polled, and later direct the wakeup to the correct thread.
Ends up looking a lot like a condition. It's not necessarily a bad thing to model.
Regards,
Anthony Liguori
Re: [Qemu-devel] Re: [patch uq/master 1/2] virtio-pci: wake up iothread on VIRTIO_PCI_QUEUE_NOTIFY
Quoted 7 lines · Anthony Liguori
Quoted 3 lines
Quoted 1 line
Spurious calls to
qemu_notify_event()also make it difficult to tell when it's actually necessary to callqemu_notify_event()vs. when it's just something that doesn't hurt.One improvement in this area would be to add a context parameter (which eventually resolves to the underlying thread). Currently we'd ignore it since we have just one iothread, but it would serve to document what's being polled, and later direct the wakeup to the correct thread.
Ends up looking a lot like a condition. It's not necessarily a bad thing to model.
But the implementation is very different - condition variables sleep in pthread_cond_wait, the iothread sleeps in poll().
qemu_notify_event() is really requesting iothread t to re-add file fd to its poll set. Maybe we should make this a CharDriverState method.
Signature · 1 line
error compiling committee.c: too many arguments to function
cover introduce QEMUIOWorker and wake up iothread on virtio-serial-bus notification
In reply to Anthony LiguoriPATCH 1/2 Pass QEMUIOWorker to qemu_notify_event
This can be used later to introduce generic iothread workers.
async.c +1 -1
@@ -180,7 +180,7 @@ void qemu_bh_schedule(QEMUBH *bh) bh->scheduled =1 ; bh->idle =0 ;/* stop the currently executing CPU to execute the BH ASAP */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_bh_cancel (QEMUBH *bh)
hw/mac_dbdma.c +1 -1
@@ -655,7 +655,7 @@ void DBDMA_register_channel(void *dbdma,void DBDMA_schedule (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); } static void
hw/virtio-net.c +1 -1
@@ -359,7 +359,7 @@ static void virtio_net_handle_rx(VirtIOD/* We now have RX buffers, signal to the IO thread to break out of the * select to re-poll the tap file descriptor */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }static int virtio_net_can_receive (VLANClientState *nc)
qemu-common.h +7 -1
@@ -234,11 +234,17 @@ typedef uint64_t pcibus_t;void cpu_save (QEMUFile *f,void *opaque);int cpu_load (QEMUFile *f,void *opaque,int version_id); +typedef struct QEMUIOWorker { +void *opaque; +}QEMUIOWorker ; +/* Force QEMU to stop what it's doing and service IO */ void qemu_service_io (void );/* Force QEMU to process pending events */ -void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker); + +extern QEMUIOWorker *main_io_worker;/* Unblock cpu */ void qemu_cpu_kick (void *env);
vl.c +12 -9
@@ -274,6 +274,9 @@ uint8_t qemu_uuid[16];static QEMUBootSetHandler *boot_set_handler;static void *boot_set_opaque; +QEMUIOWorker iothread_worker; +QEMUIOWorker *main_io_worker = &iothread_worker; +#ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4)#else
@@ -885,7 +888,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64 }/* Interrupt execution to force deadline recalculation. */ if (use_icount) -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }
@@ -1062,7 +1065,7 @@ static void host_alarm_handler(int host_ }#endif timer_alarm_pending =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }
@@ -2928,7 +2931,7 @@ static int ram_load(QEMUFile *f, void *ovoid qemu_service_io (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); }/***********************************************************/
@@ -3180,26 +3183,26 @@ void qemu_system_reset_request(void) }else { reset_requested =1 ; } -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_shutdown_request (void ) { shutdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_powerdown_request (void ) { powerdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }#ifdef CONFIG_IOTHREAD static void qemu_system_vmstop_request (int reason) { vmstop_requested = reason; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }#endif
@@ -3341,7 +3344,7 @@ void qemu_cpu_kick(void *env)return ; } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {CPUState *env = cpu_single_env;
@@ -3727,7 +3730,7 @@ void qemu_init_vcpu(void *_env)tcg_init_vcpu (env); } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {qemu_event_increment (); }
Re: [Qemu-devel] [patch 1/2] Pass QEMUIOWorker to qemu_notify_event
Quoted 4 lines · Marcelo Tosatti
This can be used later to introduce generic iothread workers.
Signed-off-by Marcelo Tosatti<[email protected]>
Could you rebase this? It failed to apply in a strange way that made me nervous...
Regards,
Anthony Liguori
Quoted 158 lines
Index:
qemu-ioworker/async.c
===================================================================async.c +1
-1@@ -180,7 +180,7 @@ void qemu_bh_schedule(QEMUBH *bh) bh->scheduled =1 ; bh->idle =0 ;/* stop the currently executing CPU to execute the BH ASAP */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_bh_cancel (QEMUBH *bh)Index:
qemu-ioworker/hw/mac_dbdma.c
===================================================================hw/mac_dbdma.c +1
-1@@ -655,7 +655,7 @@ void DBDMA_register_channel(void *dbdma,void DBDMA_schedule (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); } static voidIndex:
qemu-ioworker/hw/virtio-net.c
===================================================================hw/virtio-net.c +1
-1@@ -359,7 +359,7 @@ static void virtio_net_handle_rx(VirtIOD/* We now have RX buffers, signal to the IO thread to break out of the * select to re-poll the tap file descriptor */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }static int virtio_net_can_receive (VLANClientState *nc)Index:
qemu-ioworker/qemu-common.h
===================================================================qemu-common.h +7
-1@@ -234,11 +234,17 @@ typedef uint64_t pcibus_t;void cpu_save (QEMUFile *f,void *opaque);int cpu_load (QEMUFile *f,void *opaque,int version_id); +typedef struct QEMUIOWorker { +void *opaque; +}QEMUIOWorker ; +/* Force QEMU to stop what it's doing and service IO */ void qemu_service_io (void );/* Force QEMU to process pending events */ -void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker); + +extern QEMUIOWorker *main_io_worker;/* Unblock cpu */ void qemu_cpu_kick (void *env);Index:
qemu-ioworker/vl.c
===================================================================vl.c +12
-9@@ -274,6 +274,9 @@ uint8_t qemu_uuid[16];static QEMUBootSetHandler *boot_set_handler;static void *boot_set_opaque; +QEMUIOWorker iothread_worker; +QEMUIOWorker *main_io_worker =&iothread_worker; +#ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4)#else @@ -885,7 +888,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64 }/* Interrupt execution to force deadline recalculation. */ if (use_icount) -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }@@ -1062,7 +1065,7 @@ static void host_alarm_handler(int host_ }#endif timer_alarm_pending =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }@@ -2928,7 +2931,7 @@ static int ram_load(QEMUFile *f, void *ovoid qemu_service_io (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); }/***********************************************************/ @@ -3180,26 +3183,26 @@ void qemu_system_reset_request(void) }else { reset_requested =1 ; } -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_shutdown_request (void ) { shutdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_powerdown_request (void ) { powerdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }#ifdef CONFIG_IOTHREAD static void qemu_system_vmstop_request (int reason) { vmstop_requested = reason; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }#endif @@ -3341,7 +3344,7 @@ void qemu_cpu_kick(void *env)return ; } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {CPUState *env = cpu_single_env;@@ -3727,7 +3730,7 @@ void qemu_init_vcpu(void *_env)tcg_init_vcpu (env); } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {qemu_event_increment (); }
cover introduce QEMUIOWorker and wake up iothread on virtio-serial-bus notification (v2)
Rebased to latest qemu.git.
PATCH 1/2 Pass QEMUIOWorker to qemu_notify_event
This can be used later to introduce generic iothread workers.
async.c +1 -1
@@ -180,7 +180,7 @@ void qemu_bh_schedule(QEMUBH *bh) bh->scheduled =1 ; bh->idle =0 ;/* stop the currently executing CPU to execute the BH ASAP */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_bh_cancel (QEMUBH *bh)
hw/mac_dbdma.c +1 -1
@@ -655,7 +655,7 @@ void DBDMA_register_channel(void *dbdma,void DBDMA_schedule (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); } static void
hw/virtio-net.c +1 -1
@@ -360,7 +360,7 @@ static void virtio_net_handle_rx(VirtIOD/* We now have RX buffers, signal to the IO thread to break out of the * select to re-poll the tap file descriptor */ -qemu_notify_event (); +qemu_notify_event (main_io_worker); }static int virtio_net_can_receive (VLANClientState *nc)
qemu-common.h +7 -1
@@ -235,11 +235,17 @@ typedef uint64_t pcibus_t;void cpu_save (QEMUFile *f,void *opaque);int cpu_load (QEMUFile *f,void *opaque,int version_id); +typedef struct QEMUIOWorker { +void *opaque; +}QEMUIOWorker ; +/* Force QEMU to stop what it's doing and service IO */ void qemu_service_io (void );/* Force QEMU to process pending events */ -void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker); + +extern QEMUIOWorker *main_io_worker;/* Unblock cpu */ void qemu_cpu_kick (void *env);
vl.c +10 -7
@@ -258,6 +258,9 @@ uint8_t qemu_uuid[16];static QEMUBootSetHandler *boot_set_handler;static void *boot_set_opaque; +QEMUIOWorker iothread_worker; +QEMUIOWorker *main_io_worker = &iothread_worker; +#ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4)#else
@@ -1884,7 +1887,7 @@ static int ram_load(QEMUFile *f, void *ovoid qemu_service_io (void ) { -qemu_notify_event (); +qemu_notify_event (main_io_worker); }/***********************************************************/
@@ -2137,19 +2140,19 @@ void qemu_system_reset_request(void) }else { reset_requested =1 ; } -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_shutdown_request (void ) { shutdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void qemu_system_powerdown_request (void ) { powerdown_requested =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }static int cpu_can_run (CPUState *env)
@@ -2313,7 +2316,7 @@ void qemu_cpu_kick(void *env)return ; } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {CPUState *env = cpu_single_env;
@@ -2701,7 +2704,7 @@ void qemu_init_vcpu(void *_env)tcg_init_vcpu (env); } -void qemu_notify_event (void ) +void qemu_notify_event (QEMUIOWorker *worker) {qemu_event_increment (); }
@@ -2709,7 +2712,7 @@ void qemu_notify_event(void)static void qemu_system_vmstop_request (int reason) { vmstop_requested = reason; -qemu_notify_event (); +qemu_notify_event (main_io_worker); }void vm_stop (int reason)
qemu-timer.c +2 -2
@@ -547,7 +547,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64 }/* Interrupt execution to force deadline recalculation. */ if (use_icount) -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }
@@ -775,7 +775,7 @@ static void host_alarm_handler(int host_ t->expired =alarm_has_dynticks (t); t->pending =1 ; -qemu_notify_event (); +qemu_notify_event (main_io_worker); } }
Re: [Qemu-devel] [patch 1/2] Pass QEMUIOWorker to qemu_notify_event
hw/mac_dbdma.c void DBDMA_register_channel(void *dbdma, · line 659
Quoted 8 lines
/* Force QEMU to process pending events */
hw/mac_dbdma.c +2
-1-void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker);static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }
This feels completely wrong.
Devices shouldn't know or care about implementation details like this. How is a device supposed to know which worker it should be waking up?
qemu_notify_event is an ugly hack to workaround the fact that our character device API is polled. If shouldn't exist in the first place, instead we should have a proper mechanism for device emulation to notify the CharDriverState when it is ready to recieve more data.
Paul
Re: [Qemu-devel] [patch 1/2] Pass QEMUIOWorker to qemu_notify_event
Quoted 9 lines · Paul Brook
hw/mac_dbdma.c void DBDMA_register_channel(void *dbdma, · line 659
Quoted 8 lines
/* Force QEMU to process pending events */
hw/mac_dbdma.c +2
-1-void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker);static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }
Quoted 4 lines
This feels completely wrong.
Devices shouldn't know or care about implementation details like this. How is a device supposed to know which worker it should be waking up?
Its not. It could use qemu_notify_event(DeviceInfo->worker), and have no knowledge of the internals.
Quoted 4 lines
qemu_notify_eventis an ugly hack to workaround the fact that our character device API is polled. If shouldn't exist in the first place, instead we should have a proper mechanism for device emulation to notify the CharDriverState when it is ready to recieve more data.
qemu_notify_event is used to break the main_loop_wait out of select(), to reprocess events that are handled by it (such as ability to receive more data). Perhaps it is appropriate to move that notification to another level, but there are other users of it at device level already.
Re: [Qemu-devel] [patch 1/2] Pass QEMUIOWorker to qemu_notify_event
Quoted 12 lines · Paul Brook
Quoted 11 lines
hw/mac_dbdma.c void DBDMA_register_channel(void *dbdma, · line 659
Quoted 8 lines
/* Force QEMU to process pending events */
hw/mac_dbdma.c +2
-1-void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker);static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }This feels completely wrong.
Quoted 5 lines
Quoted 2 lines
Devices shouldn't know or care about implementation details like this. How is a device supposed to know which worker it should be waking up?
Its not. It could use
qemu_notify_event(DeviceInfo->worker), and have no knowledge of the internals.
In that case I think you're abusing this API.
I'm very wary of introducing random bits of code that allegedly allow future use of threads. Exploiting thread level parallelism is a hard problem that needs proper design. A such I object to this patch, and think we first need to decide what form of concurrency model we want to use in QEMU.
Paul
Re: [Qemu-devel] [patch 1/2] Pass QEMUIOWorker to qemu_notify_event
Quoted 19 lines · Paul Brook
Quoted 13 lines · Paul Brook
Quoted 12 lines
hw/mac_dbdma.c void DBDMA_register_channel(void *dbdma, · line 659
Quoted 10 lines
/* Force QEMU to process pending events */
hw/mac_dbdma.c +2
-1-void qemu_notify_event (void ); +void qemu_notify_event (QEMUIOWorker *worker);static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }This feels completely wrong.
Quoted 6 lines
Quoted 3 lines
Devices shouldn't know or care about implementation details like this. How is a device supposed to know which worker it should be waking up?
Its not. It could use
qemu_notify_event(DeviceInfo->worker), and have no knowledge of the internals.
Quoted 7 lines
In that case I think you're abusing this API.
I'm very wary of introducing random bits of code that allegedly allow future use of threads. Exploiting thread level parallelism is a hard problem that needs proper design. A such I object to this patch, and think we first need to decide what form of concurrency model we want to use in QEMU.
I agree. There's a lot of context missing from a proposal like this.
Regards,
Anthony Liguori
Quoted 4 lines
Paul
PATCH 2/2 virtio-serial-bus: wake up iothread upon guest read notification
In reply to Marcelo TosattiWake up iothread when buffers are consumed.
hw/virtio-serial-bus.c +1 -0
@@ -331,6 +331,7 @@ static void handle_output(VirtIODevice *static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }static uint32_t get_features (VirtIODevice *vdev,uint32_t features)
PATCH 2/2 virtio-serial-bus: wake up iothread upon guest read notification
In reply to Marcelo TosattiWake up iothread when buffers are consumed.
hw/virtio-serial-bus.c +1 -0
@@ -331,6 +331,7 @@ static void handle_output(VirtIODevice *static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }static uint32_t get_features (VirtIODevice *vdev,uint32_t features)
Re: [patch 2/2] virtio-serial-bus: wake up iothread upon guest read notification
Quoted 9 lines · Marcelo Tosatti
Wake up iothread when buffers are consumed.
Signed-off-by Marcelo Tosatti <[email protected]>Index:
qemu-ioworker/hw/virtio-serial-bus.c
===================================================================
hw/virtio-serial-bus.c static void handle_output(VirtIODevice * · line 335
Quoted 5 lines
hw/virtio-serial-bus.c +1
-0@@ -331,6 +331,7 @@ static void handle_output(VirtIODevice *static void handle_input (VirtIODevice *vdev,VirtQueue *vq) { +qemu_notify_event (main_io_worker); }
ACK, the host lets us know buffers are consumed and new buffers have been added to the pool so that we can start sending more data.
Before this patch my tests took 16m18s to run.
After this patch my tests take 1m17s to run.
Both tests done with just one buffer made available in the virtio-queues.
Amit
PATCH 2/2 kvm-all.c: define smp_wmb and use it for coalesced mmio
In reply to Marcelo Tosattikvm-all.c +4 -1
@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; } +/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +void kvm_flush_coalesced_mmio_buffer (void ) {#ifdef KVM_CAP_COALESCED_MMIO
@@ -730,7 +733,7 @@ void kvm_flush_coalesced_mmio_buffer(voi ent = &ring->coalesced_mmio[ring->first];cpu_physical_memory_write (ent->phys_addr, ent->data, ent->len); -/* FIXME smp_wmb() */ +smp_wmb (); ring->first = (ring->first +1 ) %KVM_COALESCED_MMIO_MAX ; } }
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 8 lines · Marcelo Tosatti
Cc "Michael S. Tsirkin"<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Index:
qemu/kvm-all.c
===================================================================
kvm-all.c static int kvm_handle_io(uint16_t port, · line 724
Quoted 7 lines
kvm-all.c +3
-0@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; } +/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +
sfence? what about other arches?
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 12 lines · Avi Kivity
Quoted 11 lines · Marcelo Tosatti
Cc "Michael S. Tsirkin"<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Index:
qemu/kvm-all.c
===================================================================kvm-all.c +0
-0@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; }
Quoted 5 lines
kvm-all.c static int kvm_handle_io(uint16_t port, · line 723
Quoted 3 lines
kvm-all.c +3
-0+/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +sfence?
There is no need (for this case). Older read cannot be reordered with write, writes are not reordered with other writes, writes by a single processor are observed in the same order by all processors.
Quoted 1 line
what about other arches?
They need to be fixed? PPC needs an instruction apparently.
Is there any objection to including this patch?
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 21 lines · Marcelo Tosatti
Quoted 13 lines · Avi Kivity
Quoted 11 lines · Marcelo Tosatti
Cc "Michael S. Tsirkin"<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Index:
qemu/kvm-all.c
===================================================================kvm-all.c +0
-0@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; }Quoted 6 lines
kvm-all.c static int kvm_handle_io(uint16_t port,
Quoted 4 lines
kvm-all.c +3
-0+/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +sfence?
Quoted 4 lines
There is no need (for this case). Older read cannot be reordered with write, writes are not reordered with other writes, writes by a single processor are observed in the same order by all processors.
Well, Linux does use sfence. Perhaps it's only needed for WC writes (movnti and friends), but better be careful here.
Quoted 6 lines
Quoted 2 lines
what about other arches?
They need to be fixed? PPC needs an instruction apparently.
Is there any objection to including this patch?
I imagine all arches need an instruction. For reads as well.
Note, gcc has a __sync_synchronize() builtin that compiles to mfence on x86. We might use that as a baseline for both rmb and wmb, and let each arch override it incrementally.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 22 lines · Avi Kivity
Quoted 21 lines · Marcelo Tosatti
Quoted 19 lines · Avi Kivity
Quoted 8 lines · Marcelo Tosatti
Cc "Michael S. Tsirkin"<[email protected]>Signed-off-by Marcelo Tosatti<[email protected]>Index:
qemu/kvm-all.c
===================================================================kvm-all.c static int kvm_handle_io(uint16_t port, · line 724
Quoted 7 lines
kvm-all.c +3
-0@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; } +/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +sfence?
Quoted 6 lines
Quoted 4 lines
There is no need (for this case). Older read cannot be reordered with write, writes are not reordered with other writes, writes by a single processor are observed in the same order by all processors.
Well, Linux does use sfence.
At least on 64 bit it doesnt.
Quoted 7 lines
Perhaps it's only needed for WC writes
(movnti and friends), but better be careful here.Quoted 4 lines
Quoted 2 lines
what about other arches?
They need to be fixed? PPC needs an instruction apparently.
Quoted 8 lines
Quoted 2 lines
Is there any objection to including this patch?
I imagine all arches need an instruction. For reads as well.
Note, gcc has a
__sync_synchronize()builtin that compiles to mfence on x86. We might use that as a baseline for both rmb and wmb, and let each arch override it incrementally.
This it what my patch did. Note it only works well for recent gcc.
Quoted 2 lines
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 11 lines · Michael S. Tsirkin
Quoted 9 lines
Quoted 7 lines
There is no need (for this case). Older read cannot be reordered with write, writes are not reordered with other writes, writes by a single processor are observed in the same order by all processors.
Well, Linux does use sfence.
At least on 64 bit it doesnt.
Right, I was looking at wmb(), not smp_wmb().
Quoted 8 lines
Quoted 6 lines
I imagine all arches need an instruction. For reads as well.
Note, gcc has a
__sync_synchronize()builtin that compiles to mfence on x86. We might use that as a baseline for both rmb and wmb, and let each arch override it incrementally.This it what my patch did. Note it only works well for recent gcc.
Do you know how recent?
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 17 lines · Avi Kivity
Quoted 11 lines · Michael S. Tsirkin
Quoted 9 lines
Quoted 7 lines
There is no need (for this case). Older read cannot be reordered with write, writes are not reordered with other writes, writes by a single processor are observed in the same order by all processors.
Well, Linux does use sfence.
At least on 64 bit it doesnt.
Right, I was looking at
wmb(), notsmp_wmb().Quoted 2 lines
Quoted 2 lines
I imagine all arches need an instruction. For reads as well.
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Note, gcc has a
__sync_synchronize()builtin that compiles to mfence on x86. We might use that as a baseline for both rmb and wmb, and let each arch override it incrementally.This it what my patch did. Note it only works well for recent gcc.
Do you know how recent?
IIRC 4.3 has broken implementation.
4.4 seems OK as far as I can tell.
Quoted 2 lines
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 9 lines · Michael S. Tsirkin
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
I imagine all arches need an instruction. For reads as well.
Note, gcc has a
__sync_synchronize()builtin that compiles to mfence on x86. We might use that as a baseline for both rmb and wmb, and let each arch override it incrementally.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
This it what my patch did. Note it only works well for recent gcc.
Do you know how recent?
IIRC 4.3 has broken implementation.
4.4 seems OK as far as I can tell.
Well, so that idea's down.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
In reply to Marcelo TosattiQuoted 2 lines · Marcelo Tosatti
Cc "Michael S. Tsirkin" <[email protected]>Signed-off-by Marcelo Tosatti <[email protected]>
We'll need implementation for other arches, I'll dust off my patch that adds it and repost, but for now this is better than what we have.
Quoted 24 lines
Index:
qemu/kvm-all.c
===================================================================kvm-all.c +4
-1@@ -718,6 +718,9 @@ static int kvm_handle_io(uint16_t port,return 1 ; } +/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") +void kvm_flush_coalesced_mmio_buffer (void ) {#ifdef KVM_CAP_COALESCED_MMIO @@ -730,7 +733,7 @@ void kvm_flush_coalesced_mmio_buffer(voi ent = &ring->coalesced_mmio[ring->first];cpu_physical_memory_write (ent->phys_addr, ent->data, ent->len); -/* FIXME smp_wmb() */ +smp_wmb (); ring->first = (ring->first +1 ) %KVM_COALESCED_MMIO_MAX ; } }
Re: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
In reply to Marcelo Tosattikvm-all.c +2 -1
@@ -21,6 +21,7 @@#include <linux/kvm.h> #include "qemu-common.h" +#include "qemu-barrier.h" #include "sysemu.h" #include "hw/hw.h" #include "gdbstub.h"
@@ -730,7 +731,7 @@ void kvm_flush_coalesced_mmio_buffer(voi ent = &ring->coalesced_mmio[ring->first];cpu_physical_memory_write (ent->phys_addr, ent->data, ent->len); -/* FIXME smp_wmb() */ +smp_wmb (); ring->first = (ring->first +1 ) %KVM_COALESCED_MMIO_MAX ; } }
qemu-barrier.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef __QEMU_BARRIER_H +#define __QEMU_BARRIER_H 1 + +/* FIXME: arch dependant, x86 version */ +#define smp_wmb () asm volatile("" ::: "memory") + +#endif
Avi Kivity
AppliedRe: [patch uq/master 2/2] kvm-all.c: define smp_wmb and use it for coalesced mmio
Quoted 3 lines · Marcelo Tosatti
Signed-off-by Marcelo Tosatti<[email protected]>
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function