On 10/27/07, Blue Swirl <[EMAIL PROTECTED]> wrote:
> I changed Slirp output to use vectored IO to avoid the slowdown from
> memcpy (see the patch for the work in progress, gives a small
> performance improvement). But then I got the idea that using AIO would
> be nice at the outgoing end of the network IO processing. In fact,
> vectored AIO model could even be used for the generic DMA! The benefit
> is that no buffering or copying should be needed.

I made a sketch of the API, please have a look at the patch.

> Each stage would translate the IO list and callback as needed and only
> the final stage would perform the IO or memcpy. This would be used in
> each stage of the chain memory<->IOMMU<->device<->SLIRP<->host network
> device. Of course some kind of host support for vectored AIO for these
> devices is required. On target side, devices that can do
> scatter/gather DMA would benefit most.

Inside Qemu the vectors would use target physical addresses (struct
qemu_iovec), but at some point the addresses would change to host
pointers suitable for real AIO.
Index: qemu/vl.h
===================================================================
--- qemu.orig/vl.h	2007-10-27 14:58:09.000000000 +0000
+++ qemu/vl.h	2007-10-27 16:51:40.000000000 +0000
@@ -746,6 +746,85 @@
 
 #include "hw/irq.h"
 
+/* Generic DMA API */
+
+typedef void DMADriverCompletionFunc(void *opaque, int ret);
+
+struct qemu_iovec {
+    target_phys_addr_t iov_base;
+    size_t iov_len;
+};
+
+typedef struct qemu_bus qemu_bus;
+
+typedef struct DMADriverAIOCB {
+    void *opaque;
+    int type;
+    int nent;
+    struct aiocb **aiocb;
+    DMADriverCompletionFunc *cb;
+    struct DMADriverAIOCB *next;
+} DMADriverAIOCB;
+
+typedef void DMARWHandler(void *opaque,
+                          const struct qemu_iovec *dst_vector,
+                          int dst_count,
+                          const struct qemu_iovec *src_vector,
+                          int src_count);
+
+qemu_bus *bus_init(unsigned int bus_bits, DMARWHandler north_handler,
+                   void *north_handler_opaque, DMARWHandler south_handler,
+                   void *south_handler_opaque);
+
+/* Direction CPU->bridge->device/memory */
+void bus_rw_south(qemu_bus *bus,
+                  const struct qemu_iovec *dst_vector,
+                  int dst_count,
+                  const struct qemu_iovec *src_vector,
+                  int src_count,
+                  int is_write);
+
+static inline void bus_read_south(qemu_bus *bus,
+                                  const struct qemu_iovec *dst_vector,
+                                  int dst_count,
+                                  const struct qemu_iovec *src_vector,
+                                  int src_count)
+{
+    bus_rw_south(bus, dst_vector, dst_count, src_vector, src_count, 0);
+}
+static inline void bus_write_south(qemu_bus *bus,
+                                   const struct qemu_iovec *dst_vector,
+                                   int dst_count,
+                                   const struct qemu_iovec *src_vector,
+                                   int src_count)
+{
+    bus_rw_south(bus, dst_vector, dst_count, src_vector, src_count, 1);
+}
+/* From device towards CPU/memory (DMA) */
+void bus_rw_north(qemu_bus *bus,
+                  const struct qemu_iovec *dst_vector,
+                  int dst_count,
+                  const struct qemu_iovec *src_vector,
+                  int src_count,
+                  int is_write);
+
+static inline void bus_read_north(qemu_bus *bus,
+                                  const struct qemu_iovec *dst_vector,
+                                  int dst_count,
+                                  const struct qemu_iovec *src_vector,
+                                  int src_count)
+{
+    bus_rw_north(bus, dst_vector, dst_count, src_vector, src_count, 0);
+}
+static inline void bus_write_north(qemu_bus *bus,
+                                   const struct qemu_iovec *dst_vector,
+                                   int dst_count,
+                                   const struct qemu_iovec *src_vector,
+                                   int src_count)
+{
+    bus_rw_north(bus, dst_vector, dst_count, src_vector, src_count, 1);
+}
+
 /* ISA bus */
 
 extern target_phys_addr_t isa_mem_base;

Reply via email to