Skip to contentSkip to conversation

virtio with config abstraction and ring implementation

PATCH In review Rusty Russell 15 participants 82 messages Sep 20, 2007 – Sep 26, 2007 30 messages not in the archive

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

cover virtio with config abstraction and ring implementation

Hi all,

This patch series attempts to come closer to unifying kvm and lguest's
usage of virtio. As these two are the first implementations we've seen, I hope making them closer will make future ones closer too.

Drivers now unpack their own configuration: their probe() methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I've abstracted out the lguest ring buffer code into a common library.
The format has changed slightly (mainly because I had an epiphany about inter-guest I/O).

I also implemented a console (lguest needs one).

Finally, there is a working lguest implementation. Unfortunately,
lguest is being refactored for non-i386 ports, so the virtio patches sit at the end of the (quite long) for-2.6.24 patchqueue. Nonetheless, they can be found at http://lguest.ozlabs.org/patches (click on bz2 to get the series).

Cheers!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190289808.7262.223.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#2 lore raw

PATCH 1/6 virtio interace

(Changes:
- renamed sync to kick as Dor suggested
- added new_vq and free_vq hooks to create virtqueues
- define a simple virtio driver, which uses PCI ids
- provide register/unregister_virtio_driver hooks)

This attempts to implement a "virtual I/O" layer which should allow common drivers to be efficiently used across most virtual I/O mechanisms. It will no-doubt need further enhancement.

The virtio drivers add and get I/O buffers; as the buffers are consumed the driver "interrupt" callbacks are invoked.

It also provides driver register and unregister hooks, which are simply overridden at run time (eg. for a guest kernel which supports KVM paravirt and lguest).

---
 drivers/virtio/Kconfig  |    3 +
 drivers/virtio/Makefile |    1 
 drivers/virtio/virtio.c |   20 ++++++++
 include/linux/virtio.h  |  114 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 138 insertions(+)

===================================================================

drivers/virtio/Kconfig new file +3 -0
@@ -0,0 +1,3 @@
+# Virtio always gets selected by whoever wants it.
+config VIRTIO
+	bool

===================================================================

drivers/virtio/Makefile new file +1 -0
@@ -0,0 +1,1 @@
+obj-$(CONFIG_VIRTIO) += virtio.o

===================================================================

drivers/virtio/virtio.c new file +20 -0
@@ -0,0 +1,20 @@
+#include <linux/virtio.h>
+
+struct virtio_backend_ops virtio_backend_ops;
+EXPORT_SYMBOL_GPL(virtio_backend_ops);
+
+/* register and unregister simply punt through to the specific backend. */
+int register_virtio_driver(struct virtio_driver *drv)
+{
+	if (!virtio_backend_ops.register_driver)
+		return -ENOSYS;
+
+	return virtio_backend_ops.register_driver(drv);
+}
+EXPORT_SYMBOL_GPL(register_virtio_driver);
+
+void unregister_virtio_driver(struct virtio_driver *drv)
+{
+	virtio_backend_ops.unregister_driver(drv);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_driver);

===================================================================

include/linux/virtio.h new file +114 -0

114 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190290140.7262.228.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#4 lore raw

PATCH 2/6 virtio_config

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

---
 drivers/Kconfig               |    2 
 drivers/Makefile              |    1 
 drivers/virtio/Makefile       |    2 
 drivers/virtio/config.c       |  109 +++++++++++++++++++++++++++++++
 include/linux/virtio_config.h |  141 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 254 insertions(+), 1 deletion(-)

===================================================================

drivers/Kconfig +2 -0
@@ -87,4 +87,6 @@ source "drivers/kvm/Kconfig"
 source "drivers/kvm/Kconfig"
 
 source "drivers/uio/Kconfig"
+
+source "drivers/virtio/Kconfig"
 endmenu

===================================================================

drivers/Makefile +1 -0
@@ -88,3 +88,4 @@ obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_OF)		+= of/
+obj-$(CONFIG_VIRTIO)		+= virtio/

===================================================================

drivers/virtio/Makefile +1 -1
@@ -1,1 +1,1 @@ obj-$(CONFIG_VIRTIO) += virtio.o
-obj-$(CONFIG_VIRTIO) += virtio.o
+obj-$(CONFIG_VIRTIO) += virtio.o config.o

===================================================================

drivers/virtio/config.c new file +109 -0

109 lines not on this page · raw message

===================================================================

include/linux/virtio_config.h new file +141 -0

141 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190290369.7262.231.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#6 lore raw

PATCH 3/6 virtio net driver

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

TODO:
1) Big packets.
2) Multi-client devices (maybe separate driver?).
3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

---
 drivers/net/Kconfig        |    6 
 drivers/net/Makefile       |    2 
 drivers/net/virtio_net.c   |  438 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/virtio_net.h |   36 +++
 4 files changed, 481 insertions(+), 1 deletion(-)

===================================================================

drivers/net/Kconfig +6 -0
@@ -2998,4 +2998,10 @@ config NET_POLL_CONTROLLER
 config NET_POLL_CONTROLLER
 	def_bool NETPOLL
 
+config VIRTIO_NET
+	tristate "Virtio network driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual network driver for lguest.  Say Y or M.
+
 endif # NETDEVICES

===================================================================

drivers/net/Makefile +1 -1
@@ -38,7 +38,7 @@ obj-$(CONFIG_SUNVNET) += sunvnet.o
 
 obj-$(CONFIG_MACE) += mace.o
 obj-$(CONFIG_BMAC) += bmac.o
-
+obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_DGRS) += dgrs.o
 obj-$(CONFIG_VORTEX) += 3c59x.o
 obj-$(CONFIG_TYPHOON) += typhoon.o

===================================================================

drivers/net/virtio_net.c new file +438 -0

438 lines not on this page · raw message

===================================================================

include/linux/virtio_net.h new file +36 -0
@@ -0,0 +1,36 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_net */
+#define VIRTIO_ID_NET	1
+
+/* The bitmap of config for virtio net */
+#define VIRTIO_CONFIG_NET_F	0x40
+#define VIRTIO_NET_F_NO_CSUM	1
+#define VIRTIO_NET_F_TSO4	2
+#define VIRTIO_NET_F_UFO	4
+#define VIRTIO_NET_F_TSO4_ECN	8
+#define VIRTIO_NET_F_TSO6	16
+
+/* The config defining mac address. */
+#define VIRTIO_CONFIG_NET_MAC_F	0x41
+
+/* This is the first element of the scatter-gather list.  If you don't
+ * specify GSO or CSUM features, you can simply ignore the header. */
+struct virtio_net_hdr
+{
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM	1	// Use csum_start, csum_offset
+      __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE		0	// Not a GSO frame
+#define VIRTIO_NET_HDR_GSO_TCPV4	1	// GSO frame, IPv4 TCP (TSO)
+/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
+#define VIRTIO_NET_HDR_GSO_TCPV4_ECN	2	// GSO frame, IPv4 TCP w/ ECN
+#define VIRTIO_NET_HDR_GSO_UDP		3	// GSO frame, IPv4 UDP (UFO)
+#define VIRTIO_NET_HDR_GSO_TCPV6	4	// GSO frame, IPv6 TCP
+      __u8 gso_type;
+      __u16 gso_size;
+      __u16 csum_start;
+      __u16 csum_offset;
+};
+#endif /* _LINUX_VIRTIO_NET_H */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190290495.7262.235.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#8 lore raw

PATCH 4/6 virtio block driver

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

---
 drivers/block/Kconfig      |    6 
 drivers/block/Makefile     |    1 
 drivers/block/virtio_blk.c |  327 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/Kbuild       |    1 
 include/linux/virtio_blk.h |   51 ++++++
 5 files changed, 386 insertions(+)

===================================================================

drivers/block/Kconfig +6 -0
@@ -443,4 +443,10 @@ config XEN_BLKDEV_FRONTEND
 	  block device driver.  It communicates with a back-end driver
 	  in another domain which drives the actual block device.
 
+config VIRTIO_BLK
+	tristate "Virtio block driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual block driver for lguest.  Say Y or M.
+
 endif # BLK_DEV

===================================================================

drivers/block/Makefile +1 -0
@@ -25,6 +25,7 @@ obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
+obj-$(CONFIG_VIRTIO_BLK)	+= virtio_blk.o
 
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o

===================================================================

drivers/block/virtio_blk.c new file +327 -0

327 lines not on this page · raw message

===================================================================

include/linux/Kbuild +1 -0
@@ -343,6 +343,7 @@ unifdef-y += utsname.h
 unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
+unifdef-y += virtio_blk.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h

===================================================================

include/linux/virtio_blk.h new file +51 -0

51 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190290606.7262.239.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#10 lore raw

PATCH 5/6 virtio console driver

This is an hvc-based virtio console driver. It's suboptimal becuase hvc expects to have raw access to interrupts and virtio doesn't assume that, so it currently polls.

There are two solutions: expose hvc's "kick" interface, or wean off hvc.

---
 drivers/char/Kconfig           |    4 
 drivers/char/Makefile          |    1 
 drivers/char/virtio_console.c  |  232 ++++++++++++++++++++++++++++++++++++++++
 include/linux/virtio_console.h |   12 ++
 4 files changed, 249 insertions(+)

===================================================================

drivers/char/Kconfig +4 -0
@@ -613,6 +613,10 @@ config HVC_XEN
 	help
 	  Xen virtual console device driver
 
+config VIRTIO_CONSOLE
+	bool
+	select HVC_DRIVER
+
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES

===================================================================

drivers/char/Makefile +1 -0
@@ -50,6 +50,7 @@ obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
 obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
 obj-$(CONFIG_HVC_DRIVER)	+= hvc_console.o
 obj-$(CONFIG_HVC_XEN)		+= hvc_xen.o
+obj-$(CONFIG_VIRTIO_CONSOLE)	+= virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)		+= mspec.o

===================================================================

drivers/char/virtio_console.c new file +232 -0

232 lines not on this page · raw message

===================================================================

include/linux/virtio_console.h new file +12 -0
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_CONSOLE_H
+#define _LINUX_VIRTIO_CONSOLE_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_CONSOLE	3
+
+#ifdef __KERNEL__
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_VIRTIO_CONSOLE_H */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190290761.7262.242.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#12 lore raw

PATCH 6/6 virtio ring helper

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

1) The rings are variable sized (2^n-1 elements).
2) They have an unfortunate limit of 65535 bytes per sg element.
3) The page numbers are always 64 bit (PAE anyone?)
4) They no longer place used[] on a separate page, just a separate cacheline.
5) We do a modulo on a variable. We could be tricky if we cared.

Users need only implement the new_vq and free_vq hooks (KVM wants the guest to allocate the rings, lguest does it sanely).

---
 arch/i386/lguest/Kconfig     |    1 
 drivers/virtio/Kconfig       |    5 
 drivers/virtio/Makefile      |    1 
 drivers/virtio/virtio_ring.c |  301 ++++++++++++++++++++++++++++++++++++++++++
 drivers/virtio/vring.h       |   50 ++++++
 include/linux/virtio_ring.h  |   96 +++++++++++++
 6 files changed, 454 insertions(+)

===================================================================

arch/i386/lguest/Kconfig +1 -0
@@ -2,6 +2,7 @@ config LGUEST_GUEST
 	bool "Lguest guest support"
 	select PARAVIRT
 	depends on !X86_PAE
+	select VIRTIO_RING
 	help
 	  Lguest is a tiny in-kernel hypervisor.  Selecting this will
 	  allow your kernel to boot under lguest.  This option will increase

===================================================================

drivers/virtio/Kconfig +5 -0
@@ -1,3 +1,8 @@
 # Virtio always gets selected by whoever wants it.
 config VIRTIO
 	bool
+
+# Similarly the virtio ring implementation.
+config VIRTIO_RING
+	bool
+	depends on VIRTIO

===================================================================

drivers/virtio/Makefile +1 -0
@@ -1,1 +1,2 @@ obj-$(CONFIG_VIRTIO) += virtio.o config.
 obj-$(CONFIG_VIRTIO) += virtio.o config.o
+obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o

===================================================================

drivers/virtio/virtio_ring.c new file +301 -0

301 lines not on this page · raw message

===================================================================

drivers/virtio/vring.h new file +50 -0

50 lines not on this page · raw message

===================================================================

include/linux/virtio_ring.h new file +96 -0

96 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190291234.7262.246.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#14 lore raw

Re: [PATCH 6/6] virtio ring helper

Quoted 6 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 46F26AF6.60904-atKUWr5tajBWk0Htik3J/[email protected]

#16 lore raw

Re: [PATCH 6/6] virtio ring helper

Quoted 10 lines · Avi Kivity
Quoted 6 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Will fix and resend tomorrow (Friday is in-office-away-from-test-machine day).

Quoted 3 lines

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

The intent is for kvm to use it. I'll certainly consider your patches, although I suspect that managing descriptor pages will make things ugly enough to cause you to reconsider.

Thanks!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190340251.19451.36.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#18 lore raw

Re: [PATCH 6/6] virtio ring helper

Quoted 11 lines · Rusty Russell
Quoted 9 lines · Avi Kivity
Quoted 7 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

Quoted 9 lines
Quoted 3 lines

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Why are we sending page numbers anyway? See below.

Quoted 9 lines
Quoted 4 lines

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

The intent is for kvm to use it. I'll certainly consider your patches, although I suspect that managing descriptor pages will make things ugly enough to cause you to reconsider.

How about, instead:

    struct vring_desc {
         __u64 address;
         __u32 length;
         __u32 flags;
    };

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

This has the following nice properties:
- no dependency on page size, for archs where the page size definition is muddy
- no indirection for ethernet rx on Linux, even with jumbograms (a buffer can span pages in one descriptor, as long as they're physically contiguous)
- reward OSes that can do contiguous I/O (with a 32-bit length, too)
- keeps the interface simple at the expense of the implementation (address vs. page+offset)
- no nasty 16-bit fields, which some archs don't like
- be free! cast off your chains!

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 46F63A64.9070200-atKUWr5tajBWk0Htik3J/[email protected]

#20 lore raw

Re: [PATCH 6/6] virtio ring helper

Quoted 11 lines · Avi Kivity
Quoted 8 lines · Rusty Russell
Quoted 2 lines · Avi Kivity

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Why are we sending page numbers anyway? See below.

Perhaps I was unclear. I already changed to a 64-bit address. I haven't send out another set of patches because I'm changing to Arnd's explicit virtio bus too. Will send out a new set tomorrow at this rate.

Quoted 3 lines

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

If that's all we wanted, it's fairly easy to do as a future extension even if we didn't change it today. My concern was the allocation and management of those sg pages; hence my desire for a patch 8)

Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190547607.27805.120.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#22 lore raw

Re: [PATCH 6/6] virtio ring helper

Quoted 14 lines · Rusty Russell
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Rusty Russell
Quoted 3 lines · Avi Kivity

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Quoted 8 lines
Quoted 2 lines

Why are we sending page numbers anyway? See below.

Perhaps I was unclear. I already changed to a 64-bit address. I haven't send out another set of patches because I'm changing to Arnd's explicit virtio bus too. Will send out a new set tomorrow at this rate.

It does say so quite explicitly in the quoted text. Sorry.

Quoted 9 lines
Quoted 4 lines

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

If that's all we wanted, it's fairly easy to do as a future extension even if we didn't change it today. My concern was the allocation and management of those sg pages; hence my desire for a patch 8)

Won't kmalloc()/kfree() suffice? IMO the tradeoff (compared to chaining with its reduction in ring size, and handling ood) is positive.

I'll try a patch based on the next patchset.

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#23 lore raw

Re: [kvm-devel] [PATCH 6/6] virtio ring helper

In reply to Rusty Russell
Quoted 13 lines · Rusty Russell
Quoted 11 lines · Avi Kivity
Quoted 9 lines · Rusty Russell
Quoted 2 lines · Avi Kivity

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Quoted 8 lines
Quoted 2 lines

Why are we sending page numbers anyway? See below.

Perhaps I was unclear. I already changed to a 64-bit address. I haven't send out another set of patches because I'm changing to Arnd's explicit virtio bus too. Will send out a new set tomorrow at this rate.

It does say so quite explicitly in the quoted text. Sorry.

Quoted 7 lines
Quoted 2 lines

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

If that's all we wanted, it's fairly easy to do as a future extension even if we didn't change it today. My concern was the allocation and management of those sg pages; hence my desire for a patch 8)

Won't kmalloc()/kfree() suffice? IMO the tradeoff (compared to chaining with its reduction in ring size, and handling ood) is positive.

I'll try a patch based on the next patchset.

Signature · 1 line
error compiling committee.c: too many arguments to function
#24 lore raw

Re: [kvm-devel] [PATCH 6/6] virtio ring helper

In reply to Avi Kivity
Quoted 11 lines · Avi Kivity
Quoted 8 lines · Rusty Russell
Quoted 2 lines · Avi Kivity

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Why are we sending page numbers anyway? See below.

Perhaps I was unclear. I already changed to a 64-bit address. I haven't send out another set of patches because I'm changing to Arnd's explicit virtio bus too. Will send out a new set tomorrow at this rate.

Quoted 3 lines

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

If that's all we wanted, it's fairly easy to do as a future extension even if we didn't change it today. My concern was the allocation and management of those sg pages; hence my desire for a patch 8)

Rusty.

#25 lore raw

Re: [kvm-devel] [PATCH 6/6] virtio ring helper

In reply to Rusty Russell
Quoted 11 lines · Rusty Russell
Quoted 9 lines · Avi Kivity
Quoted 7 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

Quoted 8 lines
Quoted 2 lines

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Why are we sending page numbers anyway? See below.

Quoted 7 lines
Quoted 2 lines

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

The intent is for kvm to use it. I'll certainly consider your patches, although I suspect that managing descriptor pages will make things ugly enough to cause you to reconsider.

How about, instead:

   struct vring_desc {
        __u64 address;
        __u32 length;
        __u32 flags;
   };

Where one of the flags is VRING_DESC_INDIRECT, which means that the memory within (address, length) is a bunch of descriptors instead of raw data.

This has the following nice properties:
- no dependency on page size, for archs where the page size definition is muddy
- no indirection for ethernet rx on Linux, even with jumbograms (a buffer can span pages in one descriptor, as long as they're physically contiguous)
- reward OSes that can do contiguous I/O (with a 32-bit length, too)
- keeps the interface simple at the expense of the implementation (address vs. page+offset)
- no nasty 16-bit fields, which some archs don't like
- be free! cast off your chains!

Signature · 1 line
error compiling committee.c: too many arguments to function
#26 lore raw

Re: [kvm-devel] [PATCH 6/6] virtio ring helper

In reply to Avi Kivity
Quoted 10 lines · Avi Kivity
Quoted 6 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I like to feel that I make these mistakes to ensure others are paying attention. However, it does mean that I can just put an address in there and increase the length field to 32 bits. Much rejoicing.

Will fix and resend tomorrow (Friday is in-office-away-from-test-machine day).

Quoted 3 lines

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

The intent is for kvm to use it. I'll certainly consider your patches, although I suspect that managing descriptor pages will make things ugly enough to cause you to reconsider.

Thanks!
Rusty.

#27 lore raw

Re: [kvm-devel] [PATCH 6/6] virtio ring helper

In reply to Rusty Russell
Quoted 6 lines · Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

3) The page numbers are always 64 bit (PAE anyone?)

32 bits of page numbers give 44 bits of physical address on x86. That's 16TB per guest. Admittedly it's smaller on a VAX.

I don't like the chaining and would prefer the descriptor to refer to an array of page descriptors. However I can't complain since this isn't common code.

Signature · 1 line
error compiling committee.c: too many arguments to function
#28 lore raw

PATCH 6/6 virtio ring helper

In reply to Rusty Russell

These helper routines supply most of the virtqueue_ops for hypervisors which want to use a ring for virtio. Unlike the previous lguest implementation:

1) The rings are variable sized (2^n-1 elements).
2) They have an unfortunate limit of 65535 bytes per sg element.
3) The page numbers are always 64 bit (PAE anyone?)
4) They no longer place used[] on a separate page, just a separate cacheline.
5) We do a modulo on a variable. We could be tricky if we cared.

Users need only implement the new_vq and free_vq hooks (KVM wants the guest to allocate the rings, lguest does it sanely).

---
 arch/i386/lguest/Kconfig     |    1 
 drivers/virtio/Kconfig       |    5 
 drivers/virtio/Makefile      |    1 
 drivers/virtio/virtio_ring.c |  301 ++++++++++++++++++++++++++++++++++++++++++
 drivers/virtio/vring.h       |   50 ++++++
 include/linux/virtio_ring.h  |   96 +++++++++++++
 6 files changed, 454 insertions(+)

===================================================================

arch/i386/lguest/Kconfig +1 -0
@@ -2,6 +2,7 @@ config LGUEST_GUEST
 	bool "Lguest guest support"
 	select PARAVIRT
 	depends on !X86_PAE
+	select VIRTIO_RING
 	help
 	  Lguest is a tiny in-kernel hypervisor.  Selecting this will
 	  allow your kernel to boot under lguest.  This option will increase

===================================================================

drivers/virtio/Kconfig +5 -0
@@ -1,3 +1,8 @@
 # Virtio always gets selected by whoever wants it.
 config VIRTIO
 	bool
+
+# Similarly the virtio ring implementation.
+config VIRTIO_RING
+	bool
+	depends on VIRTIO

===================================================================

drivers/virtio/Makefile +1 -0
@@ -1,1 +1,2 @@ obj-$(CONFIG_VIRTIO) += virtio.o config.
 obj-$(CONFIG_VIRTIO) += virtio.o config.o
+obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o

===================================================================

drivers/virtio/virtio_ring.c new file +301 -0

301 lines not on this page · raw message

===================================================================

drivers/virtio/vring.h new file +50 -0

50 lines not on this page · raw message

===================================================================

include/linux/virtio_ring.h new file +96 -0

96 lines not on this page · raw message

#29 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to a message not in the archive
Quoted 10 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

They should, if they imply a data transfer.

Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

Signature · 7 lines
Jens Axboe


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 20070920122713.GK2367-tSWWG44O7X1aa/[email protected]

#31 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 7 lines · Jens Axboe
Quoted 6 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

Quoted 6 lines
Quoted 4 lines

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

They should, if they imply a data transfer.

OK, good. We rely on that to mark input vs output sg elements. I was wondering if there was some weird requests which did both input and output.

Quoted 6 lines
Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

To be fair, I've left the complaint in that same patch, you're just reading it repeatedly 8)

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

Thanks!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190376007.27805.19.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#33 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 13 lines · Rusty Russell
Quoted 12 lines · Jens Axboe
Quoted 10 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

Quoted 5 lines
Quoted 1 line

They should, if they imply a data transfer.

OK, good. We rely on that to mark input vs output sg elements. I was wondering if there was some weird requests which did both input and output.

There very soon will be bidirectional requests with both in and out elements, but they will be clearly marked as such (and the driver needs to be marked capable). So nothing to worry about for now.

Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

To be fair, I've left the complaint in that same patch, you're just reading it repeatedly 8)

That may be the case :-)

Quoted 3 lines

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

It surely sounds like a bug, if you issue ioctl(fd, CDROMEJECT), the driver sees it and returns -ENOTTY, but userland sees a 0 retval. So if you have time, please do poke at it a bit.

Signature · 7 lines
Jens Axboe


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 20070921122746.GO2367-tSWWG44O7X1aa/[email protected]

#35 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 8 lines · Jens Axboe
Quoted 3 lines · Rusty Russell

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

It surely sounds like a bug, if you issue ioctl(fd, CDROMEJECT), the driver sees it and returns -ENOTTY, but userland sees a 0 retval. So if you have time, please do poke at it a bit.

OK, error (-ENOTTY) gets to blk_end_sync_rq(), but nothing happens to it. This patch makes the ioctl return -EIO: I can't see a way to pass the errno back properly.

block/ll_rw_blk.c +3 -0
diff -r 99e125262d6a block/ll_rw_blk.c
@@ -2792,6 +2792,9 @@ void blk_end_sync_rq(struct request *rq,
 	rq->end_io_data = NULL;
 	__blk_put_request(rq->q, rq);
 
+	if (error)
+		rq->errors++;
+
 	/*
 	 * complete last, if this is a stack request the process (and thus
 	 * the rq pointer) could be invalid right after this complete()

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#36 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Jens Axboe
Quoted 8 lines · Jens Axboe
Quoted 3 lines · Rusty Russell

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

It surely sounds like a bug, if you issue ioctl(fd, CDROMEJECT), the driver sees it and returns -ENOTTY, but userland sees a 0 retval. So if you have time, please do poke at it a bit.

OK, error (-ENOTTY) gets to blk_end_sync_rq(), but nothing happens to it. This patch makes the ioctl return -EIO: I can't see a way to pass the errno back properly.

block/ll_rw_blk.c +3 -0
diff -r 99e125262d6a block/ll_rw_blk.c
@@ -2792,6 +2792,9 @@ void blk_end_sync_rq(struct request *rq,
 	rq->end_io_data = NULL;
 	__blk_put_request(rq->q, rq);
 
+	if (error)
+		rq->errors++;
+
 	/*
 	 * complete last, if this is a stack request the process (and thus
 	 * the rq pointer) could be invalid right after this complete()
#37 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Rusty Russell
Quoted 13 lines · Rusty Russell
Quoted 12 lines · Jens Axboe
Quoted 10 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

Quoted 5 lines
Quoted 1 line

They should, if they imply a data transfer.

OK, good. We rely on that to mark input vs output sg elements. I was wondering if there was some weird requests which did both input and output.

There very soon will be bidirectional requests with both in and out elements, but they will be clearly marked as such (and the driver needs to be marked capable). So nothing to worry about for now.

Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

To be fair, I've left the complaint in that same patch, you're just reading it repeatedly 8)

That may be the case :-)

Quoted 3 lines

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

It surely sounds like a bug, if you issue ioctl(fd, CDROMEJECT), the driver sees it and returns -ENOTTY, but userland sees a 0 retval. So if you have time, please do poke at it a bit.

Signature · 1 line
Jens Axboe
#38 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Jens Axboe
Quoted 7 lines · Jens Axboe
Quoted 6 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

Quoted 6 lines
Quoted 4 lines

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

They should, if they imply a data transfer.

OK, good. We rely on that to mark input vs output sg elements. I was wondering if there was some weird requests which did both input and output.

Quoted 6 lines
Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

To be fair, I've left the complaint in that same patch, you're just reading it repeatedly 8)

I shall look through the code and see if I can figure out how to fix it. I'm assuming from your response that there's not some strange reason to preserve current behaviour.

Thanks!
Rusty.

#39 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to a message not in the archive
Quoted 6 lines · Rusty Russell
(quoted diff) +6 -0
+static void end_dequeued_request(struct request *req,
+				 struct request_queue *q, int uptodate)
+{
+	/* And so the insanity of the block layer infects us here. */
+	int nsectors = req->hard_nr_sectors;
+

Review

Quoted 10 lines
(quoted diff) +10 -0
+	if (blk_pc_request(req)) {
+		nsectors = (req->data_len + 511) >> 9;
+		if (!nsectors)
+			nsectors = 1;
+	}
+	if (end_that_request_first(req, uptodate, nsectors))
+		BUG();
+	add_disk_randomness(req->rq_disk);
+	end_that_request_last(req, uptodate);
+}

We have end_queued_request(), lets add end_dequeued_request(). Below.

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Review

Quoted 5 lines
(quoted diff) +5 -0
+		if (!do_req(q, vblk, req)) {
+			/* Queue full?  Wait. */
+			blk_stop_queue(q);
+			break;
+		}

Personally I think this bool stuff is foul. You return false/true, but still use ! to test. That is just more confusing than the canonical 0/1 good/bad return imho.

block/ll_rw_blk.c +31 -11
index f6d3994..c1dc23a 100644
@@ -3719,15 +3719,24 @@ void end_that_request_last(struct request *req, int uptodate)
 EXPORT_SYMBOL(end_that_request_last);
 
 static inline void __end_request(struct request *rq, int uptodate,
-				 unsigned int nr_bytes)
+				 unsigned int nr_bytes, int dequeue)
 {
 	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
-		blkdev_dequeue_request(rq);
+		if (dequeue)
+			blkdev_dequeue_request(rq);
 		add_disk_randomness(rq->rq_disk);
 		end_that_request_last(rq, uptodate);
 	}
 }
 
+static unsigned int rq_byte_size(struct request *rq)
+{
+	if (blk_fs_request(rq))
+		return rq->hard_nr_sectors << 9;
+
+	return rq->data_len;
+}
+
 /**
  * end_queued_request - end all I/O on a queued request
  * @rq:		the request being processed
@@ -3741,18 +3750,29 @@ static inline void __end_request(struct request *rq, int uptodate,
  **/
 void end_queued_request(struct request *rq, int uptodate)
 {
-	unsigned int nr_bytes;
-
-	if (blk_fs_request(rq))
-		nr_bytes = rq->hard_nr_sectors << 9;
-	else
-		nr_bytes = rq->data_len;
-
-	__end_request(rq, uptodate, nr_bytes);
+	__end_request(rq, uptodate, rq_byte_size(rq), 1);
 }
 EXPORT_SYMBOL(end_queued_request);
 
 /**
+ * end_dequeued_request - end all I/O on a dequeued request
+ * @rq:		the request being processed
+ * @uptodate:	error value or 0/1 uptodate flag
+ *
+ * Description:
+ *     Ends all I/O on a request. The request must already have been
+ *     dequeued using blkdev_dequeue_request(), as is normally the case
+ *     for most drivers.
+ *
+ **/
+void end_dequeued_request(struct request *rq, int uptodate)
+{
+	__end_request(rq, uptodate, rq_byte_size(rq), 0);
+}
+EXPORT_SYMBOL(end_dequeued_request);
+
+
+/**
  * end_request - end I/O on the current segment of the request
  * @rq:		the request being processed
  * @uptodate:	error value or 0/1 uptodate flag
@@ -3773,7 +3793,7 @@ EXPORT_SYMBOL(end_queued_request);
  **/
 void end_request(struct request *req, int uptodate)
 {
-	__end_request(req, uptodate, req->hard_cur_sectors << 9);
+	__end_request(req, uptodate, req->hard_cur_sectors << 9, 1);
 }
 EXPORT_SYMBOL(end_request);
 
include/linux/blkdev.h +1 -0
index 12ab4d4..4b24265 100644
@@ -732,6 +732,7 @@ extern int end_that_request_chunk(struct request *, int, int);
 extern void end_that_request_last(struct request *, int);
 extern void end_request(struct request *, int);
 extern void end_queued_request(struct request *, int);
+extern void end_dequeued_request(struct request *, int);
 extern void blk_complete_request(struct request *);
 
 /*
Signature · 7 lines
Jens Axboe


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#40 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 11 lines · Jens Axboe
Quoted 10 lines · Rusty Russell
(quoted diff) +10 -0
+static void end_dequeued_request(struct request *req,
+				 struct request_queue *q, int uptodate)
+{
+	/* And so the insanity of the block layer infects us here. */
+	int nsectors = req->hard_nr_sectors;
+
+	if (blk_pc_request(req)) {
+		nsectors = (req->data_len + 511) >> 9;
+		if (!nsectors)
+			nsectors = 1;
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+	}
+	if (end_that_request_first(req, uptodate, nsectors))
+		BUG();
+	add_disk_randomness(req->rq_disk);
+	end_that_request_last(req, uptodate);
+}

We have end_queued_request(), lets add end_dequeued_request(). Below.

OK, thanks, I'll throw that in the mix and test...

Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Hmm, potentially extremely large. What do I need to do for chained sglists?

Quoted 9 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+		if (!do_req(q, vblk, req)) {
+			/* Queue full?  Wait. */
+			blk_stop_queue(q);
+			break;
+		}

Personally I think this bool stuff is foul. You return false/true, but still use ! to test. That is just more confusing than the canonical 0/1 good/bad return imho.

Except "0/1" is not canonical in the kernel. Arguably, "-errno/0" is canonical. OTOH, bool is clear.

if do_req() fails, we assume the queue is full. I shall change the comment to that effect.

Thanks!
Rusty.

A message that is not in the archive (sent off-list or not yet received): 1190340367.19451.40.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#42 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 21 lines · Rusty Russell
Quoted 11 lines · Jens Axboe
Quoted 10 lines · Rusty Russell
(quoted diff) +10 -0
+static void end_dequeued_request(struct request *req,
+				 struct request_queue *q, int uptodate)
+{
+	/* And so the insanity of the block layer infects us here. */
+	int nsectors = req->hard_nr_sectors;
+
+	if (blk_pc_request(req)) {
+		nsectors = (req->data_len + 511) >> 9;
+		if (!nsectors)
+			nsectors = 1;
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+	}
+	if (end_that_request_first(req, uptodate, nsectors))
+		BUG();
+	add_disk_randomness(req->rq_disk);
+	end_that_request_last(req, uptodate);
+}

We have end_queued_request(), lets add end_dequeued_request(). Below.

Quoted 1 line

OK, thanks, I'll throw that in the mix and test...

I've queued it for 2.6.24 as well, so should be in mainline in that time frame.

Quoted 10 lines
Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Hmm, potentially extremely large. What do I need to do for chained sglists?

Not a lot, actually. You snipped the problematic part in your reply, though:

        vblk->sg[num+1].page = virt_to_page(&vbr->in_hdr);

which assumes that sg is a contigious piece of memory, for chained sg lists that isn't true. sg chaining will be in 2.6.24, so if you really do need large sglists, then that's the way to go.

blk_rq_map_sg() maps correctly for you, no changes needed there. But you want to use sg_last() for adding to the end of the sglist. And then use sg_next() to retrieve the next sg segment instead of sg + 1, and for_each_sg() to loop over all segments.

Just something to keep in mind, if you plan on merging this post 2.6.23.

Quoted 10 lines
Quoted 9 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+		if (!do_req(q, vblk, req)) {
+			/* Queue full?  Wait. */
+			blk_stop_queue(q);
+			break;
+		}

Personally I think this bool stuff is foul. You return false/true, but still use ! to test. That is just more confusing than the canonical 0/1 good/bad return imho.

Quoted 2 lines

Except "0/1" is not canonical in the kernel. Arguably, "-errno/0" is canonical. OTOH, bool is clear.

-errno/0, then. 1 is typically used for 'failure without specific error number' when -Exx doesn't apply. Like the above :-)

But lets just agree to disagree on the bool.

Quoted 2 lines

if do_req() fails, we assume the queue is full. I shall change the comment to that effect.

Thanks!

Signature · 7 lines
Jens Axboe


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 20070921114703.GN2367-tSWWG44O7X1aa/[email protected]

#44 lore raw

Re: [PATCH 4/6] virtio block driver

Quoted 8 lines · Jens Axboe
Quoted 4 lines · Rusty Russell
Quoted 1 line · Jens Axboe

We have end_queued_request(), lets add end_dequeued_request(). Below.

OK, thanks, I'll throw that in the mix and test...

I've queued it for 2.6.24 as well, so should be in mainline in that time frame.

OK, I'll sit it in my queue so my patches work until then.

Quoted 11 lines
Quoted 10 lines
Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Hmm, potentially extremely large. What do I need to do for chained sglists?

Quoted 8 lines

Not a lot, actually. You snipped the problematic part in your reply, though:

        vblk->sg[num+1].page = virt_to_page(&vbr->in_hdr);

which assumes that sg is a contigious piece of memory, for chained sg lists that isn't true. sg chaining will be in 2.6.24, so if you really do need large sglists, then that's the way to go.

I'm not sure if I need large sglists here. Obviously I want to handle anything the block layer can give to me (assume you're going to increase MAX_PHYS_SEGMENTS soon?). This might make "vblk" too big to kmalloc easily:

        struct virtio_blk
        {
        ...
        	/* Scatterlist: can be too big for stack. */
        	struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
        };

The sglist for virtio is really a scratch space to represent the request buffers (with one element for metadata at start and one at end) which we hand through to the virtio layer which turns it into its internal descriptors for the host to read.

Have you thought of putting an sglist inside the req itself? Then instead of blk_rq_map_sg() it'd just be req->sg? It could just be a chain of sg's in each bio I guess.

This would allow me to just to borrow that request sg chain, rather than doing the req -> sg -> virtio double-conversion.

Quoted 5 lines
Quoted 2 lines

Except "0/1" is not canonical in the kernel. Arguably, "-errno/0" is canonical. OTOH, bool is clear.

-errno/0, then. 1 is typically used for 'failure without specific error number' when -Exx doesn't apply. Like the above :-)

See, I'd be absolutely sure that >= 0 is success (like all syscalls), and I'd be appalled by code which used it as failure.

So I think you're right that we should agree to disagree :)

Thanks!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#45 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Jens Axboe
Quoted 8 lines · Jens Axboe
Quoted 4 lines · Rusty Russell
Quoted 1 line · Jens Axboe

We have end_queued_request(), lets add end_dequeued_request(). Below.

OK, thanks, I'll throw that in the mix and test...

I've queued it for 2.6.24 as well, so should be in mainline in that time frame.

OK, I'll sit it in my queue so my patches work until then.

Quoted 11 lines
Quoted 10 lines
Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Hmm, potentially extremely large. What do I need to do for chained sglists?

Quoted 8 lines

Not a lot, actually. You snipped the problematic part in your reply, though:

        vblk->sg[num+1].page = virt_to_page(&vbr->in_hdr);

which assumes that sg is a contigious piece of memory, for chained sg lists that isn't true. sg chaining will be in 2.6.24, so if you really do need large sglists, then that's the way to go.

I'm not sure if I need large sglists here. Obviously I want to handle anything the block layer can give to me (assume you're going to increase MAX_PHYS_SEGMENTS soon?). This might make "vblk" too big to kmalloc easily:

        struct virtio_blk
        {
        ...
        	/* Scatterlist: can be too big for stack. */
        	struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
        };

The sglist for virtio is really a scratch space to represent the request buffers (with one element for metadata at start and one at end) which we hand through to the virtio layer which turns it into its internal descriptors for the host to read.

Have you thought of putting an sglist inside the req itself? Then instead of blk_rq_map_sg() it'd just be req->sg? It could just be a chain of sg's in each bio I guess.

This would allow me to just to borrow that request sg chain, rather than doing the req -> sg -> virtio double-conversion.

Quoted 5 lines
Quoted 2 lines

Except "0/1" is not canonical in the kernel. Arguably, "-errno/0" is canonical. OTOH, bool is clear.

-errno/0, then. 1 is typically used for 'failure without specific error number' when -Exx doesn't apply. Like the above :-)

See, I'd be absolutely sure that >= 0 is success (like all syscalls), and I'd be appalled by code which used it as failure.

So I think you're right that we should agree to disagree :)

Thanks!
Rusty.

#46 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Rusty Russell
Quoted 21 lines · Rusty Russell
Quoted 11 lines · Jens Axboe
Quoted 10 lines · Rusty Russell
(quoted diff) +10 -0
+static void end_dequeued_request(struct request *req,
+				 struct request_queue *q, int uptodate)
+{
+	/* And so the insanity of the block layer infects us here. */
+	int nsectors = req->hard_nr_sectors;
+
+	if (blk_pc_request(req)) {
+		nsectors = (req->data_len + 511) >> 9;
+		if (!nsectors)
+			nsectors = 1;
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+	}
+	if (end_that_request_first(req, uptodate, nsectors))
+		BUG();
+	add_disk_randomness(req->rq_disk);
+	end_that_request_last(req, uptodate);
+}

We have end_queued_request(), lets add end_dequeued_request(). Below.

Quoted 1 line

OK, thanks, I'll throw that in the mix and test...

I've queued it for 2.6.24 as well, so should be in mainline in that time frame.

Quoted 10 lines
Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Hmm, potentially extremely large. What do I need to do for chained sglists?

Not a lot, actually. You snipped the problematic part in your reply, though:

        vblk->sg[num+1].page = virt_to_page(&vbr->in_hdr);

which assumes that sg is a contigious piece of memory, for chained sg lists that isn't true. sg chaining will be in 2.6.24, so if you really do need large sglists, then that's the way to go.

blk_rq_map_sg() maps correctly for you, no changes needed there. But you want to use sg_last() for adding to the end of the sglist. And then use sg_next() to retrieve the next sg segment instead of sg + 1, and for_each_sg() to loop over all segments.

Just something to keep in mind, if you plan on merging this post 2.6.23.

Quoted 10 lines
Quoted 9 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+		if (!do_req(q, vblk, req)) {
+			/* Queue full?  Wait. */
+			blk_stop_queue(q);
+			break;
+		}

Personally I think this bool stuff is foul. You return false/true, but still use ! to test. That is just more confusing than the canonical 0/1 good/bad return imho.

Quoted 2 lines

Except "0/1" is not canonical in the kernel. Arguably, "-errno/0" is canonical. OTOH, bool is clear.

-errno/0, then. 1 is typically used for 'failure without specific error number' when -Exx doesn't apply. Like the above :-)

But lets just agree to disagree on the bool.

Quoted 2 lines

if do_req() fails, we assume the queue is full. I shall change the comment to that effect.

Thanks!

Signature · 1 line
Jens Axboe
#47 lore raw

PATCH 5/6 virtio console driver

In reply to Rusty Russell

This is an hvc-based virtio console driver. It's suboptimal becuase hvc expects to have raw access to interrupts and virtio doesn't assume that, so it currently polls.

There are two solutions: expose hvc's "kick" interface, or wean off hvc.

---
 drivers/char/Kconfig           |    4 
 drivers/char/Makefile          |    1 
 drivers/char/virtio_console.c  |  232 ++++++++++++++++++++++++++++++++++++++++
 include/linux/virtio_console.h |   12 ++
 4 files changed, 249 insertions(+)

===================================================================

drivers/char/Kconfig +4 -0
@@ -613,6 +613,10 @@ config HVC_XEN
 	help
 	  Xen virtual console device driver
 
+config VIRTIO_CONSOLE
+	bool
+	select HVC_DRIVER
+
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES

===================================================================

drivers/char/Makefile +1 -0
@@ -50,6 +50,7 @@ obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
 obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
 obj-$(CONFIG_HVC_DRIVER)	+= hvc_console.o
 obj-$(CONFIG_HVC_XEN)		+= hvc_xen.o
+obj-$(CONFIG_VIRTIO_CONSOLE)	+= virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)		+= mspec.o

===================================================================

drivers/char/virtio_console.c new file +232 -0

232 lines not on this page · raw message

===================================================================

include/linux/virtio_console.h new file +12 -0
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_CONSOLE_H
+#define _LINUX_VIRTIO_CONSOLE_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_CONSOLE	3
+
+#ifdef __KERNEL__
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_VIRTIO_CONSOLE_H */
#48 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Rusty Russell
Quoted 10 lines · Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

They should, if they imply a data transfer.

Quoted 3 lines

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

How about ever submitting a patch for that, instead of just repeatedly complaining about it?

Signature · 1 line
Jens Axboe
#49 lore raw

Re: [PATCH 4/6] virtio block driver

In reply to Rusty Russell
Quoted 6 lines · Rusty Russell
(quoted diff) +6 -0
+static void end_dequeued_request(struct request *req,
+				 struct request_queue *q, int uptodate)
+{
+	/* And so the insanity of the block layer infects us here. */
+	int nsectors = req->hard_nr_sectors;
+

Review

Quoted 10 lines
(quoted diff) +10 -0
+	if (blk_pc_request(req)) {
+		nsectors = (req->data_len + 511) >> 9;
+		if (!nsectors)
+			nsectors = 1;
+	}
+	if (end_that_request_first(req, uptodate, nsectors))
+		BUG();
+	add_disk_randomness(req->rq_disk);
+	end_that_request_last(req, uptodate);
+}

We have end_queued_request(), lets add end_dequeued_request(). Below.

Review

Quoted 4 lines
(quoted diff) +4 -0
+	vblk->sg[0].page = virt_to_page(&vbr->out_hdr);
+	vblk->sg[0].offset = offset_in_page(&vbr->out_hdr);
+	vblk->sg[0].length = sizeof(vbr->out_hdr);
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);

This wont work for chained sglists, but I gather (I'm so funny) that it wont be an issue for you. How large are your sglists?

Review

Quoted 5 lines
(quoted diff) +5 -0
+		if (!do_req(q, vblk, req)) {
+			/* Queue full?  Wait. */
+			blk_stop_queue(q);
+			break;
+		}

Personally I think this bool stuff is foul. You return false/true, but still use ! to test. That is just more confusing than the canonical 0/1 good/bad return imho.

block/ll_rw_blk.c +31 -11
index f6d3994..c1dc23a 100644
@@ -3719,15 +3719,24 @@ void end_that_request_last(struct request *req, int uptodate)
 EXPORT_SYMBOL(end_that_request_last);
 
 static inline void __end_request(struct request *rq, int uptodate,
-				 unsigned int nr_bytes)
+				 unsigned int nr_bytes, int dequeue)
 {
 	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
-		blkdev_dequeue_request(rq);
+		if (dequeue)
+			blkdev_dequeue_request(rq);
 		add_disk_randomness(rq->rq_disk);
 		end_that_request_last(rq, uptodate);
 	}
 }
 
+static unsigned int rq_byte_size(struct request *rq)
+{
+	if (blk_fs_request(rq))
+		return rq->hard_nr_sectors << 9;
+
+	return rq->data_len;
+}
+
 /**
  * end_queued_request - end all I/O on a queued request
  * @rq:		the request being processed
@@ -3741,18 +3750,29 @@ static inline void __end_request(struct request *rq, int uptodate,
  **/
 void end_queued_request(struct request *rq, int uptodate)
 {
-	unsigned int nr_bytes;
-
-	if (blk_fs_request(rq))
-		nr_bytes = rq->hard_nr_sectors << 9;
-	else
-		nr_bytes = rq->data_len;
-
-	__end_request(rq, uptodate, nr_bytes);
+	__end_request(rq, uptodate, rq_byte_size(rq), 1);
 }
 EXPORT_SYMBOL(end_queued_request);
 
 /**
+ * end_dequeued_request - end all I/O on a dequeued request
+ * @rq:		the request being processed
+ * @uptodate:	error value or 0/1 uptodate flag
+ *
+ * Description:
+ *     Ends all I/O on a request. The request must already have been
+ *     dequeued using blkdev_dequeue_request(), as is normally the case
+ *     for most drivers.
+ *
+ **/
+void end_dequeued_request(struct request *rq, int uptodate)
+{
+	__end_request(rq, uptodate, rq_byte_size(rq), 0);
+}
+EXPORT_SYMBOL(end_dequeued_request);
+
+
+/**
  * end_request - end I/O on the current segment of the request
  * @rq:		the request being processed
  * @uptodate:	error value or 0/1 uptodate flag
@@ -3773,7 +3793,7 @@ EXPORT_SYMBOL(end_queued_request);
  **/
 void end_request(struct request *req, int uptodate)
 {
-	__end_request(req, uptodate, req->hard_cur_sectors << 9);
+	__end_request(req, uptodate, req->hard_cur_sectors << 9, 1);
 }
 EXPORT_SYMBOL(end_request);
 
include/linux/blkdev.h +1 -0
index 12ab4d4..4b24265 100644
@@ -732,6 +732,7 @@ extern int end_that_request_chunk(struct request *, int, int);
 extern void end_that_request_last(struct request *, int);
 extern void end_request(struct request *, int);
 extern void end_queued_request(struct request *, int);
+extern void end_dequeued_request(struct request *, int);
 extern void blk_complete_request(struct request *);
 
 /*
Signature · 1 line
Jens Axboe
#50 lore raw

Re: [PATCH 3/6] virtio net driver

In reply to a message not in the archive

Am Donnerstag, 20. September 2007 schrieb Rusty Russell:

Quoted 3 lines

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

[...]

Quoted 1 line

3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

Yes, that was me. I am quite busy at the moment but I will send a refreshed patch soon. The most annoying fact of my current patch is, that I have to add locking. (Because of the only one operation per virtqueue at a time rule)

[...]

drivers/net/virtio_net.c line 35

Quoted 6 lines
drivers/net/virtio_net.c new file +6 -0
+struct virtnet_info
+{
+	struct virtqueue_ops *vq_ops;
+	struct virtqueue *vq_recv;
+	struct virtqueue *vq_send;
+	struct net_device *ndev;

This is only a matter of taste, but I like netdev or dev more than ndev.

[...]

Everything else looks sane.

20-minutes-code-review-by: Christian Borntraeger <[email protected]>

Christian

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 200709211248.11783.borntraeger-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org

#52 lore raw

Re: [PATCH 3/6] virtio net driver

Quoted 10 lines · Christian Borntraeger

Am Donnerstag, 20. September 2007 schrieb Rusty Russell:

Quoted 3 lines

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

[...]

Quoted 1 line

3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

Yes, that was me. I am quite busy at the moment but I will send a refreshed patch soon. The most annoying fact of my current patch is, that I have to add locking. (Because of the only one operation per virtqueue at a time rule)

Sorry Christian, I thought it was you but was in a hurry to send out the patches so didn't go back and check.

Can't we just re-use the default xmit lock?

Quoted 9 lines

[...]

drivers/net/virtio_net.c line 35

Quoted 6 lines
drivers/net/virtio_net.c new file +6 -0
+struct virtnet_info
+{
+	struct virtqueue_ops *vq_ops;
+	struct virtqueue *vq_recv;
+	struct virtqueue *vq_send;
+	struct net_device *ndev;

This is only a matter of taste, but I like netdev or dev more than ndev.

Yeah, I agreed. It was a moment of weakness: I've renamed it to "dev".

Thanks!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190375615.27805.9.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#54 lore raw

Re: [PATCH 3/6] virtio net driver

Am Freitag, 21. September 2007 schrieb Rusty Russell:

Quoted 1 line

Can't we just re-use the default xmit lock?

yes we can.

This patch is untested but is basically an refresh of an ealier version. I currently have no code testable with the latest virtio version from this mail thread, so if you could apply this (It still has the ndev name) and test the patch? Thanks

Christian
---

Use the sent interrupt for xmit reclaim.

---
 drivers/net/virtio_net.c |   43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)
drivers/net/virtio_net.c +26 -17
Index: virtio/drivers/net/virtio_net.c
===================================================================
@@ -52,10 +52,29 @@ static inline void vnet_hdr_to_sg(struct
 	sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
 }
 
+static void free_old_xmit_skbs(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct sk_buff *skb;
+	unsigned int len;
+
+	netif_tx_lock(dev);
+	while ((skb = vi->vq_ops->get_buf(vi->vq_send, &len)) != NULL) {
+		pr_debug("Sent skb %p\n", skb);
+		__skb_unlink(skb, &vi->send);
+		dev->stats.tx_bytes += len;
+		dev->stats.tx_packets++;
+		dev_kfree_skb_irq(skb);
+	}
+	netif_tx_unlock(dev);
+}
+
 static bool skb_xmit_done(void *ndev)
 {
 	/* In case we were waiting for output buffers. */
 	netif_wake_queue(ndev);
+	/* reclaim sent skbs */
+	fre_old_xmit_skbs(ndev);
 	return true;
 }
 
@@ -209,20 +228,6 @@ again:
 	return 0;
 }
 
-static void free_old_xmit_skbs(struct virtnet_info *vi)
-{
-	struct sk_buff *skb;
-	unsigned int len;
-
-	while ((skb = vi->vq_ops->get_buf(vi->vq_send, &len)) != NULL) {
-		pr_debug("Sent skb %p\n", skb);
-		__skb_unlink(skb, &vi->send);
-		vi->ndev->stats.tx_bytes += len;
-		vi->ndev->stats.tx_packets++;
-		kfree_skb(skb);
-	}
-}
-
 static int start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
@@ -235,8 +240,6 @@ static int start_xmit(struct sk_buff *sk
 		 dev->name, skb,
 		 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]);
 
-	free_old_xmit_skbs(vi);
-
 	/* Encode metadata header at front. */
 	hdr = skb_vnet_hdr(skb);
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -267,15 +270,21 @@ static int start_xmit(struct sk_buff *sk
 
 	vnet_hdr_to_sg(sg, skb);
 	num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+	local_irq_disable();
+	netif_tx_lock(dev);
 	__skb_queue_head(&vi->send, skb);
 	err = vi->vq_ops->add_buf(vi->vq_send, sg, num, 0, skb);
 	if (err) {
 		pr_debug("%s: virtio not prepared to send\n", dev->name);
 		skb_unlink(skb, &vi->send);
 		netif_stop_queue(dev);
+		netif_tx_unlock(dev);
+		local_irq_enable();
 		return NETDEV_TX_BUSY;
 	}
 	vi->vq_ops->kick(vi->vq_send);
+	netif_tx_unlock(dev);
+	local_irq_enable();
 
 	return 0;
 }
@@ -335,7 +344,7 @@ static void *virtnet_probe(struct device
 	dev->poll = virtnet_poll;
 	dev->hard_start_xmit = start_xmit;
 	dev->weight = 16;
-	dev->features = NETIF_F_HIGHDMA;
+	dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
 	SET_NETDEV_DEV(dev, device);
 
 	/* Do we support "hardware" checksums? */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 200709211436.43964.borntraeger-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org

#56 lore raw

Re: [PATCH 3/6] virtio net driver

drivers/net/virtio_net.c static void *virtnet_probe(struct device · line 350

Quoted 10 lines · Christian Borntraeger
drivers/net/virtio_net.c +1 -1
@@ -335,7 +344,7 @@ static void *virtnet_probe(struct device
 	dev->poll = virtnet_poll;
 	dev->hard_start_xmit = start_xmit;
 	dev->weight = 16;
-	dev->features = NETIF_F_HIGHDMA;
+	dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
 	SET_NETDEV_DEV(dev, device);
 
 	/* Do we support "hardware" checksums? */

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Thanks,

Signature · 9 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 20070921140833.GA12242-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org

#58 lore raw

Re: [PATCH 3/6] virtio net driver

Am Freitag, 21. September 2007 schrieb Herbert Xu:

Quoted 5 lines

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Ok, but then I cannot reuse the xmit lock in an interrupt handler. Otherwise deadlock can occur because hard_start_xmit has interrupts enabled.

Rusty, seems we need an additional lock.

Christian

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 200709211642.25208.borntraeger-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org

#60 lore raw

Re: [PATCH 3/6] virtio net driver

Quoted 11 lines · Christian Borntraeger

Am Freitag, 21. September 2007 schrieb Herbert Xu:

Quoted 5 lines

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Ok, but then I cannot reuse the xmit lock in an interrupt handler. Otherwise deadlock can occur because hard_start_xmit has interrupts enabled.

Rusty, seems we need an additional lock.

Can we use a tasklet? Seems like it'd be safe at a glance...

Thanks,
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#61 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Christian Borntraeger
Quoted 11 lines · Christian Borntraeger

Am Freitag, 21. September 2007 schrieb Herbert Xu:

Quoted 5 lines

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Ok, but then I cannot reuse the xmit lock in an interrupt handler. Otherwise deadlock can occur because hard_start_xmit has interrupts enabled.

Rusty, seems we need an additional lock.

Can we use a tasklet? Seems like it'd be safe at a glance...

Thanks,
Rusty.

#62 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Herbert Xu

Am Freitag, 21. September 2007 schrieb Herbert Xu:

Quoted 5 lines

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Ok, but then I cannot reuse the xmit lock in an interrupt handler. Otherwise deadlock can occur because hard_start_xmit has interrupts enabled.

Rusty, seems we need an additional lock.

Christian

#63 lore raw

PATCH 1/1 note that NETIF_F_LLTX is deprecated (was: [kvm-devel][PATCH 3/6] virtio net driver)

In reply to Herbert Xu

Am Freitag, 21. September 2007 schrieb Herbert Xu:

Quoted 5 lines

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

I suggest to document that LLTX is deprecated.

---
 Documentation/networking/netdevices.txt |    3 ++-
 include/linux/netdevice.h               |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
include/linux/netdevice.h +2 -1
Index: linux-2.6/include/linux/netdevice.h
===================================================================
@@ -339,7 +339,8 @@ struct net_device
 #define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
 #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
 #define NETIF_F_GSO		2048	/* Enable software GSO. */
-#define NETIF_F_LLTX		4096	/* LockLess TX */
+#define NETIF_F_LLTX		4096	/* LockLess TX - deprecated. Please */
+					/* do not use LLTX in new drivers */
 #define NETIF_F_MULTI_QUEUE	16384	/* Has multiple TX/RX queues */
 
 	/* Segmentation offload features */
Documentation/networking/netdevices.txt +2 -1
Index: linux-2.6/Documentation/networking/netdevices.txt
===================================================================
@@ -73,7 +73,8 @@ dev->hard_start_xmit:
 	has to lock by itself when needed. It is recommended to use a try lock
 	for this and return NETDEV_TX_LOCKED when the spin lock fails.
 	The locking there should also properly protect against 
-	set_multicast_list.
+	set_multicast_list. Note that the use of NETIF_F_LLTX is deprecated.
+	Dont use it for new drivers.
 
 	Context: Process with BHs disabled or BH (timer),
 	         will be called with interrupts disabled by netconsole.
#64 lore raw

Re: [PATCH] note that NETIF_F_LLTX is deprecated (was: [kvm-devel][PATCH 3/6] virtio net driver)

Quoted 4 lines · Christian Borntraeger

I suggest to document that LLTX is deprecated.

This looks good to me.

Thanks,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#66 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Christian Borntraeger

drivers/net/virtio_net.c static void *virtnet_probe(struct device · line 350

Quoted 10 lines · Christian Borntraeger
drivers/net/virtio_net.c +1 -1
@@ -335,7 +344,7 @@ static void *virtnet_probe(struct device
 	dev->poll = virtnet_poll;
 	dev->hard_start_xmit = start_xmit;
 	dev->weight = 16;
-	dev->features = NETIF_F_HIGHDMA;
+	dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
 	SET_NETDEV_DEV(dev, device);
 
 	/* Do we support "hardware" checksums? */

Please don't use LLTX in new drivers. We're trying to get rid of it since it's

1) unnecessary;
2) causes problems with AF_PACKET seeing things twice.

Thanks,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#67 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Rusty Russell

Am Freitag, 21. September 2007 schrieb Rusty Russell:

Quoted 1 line

Can't we just re-use the default xmit lock?

yes we can.

This patch is untested but is basically an refresh of an ealier version. I currently have no code testable with the latest virtio version from this mail thread, so if you could apply this (It still has the ndev name) and test the patch? Thanks

Christian
---

Use the sent interrupt for xmit reclaim.

---
 drivers/net/virtio_net.c |   43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)
drivers/net/virtio_net.c +26 -17
Index: virtio/drivers/net/virtio_net.c
===================================================================
@@ -52,10 +52,29 @@ static inline void vnet_hdr_to_sg(struct
 	sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
 }
 
+static void free_old_xmit_skbs(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct sk_buff *skb;
+	unsigned int len;
+
+	netif_tx_lock(dev);
+	while ((skb = vi->vq_ops->get_buf(vi->vq_send, &len)) != NULL) {
+		pr_debug("Sent skb %p\n", skb);
+		__skb_unlink(skb, &vi->send);
+		dev->stats.tx_bytes += len;
+		dev->stats.tx_packets++;
+		dev_kfree_skb_irq(skb);
+	}
+	netif_tx_unlock(dev);
+}
+
 static bool skb_xmit_done(void *ndev)
 {
 	/* In case we were waiting for output buffers. */
 	netif_wake_queue(ndev);
+	/* reclaim sent skbs */
+	fre_old_xmit_skbs(ndev);
 	return true;
 }
 
@@ -209,20 +228,6 @@ again:
 	return 0;
 }
 
-static void free_old_xmit_skbs(struct virtnet_info *vi)
-{
-	struct sk_buff *skb;
-	unsigned int len;
-
-	while ((skb = vi->vq_ops->get_buf(vi->vq_send, &len)) != NULL) {
-		pr_debug("Sent skb %p\n", skb);
-		__skb_unlink(skb, &vi->send);
-		vi->ndev->stats.tx_bytes += len;
-		vi->ndev->stats.tx_packets++;
-		kfree_skb(skb);
-	}
-}
-
 static int start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
@@ -235,8 +240,6 @@ static int start_xmit(struct sk_buff *sk
 		 dev->name, skb,
 		 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]);
 
-	free_old_xmit_skbs(vi);
-
 	/* Encode metadata header at front. */
 	hdr = skb_vnet_hdr(skb);
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -267,15 +270,21 @@ static int start_xmit(struct sk_buff *sk
 
 	vnet_hdr_to_sg(sg, skb);
 	num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+	local_irq_disable();
+	netif_tx_lock(dev);
 	__skb_queue_head(&vi->send, skb);
 	err = vi->vq_ops->add_buf(vi->vq_send, sg, num, 0, skb);
 	if (err) {
 		pr_debug("%s: virtio not prepared to send\n", dev->name);
 		skb_unlink(skb, &vi->send);
 		netif_stop_queue(dev);
+		netif_tx_unlock(dev);
+		local_irq_enable();
 		return NETDEV_TX_BUSY;
 	}
 	vi->vq_ops->kick(vi->vq_send);
+	netif_tx_unlock(dev);
+	local_irq_enable();
 
 	return 0;
 }
@@ -335,7 +344,7 @@ static void *virtnet_probe(struct device
 	dev->poll = virtnet_poll;
 	dev->hard_start_xmit = start_xmit;
 	dev->weight = 16;
-	dev->features = NETIF_F_HIGHDMA;
+	dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
 	SET_NETDEV_DEV(dev, device);
 
 	/* Do we support "hardware" checksums? */
#68 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Christian Borntraeger
Quoted 10 lines · Christian Borntraeger

Am Donnerstag, 20. September 2007 schrieb Rusty Russell:

Quoted 3 lines

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

[...]

Quoted 1 line

3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

Yes, that was me. I am quite busy at the moment but I will send a refreshed patch soon. The most annoying fact of my current patch is, that I have to add locking. (Because of the only one operation per virtqueue at a time rule)

Sorry Christian, I thought it was you but was in a hurry to send out the patches so didn't go back and check.

Can't we just re-use the default xmit lock?

Quoted 9 lines

[...]

drivers/net/virtio_net.c line 35

Quoted 6 lines
drivers/net/virtio_net.c new file +6 -0
+struct virtnet_info
+{
+	struct virtqueue_ops *vq_ops;
+	struct virtqueue *vq_recv;
+	struct virtqueue *vq_send;
+	struct net_device *ndev;

This is only a matter of taste, but I like netdev or dev more than ndev.

Yeah, I agreed. It was a moment of weakness: I've renamed it to "dev".

Thanks!
Rusty.

#69 lore raw

PATCH 4/6 virtio block driver

In reply to Rusty Russell

The block driver uses scatter-gather lists with sg[0] being the request information (struct virtio_blk_outhdr) with the type, sector and inbuf id. The next N sg entries are the bio itself, then the last sg is the status byte. Whether the N entries are in or out depends on whether it's a read or a write.

We accept the normal (SCSI) ioctls: they get handed through to the other side which can then handle it or reply that it's unsupported. It's not clear that this actually works in general, since I don't know if blk_pc_request() requests have an accurate rq_data_dir().

Although we try to reply -ENOTTY on unsupported commands, the block layer in its infinite wisdom suppressed the error so ioctl(fd, CDROMEJECT) returns success to userspace.

---
 drivers/block/Kconfig      |    6 
 drivers/block/Makefile     |    1 
 drivers/block/virtio_blk.c |  327 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/Kbuild       |    1 
 include/linux/virtio_blk.h |   51 ++++++
 5 files changed, 386 insertions(+)

===================================================================

drivers/block/Kconfig +6 -0
@@ -443,4 +443,10 @@ config XEN_BLKDEV_FRONTEND
 	  block device driver.  It communicates with a back-end driver
 	  in another domain which drives the actual block device.
 
+config VIRTIO_BLK
+	tristate "Virtio block driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual block driver for lguest.  Say Y or M.
+
 endif # BLK_DEV

===================================================================

drivers/block/Makefile +1 -0
@@ -25,6 +25,7 @@ obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
+obj-$(CONFIG_VIRTIO_BLK)	+= virtio_blk.o
 
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o

===================================================================

drivers/block/virtio_blk.c new file +327 -0

327 lines not on this page · raw message

===================================================================

include/linux/Kbuild +1 -0
@@ -343,6 +343,7 @@ unifdef-y += utsname.h
 unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
+unifdef-y += virtio_blk.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h

===================================================================

include/linux/virtio_blk.h new file +51 -0

51 lines not on this page · raw message

#70 lore raw

Re: [kvm-devel] [PATCH 3/6] virtio net driver

In reply to Rusty Russell

Am Donnerstag, 20. September 2007 schrieb Rusty Russell:

Quoted 3 lines

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

[...]

Quoted 1 line

3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

Yes, that was me. I am quite busy at the moment but I will send a refreshed patch soon. The most annoying fact of my current patch is, that I have to add locking. (Because of the only one operation per virtqueue at a time rule)

[...]

drivers/net/virtio_net.c line 35

Quoted 6 lines
drivers/net/virtio_net.c new file +6 -0
+struct virtnet_info
+{
+	struct virtqueue_ops *vq_ops;
+	struct virtqueue *vq_recv;
+	struct virtqueue *vq_send;
+	struct net_device *ndev;

This is only a matter of taste, but I like netdev or dev more than ndev.

[...]

Everything else looks sane.

20-minutes-code-review-by: Christian Borntraeger <[email protected]>

Christian

#71 lore raw

Re: [PATCH 2/6] virtio_config

In reply to a message not in the archive
Quoted 16 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

Quoted 4 lines

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Lovely.

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 46F26958.4080102-atKUWr5tajBWk0Htik3J/[email protected]

#73 lore raw

Re: [PATCH 2/6] virtio_config

Quoted 17 lines · Avi Kivity
Quoted 16 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

Quoted 7 lines
Quoted 4 lines

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Lovely.

A side effect of this is that Xen drivers can no longer use virtio.

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 46F26DC7.9040001-atKUWr5tajBWk0Htik3J/[email protected]

#75 lore raw

Re: [PATCH 2/6] virtio_config

Quoted 23 lines · Avi Kivity
Quoted 22 lines · Avi Kivity
Quoted 20 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Quoted 4 lines
Quoted 2 lines

Lovely.

A side effect of this is that Xen drivers can no longer use virtio.

I'm not so sure.

We were always assuming that Xen could do state management in its virtio layer. If this is not true, it implies we need hooks in the virtio drivers, and I don't think we've made it worse by making it translate xenbus config info into virtio_config.

Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190339435.19451.23.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#77 lore raw

Re: [PATCH 2/6] virtio_config

Quoted 11 lines · Rusty Russell
Quoted 3 lines

A side effect of this is that Xen drivers can no longer use virtio.

I'm not so sure.

We were always assuming that Xen could do state management in its virtio layer. If this is not true, it implies we need hooks in the virtio drivers, and I don't think we've made it worse by making it translate xenbus config info into virtio_config.

This means writing a low-level ABI in terms of a high level API. And while that describes virtualization fairly will, I prefer not to do this more than strictly necessary.

However, this can be rewritten if/when Xen or VMware show interest in porting their drivers to virtio.

Signature · 7 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#78 lore raw

Re: [kvm-devel] [PATCH 2/6] virtio_config

In reply to Rusty Russell
Quoted 11 lines · Rusty Russell
Quoted 3 lines

A side effect of this is that Xen drivers can no longer use virtio.

I'm not so sure.

We were always assuming that Xen could do state management in its virtio layer. If this is not true, it implies we need hooks in the virtio drivers, and I don't think we've made it worse by making it translate xenbus config info into virtio_config.

This means writing a low-level ABI in terms of a high level API. And while that describes virtualization fairly will, I prefer not to do this more than strictly necessary.

However, this can be rewritten if/when Xen or VMware show interest in porting their drivers to virtio.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#79 lore raw

Re: [kvm-devel] [PATCH 2/6] virtio_config

In reply to Avi Kivity
Quoted 23 lines · Avi Kivity
Quoted 22 lines · Avi Kivity
Quoted 20 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Quoted 4 lines
Quoted 2 lines

Lovely.

A side effect of this is that Xen drivers can no longer use virtio.

I'm not so sure.

We were always assuming that Xen could do state management in its virtio layer. If this is not true, it implies we need hooks in the virtio drivers, and I don't think we've made it worse by making it translate xenbus config info into virtio_config.

Rusty.

#80 lore raw

Re: [kvm-devel] [PATCH 2/6] virtio_config

In reply to Avi Kivity
Quoted 17 lines · Avi Kivity
Quoted 16 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

Quoted 7 lines
Quoted 4 lines

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Lovely.

A side effect of this is that Xen drivers can no longer use virtio.

Signature · 1 line
error compiling committee.c: too many arguments to function
#81 lore raw

PATCH 3/6 virtio net driver

In reply to Rusty Russell

The network driver uses *two* virtqueues: one for input packets and one for output packets. This has nice locking properties (ie. we don't do any for recv vs send).

TODO:
1) Big packets.
2) Multi-client devices (maybe separate driver?).
3) Resolve freeing of old xmit skbs (someone sent patch IIRC?)

---
 drivers/net/Kconfig        |    6 
 drivers/net/Makefile       |    2 
 drivers/net/virtio_net.c   |  438 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/virtio_net.h |   36 +++
 4 files changed, 481 insertions(+), 1 deletion(-)

===================================================================

drivers/net/Kconfig +6 -0
@@ -2998,4 +2998,10 @@ config NET_POLL_CONTROLLER
 config NET_POLL_CONTROLLER
 	def_bool NETPOLL
 
+config VIRTIO_NET
+	tristate "Virtio network driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual network driver for lguest.  Say Y or M.
+
 endif # NETDEVICES

===================================================================

drivers/net/Makefile +1 -1
@@ -38,7 +38,7 @@ obj-$(CONFIG_SUNVNET) += sunvnet.o
 
 obj-$(CONFIG_MACE) += mace.o
 obj-$(CONFIG_BMAC) += bmac.o
-
+obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_DGRS) += dgrs.o
 obj-$(CONFIG_VORTEX) += 3c59x.o
 obj-$(CONFIG_TYPHOON) += typhoon.o

===================================================================

drivers/net/virtio_net.c new file +438 -0

438 lines not on this page · raw message

===================================================================

include/linux/virtio_net.h new file +36 -0
@@ -0,0 +1,36 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_net */
+#define VIRTIO_ID_NET	1
+
+/* The bitmap of config for virtio net */
+#define VIRTIO_CONFIG_NET_F	0x40
+#define VIRTIO_NET_F_NO_CSUM	1
+#define VIRTIO_NET_F_TSO4	2
+#define VIRTIO_NET_F_UFO	4
+#define VIRTIO_NET_F_TSO4_ECN	8
+#define VIRTIO_NET_F_TSO6	16
+
+/* The config defining mac address. */
+#define VIRTIO_CONFIG_NET_MAC_F	0x41
+
+/* This is the first element of the scatter-gather list.  If you don't
+ * specify GSO or CSUM features, you can simply ignore the header. */
+struct virtio_net_hdr
+{
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM	1	// Use csum_start, csum_offset
+      __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE		0	// Not a GSO frame
+#define VIRTIO_NET_HDR_GSO_TCPV4	1	// GSO frame, IPv4 TCP (TSO)
+/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
+#define VIRTIO_NET_HDR_GSO_TCPV4_ECN	2	// GSO frame, IPv4 TCP w/ ECN
+#define VIRTIO_NET_HDR_GSO_UDP		3	// GSO frame, IPv4 UDP (UFO)
+#define VIRTIO_NET_HDR_GSO_TCPV6	4	// GSO frame, IPv6 TCP
+      __u8 gso_type;
+      __u16 gso_size;
+      __u16 csum_start;
+      __u16 csum_offset;
+};
+#endif /* _LINUX_VIRTIO_NET_H */
#82 lore raw

Re: [kvm-devel] [PATCH 2/6] virtio_config

In reply to Rusty Russell
Quoted 16 lines · Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

Quoted 4 lines

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

Lovely.

Signature · 1 line
error compiling committee.c: too many arguments to function
#83 lore raw

Re: [PATCH 1/6] virtio interace

In reply to a message not in the archive
Quoted 21 lines · Rusty Russell

(Changes:
- renamed sync to kick as Dor suggested
- added new_vq and free_vq hooks to create virtqueues
- define a simple virtio driver, which uses PCI ids
- provide register/unregister_virtio_driver hooks)

This attempts to implement a "virtual I/O" layer which should allow common drivers to be efficiently used across most virtual I/O mechanisms. It will no-doubt need further enhancement.

The virtio drivers add and get I/O buffers; as the buffers are consumed the driver "interrupt" callbacks are invoked.

It also provides driver register and unregister hooks, which are simply overridden at run time (eg. for a guest kernel which supports KVM paravirt and lguest).

+++ b/drivers/virtio/virtio.c

drivers/virtio/virtio.c line 4

Quoted 4 lines
drivers/virtio/virtio.c new file +4 -0
@@ -0,0 +1,20 @@
+#include <linux/virtio.h>
+
+struct virtio_backend_ops virtio_backend_ops;
+EXPORT_SYMBOL_GPL(virtio_backend_ops);

Suggest calling this virtio_transport_ops rather than the too-generic virtio_backend_ops. Especially since Xen uses backend for something completely different.

include/linux/virtio.h line 18

Quoted 8 lines
include/linux/virtio.h new file +7 -0
+
+/**
+ * virtqueue_ops - operations for virtqueue abstraction layer
+ * @new_vq: create a new virtqueue
+ *	config: the virtio_config_space field describing the queue
+ *	off: the offset in the config space of the queue configuration
+ *	len: the length of the virtio_config_space field

'off, len' are really a magic cookie. Why does the interface care about their meaning?

include/linux/virtio.h line 19

Quoted 2 lines
include/linux/virtio.h new file +1 -0
+ *	callback: the driver callback when the queue is used.

Missing callback return value description.

include/linux/virtio.h line 33

Quoted 4 lines
include/linux/virtio.h new file +3 -0
+ * @kick: update after add_buf
+ *	vq: the struct virtqueue
+ *	After one or more add_buf calls, invoke this to kick the virtio layer.

'the other side'

I'm not thrilled about reusing pci ids. Maybe the s390 can say whether this is a real issue.

Signature · 7 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#84 lore raw

Re: [kvm-devel] [PATCH 1/6] virtio interace

Quoted 7 lines · Avi Kivity

drivers/virtio/virtio.c line 4

Quoted 2 lines · Rusty Russell
drivers/virtio/virtio.c new file +2 -0
+struct virtio_backend_ops virtio_backend_ops;
+EXPORT_SYMBOL_GPL(virtio_backend_ops);

Suggest calling this virtio_transport_ops rather than the too-generic virtio_backend_ops. Especially since Xen uses backend for something completely different.

Hi Avi,

Agreed, fixed. I actually don't like this interface at all, but it is simple until we determine something better.

Quoted 10 lines
Quoted 7 lines

+/**
+ * virtqueue_ops - operations for virtqueue abstraction layer
+ * @new_vq: create a new virtqueue
+ * config: the virtio_config_space field describing the queue
+ * off: the offset in the config space of the queue configuration
+ * len: the length of the virtio_config_space field

'off, len' are really a magic cookie. Why does the interface care about their meaning?

off is a cookie, len isn't. The driver does "get me the foo field" and it returns off + len. If it wants to read or write the foo field it needs that length.

In practice, drivers use the virtio_config_vq() convenience interface which does "find field, hand to ops->new_vq".

Quoted 4 lines
Quoted 2 lines

+ * callback: the driver callback when the queue is used.

Missing callback return value description.

Indeed, that's always made me uncomfortable. Fixed. Although it's possible that an explicit disable hook is better...

Quoted 6 lines
Quoted 4 lines

+ * @kick: update after add_buf
+ * vq: the struct virtqueue
+ * After one or more add_buf calls, invoke this to kick the virtio layer.

'the other side'

Thanks, fixed.

Quoted 2 lines

I'm not thrilled about reusing pci ids. Maybe the s390 can say whether this is a real issue.

I doubt it: it's not a problem for lguest. But I wonder if I've chosen the right fields...

Rusty.

#85 lore raw

Re: [PATCH 1/6] virtio interace

In reply to a message not in the archive
Quoted 17 lines · Rusty Russell

+ * virtio_driver - operations for a virtio I/O driver
+ * @name: the name of the driver (KBUILD_MODNAME).
+ * @owner: the module which contains these routines (ie. THIS_MODULE).
+ * @id_table: the ids (we re-use PCI ids) serviced by this driver.
+ * @probe: the function to call when a device is found.  Returns a token for
+ *    remove, or PTR_ERR().
+ * @remove: the function when a device is removed.
+ */

include/linux/virtio.h new file +9 -0
+struct virtio_driver {
+       const char *name;
+       struct module *owner;
+       struct pci_device_id *id_table;
+       void *(*probe)(struct device *device,
+                      struct virtio_config_space *config,
+                      struct virtqueue_ops *vqops);
+       void (*remove)(void *dev);
+};

include/linux/virtio.h line 113

Quoted 10 lines
include/linux/virtio.h new file +10 -0
+
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+
+/* The particular virtio backend supplies these. */
+struct virtio_backend_ops {
+       int (*register_driver)(struct virtio_driver *drv);
+       void (*unregister_driver)(struct virtio_driver *drv);
+};
+extern struct virtio_backend_ops virtio_backend_ops;

This still seems a little awkward. From what I understand, you register a virtio_driver, which leads to a pci_driver (or whatever you are based on) to be registered behind the covers, so that the pci_device can be used directly as the virtio device.

I think there should instead be a pci_driver that automatically binds to all PCI based virtio imlpementations and creates a child device for the actual virtio_device. Then you can have the virtio_driver itself be based on a device_driver, and you can get rid of the global virtio_backend_ops. That will be useful when a virtual machine has two ways to get at the virtio devices, e.g. a KVM guest that has both hcall based probing for virtio devices and some other virtio devices that are exported through PCI.

	Arnd <><

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#87 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 15 lines · Arnd Bergmann

include/linux/virtio.h line 113

Quoted 9 lines · Rusty Russell
include/linux/virtio.h new file +9 -0
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+
+/* The particular virtio backend supplies these. */
+struct virtio_backend_ops {
+       int (*register_driver)(struct virtio_driver *drv);
+       void (*unregister_driver)(struct virtio_driver *drv);
+};
+extern struct virtio_backend_ops virtio_backend_ops;

This still seems a little awkward. From what I understand, you register a virtio_driver, which leads to a pci_driver (or whatever you are based on) to be registered behind the covers, so that the pci_device can be used directly as the virtio device.

Hi Arnd,

Yes, and I dislike it too.

Quoted 3 lines

I think there should instead be a pci_driver that automatically binds to all PCI based virtio imlpementations and creates a child device for the actual virtio_device.

I'm not sure I understand. For PCI probing to work, you want to have identified yourself as a driver for each PCI id claimed by a virtio device.

Hmm, I guess we could have a PCI driver which claims all VIRTIO vendor devices. Then it can call virtio_find_driver() (?) at the top of its probe function to find if there's a matching virtio driver. This PCI driver would have to be initialized after all the virtio drivers are registered, but that's easy.

The virtio layer would simply maintain a linked list of drivers and implement the virtio_find_driver() matching function.

And since we've suppressed normal PCI driver request_module (since it always finds "the driver") then we can implement that in virtio_find_driver(), and not use a PCI MODULE_DEVICE_TABLE. Then we don't need (full) PCI ids at all.

OK, I have some coding to do now...
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190378736.27805.54.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#89 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 2 lines · Rusty Russell

Hmm, I guess we could have a PCI driver which claims all VIRTIO vendor devices.

yes, that was the idea.

Quoted 4 lines

Then it can call virtio_find_driver() (?) at the top of its probe function to find if there's a matching virtio driver. This PCI driver would have to be initialized after all the virtio drivers are registered, but that's easy.

No, just use the driver model, instead of working against it:

struct pci_virtio_device {
	struct pci_dev *pdev;
	char __iomem *mmio_space;
	struct virtio_device vdev;
};

static int __devinit pci_virtio_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)

{
	struct pci_virtio_device *dev = kzalloc(sizeof (*dev), GFP_KERNEL);
	dev->pdev = pdev;
	dev->mmio_space = pcim_iomap(pdev, 0, PCI_VIRTIO_BUFSIZE);
	dev->vdev->ops = &pci_virtqueue_ops;
	dev->vdev->config = &pci_virtio_config_ops;
	dev->vdev->type = ent->device;
	dev->vdev->class = ent->class;
	dev->vdev.dev.parent = &pdev->dev;

	return virtio_device_register(&dev->vdev;
}
Quoted 2 lines

The virtio layer would simply maintain a linked list of drivers and implement the virtio_find_driver() matching function.

nonono, just a virtio_bus that all virtio drivers register to:

static int virtio_net_probe(struct device *dev)

{
	struct virtio_device *vdev = to_virtio_dev(dev);
	struct virtqueue_ops *vq_ops = vdev->ops;

	/* same as current code */
	...

	return 0;
}
static struct virtio_device_id virtio_net_ids[] = {
	{ .type = VIRTIO_ID_NET, .class = PCI_CLASS_NETWORK_OTHER },
	{ },
};

static struct virtio_driver virtio_net = {
.id_table = &virtio_net_ids,
.driver = {
.name = "virtionet",
.probe = virtio_net_probe,
.remove = virtionet_remove,
.bus = &virtio_bus, /* <- look here */
},
};

static int __init virtio_net_init(void)

{
	return driver_register(&virtio_net.driver);
}

module_init(virtio_net_init);

Quoted 4 lines

And since we've suppressed normal PCI driver request_module (since it always finds "the driver") then we can implement that in virtio_find_driver(), and not use a PCI MODULE_DEVICE_TABLE.  Then we don't need (full) PCI ids at all.

right, as shown in my example above.

	Arnd <><

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#90 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 4 lines · Arnd Bergmann
Quoted 2 lines · Rusty Russell

Hmm, I guess we could have a PCI driver which claims all VIRTIO vendor devices.

Quoted 8 lines

yes, that was the idea.

Quoted 4 lines

Then it can call virtio_find_driver() (?) at the top of its probe function to find if there's a matching virtio driver. This PCI driver would have to be initialized after all the virtio drivers are registered, but that's easy.

No, just use the driver model, instead of working against it:

But now each virtio device has two "struct device"s, not one. And
you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it. But it's still wrong.

Rusty.

A message that is not in the archive (sent off-list or not yet received): 1190454934.27805.80.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#92 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 8 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one.   And you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it.  But it's still wrong.

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

Having two struct devices for an actual device is the price to pay for this, but I do think that creating a bus_type for virtio is the logical abstraction and not something we just make up to work around a deficiency in our device reprentation.

	Arnd <><

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): [email protected]

#94 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one. And
you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it. But it's still wrong.

Quoted 7 lines

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

This is still retro-justification. The simplest way for PCI systems to represent a virtio device as a PCI device; this makes life easy for any guest OS.

I just know we're going to regret this...
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

A message that is not in the archive (sent off-list or not yet received): 1190536431.27805.109.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#96 lore raw

Re: [PATCH 1/6] virtio interace

Quoted 22 lines · Rusty Russell
Quoted 11 lines · Arnd Bergmann
Quoted 9 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one. And
you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it. But it's still wrong.

Quoted 8 lines

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

Quoted 9 lines

This is still retro-justification. The simplest way for PCI systems to represent a virtio device as a PCI device; this makes life easy for any guest OS.

I just know we're going to regret this...
Rusty.

I'm not sure what's best, maybe this can help:
With the virtio_find_driver you need to place all virtio drivers under the same pci device or suggest new mapping. Using Arnd's solution (actually I implemented it for KVM before the new patch set) and 1-1 mapping for pci and virtio devices makes life simpler.
Dor.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#97 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Rusty Russell
Quoted 22 lines · Rusty Russell
Quoted 11 lines · Arnd Bergmann
Quoted 9 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one. And
you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it. But it's still wrong.

Quoted 8 lines

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

Quoted 9 lines

This is still retro-justification. The simplest way for PCI systems to represent a virtio device as a PCI device; this makes life easy for any guest OS.

I just know we're going to regret this...
Rusty.

I'm not sure what's best, maybe this can help:
With the virtio_find_driver you need to place all virtio drivers under the same pci device or suggest new mapping. Using Arnd's solution (actually I implemented it for KVM before the new patch set) and 1-1 mapping for pci and virtio devices makes life simpler.
Dor.

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#98 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Arnd Bergmann
Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one. And
you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it. But it's still wrong.

Quoted 7 lines

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

This is still retro-justification. The simplest way for PCI systems to represent a virtio device as a PCI device; this makes life easy for any guest OS.

I just know we're going to regret this...
Rusty.

maintainer
#99 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Rusty Russell
Quoted 8 lines · Rusty Russell

But now each virtio device has two "struct device"s, not one.   And you've made up a fictional bus to do it.

Yet for PCI systems, it really is a PCI device; exposing a second bus to userspace just because we put a layer in our implementation is poor form.

Perhaps this is the easiest way of doing it.  But it's still wrong.

I think it's just a matter of perspective. In the model I'm advocating, the PCI device is not the same as the virtio device but rather a virtio host bridge, very much like USB or SATA works.

We could easily have multiple virtio devices behind one PCI device, but since virtual PCI devices are cheap, a one-to-one mapping makes sense for simplicity.

Having two struct devices for an actual device is the price to pay for this, but I do think that creating a bus_type for virtio is the logical abstraction and not something we just make up to work around a deficiency in our device reprentation.

	Arnd <><
maintainer
#100 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Rusty Russell
Quoted 2 lines · Rusty Russell

Hmm, I guess we could have a PCI driver which claims all VIRTIO vendor devices.

yes, that was the idea.

Quoted 4 lines

Then it can call virtio_find_driver() (?) at the top of its probe function to find if there's a matching virtio driver. This PCI driver would have to be initialized after all the virtio drivers are registered, but that's easy.

No, just use the driver model, instead of working against it:

struct pci_virtio_device {
	struct pci_dev *pdev;
	char __iomem *mmio_space;
	struct virtio_device vdev;
};

static int __devinit pci_virtio_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)

{
	struct pci_virtio_device *dev = kzalloc(sizeof (*dev), GFP_KERNEL);
	dev->pdev = pdev;
	dev->mmio_space = pcim_iomap(pdev, 0, PCI_VIRTIO_BUFSIZE);
	dev->vdev->ops = &pci_virtqueue_ops;
	dev->vdev->config = &pci_virtio_config_ops;
	dev->vdev->type = ent->device;
	dev->vdev->class = ent->class;
	dev->vdev.dev.parent = &pdev->dev;

	return virtio_device_register(&dev->vdev;
}
Quoted 2 lines

The virtio layer would simply maintain a linked list of drivers and implement the virtio_find_driver() matching function.

nonono, just a virtio_bus that all virtio drivers register to:

static int virtio_net_probe(struct device *dev)

{
	struct virtio_device *vdev = to_virtio_dev(dev);
	struct virtqueue_ops *vq_ops = vdev->ops;

	/* same as current code */
	...

	return 0;
}
static struct virtio_device_id virtio_net_ids[] = {
	{ .type = VIRTIO_ID_NET, .class = PCI_CLASS_NETWORK_OTHER },
	{ },
};

static struct virtio_driver virtio_net = {
.id_table = &virtio_net_ids,
.driver = {
.name = "virtionet",
.probe = virtio_net_probe,
.remove = virtionet_remove,
.bus = &virtio_bus, /* <- look here */
},
};

static int __init virtio_net_init(void)

{
	return driver_register(&virtio_net.driver);
}

module_init(virtio_net_init);

Quoted 4 lines

And since we've suppressed normal PCI driver request_module (since it always finds "the driver") then we can implement that in virtio_find_driver(), and not use a PCI MODULE_DEVICE_TABLE.  Then we don't need (full) PCI ids at all.

right, as shown in my example above.

	Arnd <><
#101 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Arnd Bergmann
Quoted 15 lines · Arnd Bergmann

include/linux/virtio.h line 113

Quoted 9 lines · Rusty Russell
include/linux/virtio.h new file +9 -0
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+
+/* The particular virtio backend supplies these. */
+struct virtio_backend_ops {
+       int (*register_driver)(struct virtio_driver *drv);
+       void (*unregister_driver)(struct virtio_driver *drv);
+};
+extern struct virtio_backend_ops virtio_backend_ops;

This still seems a little awkward. From what I understand, you register a virtio_driver, which leads to a pci_driver (or whatever you are based on) to be registered behind the covers, so that the pci_device can be used directly as the virtio device.

Hi Arnd,

Yes, and I dislike it too.

Quoted 3 lines

I think there should instead be a pci_driver that automatically binds to all PCI based virtio imlpementations and creates a child device for the actual virtio_device.

I'm not sure I understand. For PCI probing to work, you want to have identified yourself as a driver for each PCI id claimed by a virtio device.

Hmm, I guess we could have a PCI driver which claims all VIRTIO vendor devices. Then it can call virtio_find_driver() (?) at the top of its probe function to find if there's a matching virtio driver. This PCI driver would have to be initialized after all the virtio drivers are registered, but that's easy.

The virtio layer would simply maintain a linked list of drivers and implement the virtio_find_driver() matching function.

And since we've suppressed normal PCI driver request_module (since it always finds "the driver") then we can implement that in virtio_find_driver(), and not use a PCI MODULE_DEVICE_TABLE. Then we don't need (full) PCI ids at all.

OK, I have some coding to do now...
Rusty.

#102 lore raw

PATCH 2/6 virtio_config

In reply to Rusty Russell

Previous versions of virtio didn't commonalize probing. For every driver, every virtio implementation (KVM, lguest, etc) needed an in-kernel stub to join their bus to the probe code.

To solve this, we introduce a "virtio_config" mechanism, which is simply a set of [u8 type][u8 len][...data...] fields for each device. Some convenient wrapper functions make this fairly easy for drivers to unpack their configuration data themselves.

This configuration data could be PCI config space, or an unrelated bus (eg. lguest) or manufactured by the kernel itself. It's designed to be extensible: fields get marked as the device reads them so a host supporting some future extension can tell if the guest driver understood it. This also applies to bitfields: the guest explicitly acks the bits it understands.

There's also a simple status bitmask useful for low-level host analysis of what the guest is doing with the device.

---
 drivers/Kconfig               |    2 
 drivers/Makefile              |    1 
 drivers/virtio/Makefile       |    2 
 drivers/virtio/config.c       |  109 +++++++++++++++++++++++++++++++
 include/linux/virtio_config.h |  141 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 254 insertions(+), 1 deletion(-)

===================================================================

drivers/Kconfig +2 -0
@@ -87,4 +87,6 @@ source "drivers/kvm/Kconfig"
 source "drivers/kvm/Kconfig"
 
 source "drivers/uio/Kconfig"
+
+source "drivers/virtio/Kconfig"
 endmenu

===================================================================

drivers/Makefile +1 -0
@@ -88,3 +88,4 @@ obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_OF)		+= of/
+obj-$(CONFIG_VIRTIO)		+= virtio/

===================================================================

drivers/virtio/Makefile +1 -1
@@ -1,1 +1,1 @@ obj-$(CONFIG_VIRTIO) += virtio.o
-obj-$(CONFIG_VIRTIO) += virtio.o
+obj-$(CONFIG_VIRTIO) += virtio.o config.o

===================================================================

drivers/virtio/config.c new file +109 -0

109 lines not on this page · raw message

===================================================================

include/linux/virtio_config.h new file +141 -0

141 lines not on this page · raw message

#103 lore raw

Re: [kvm-devel] [PATCH 1/6] virtio interace

In reply to Rusty Russell
Quoted 21 lines · Rusty Russell

(Changes:
- renamed sync to kick as Dor suggested
- added new_vq and free_vq hooks to create virtqueues
- define a simple virtio driver, which uses PCI ids
- provide register/unregister_virtio_driver hooks)

This attempts to implement a "virtual I/O" layer which should allow common drivers to be efficiently used across most virtual I/O mechanisms. It will no-doubt need further enhancement.

The virtio drivers add and get I/O buffers; as the buffers are consumed the driver "interrupt" callbacks are invoked.

It also provides driver register and unregister hooks, which are simply overridden at run time (eg. for a guest kernel which supports KVM paravirt and lguest).

+++ b/drivers/virtio/virtio.c

drivers/virtio/virtio.c line 4

Quoted 4 lines
drivers/virtio/virtio.c new file +4 -0
@@ -0,0 +1,20 @@
+#include <linux/virtio.h>
+
+struct virtio_backend_ops virtio_backend_ops;
+EXPORT_SYMBOL_GPL(virtio_backend_ops);

Suggest calling this virtio_transport_ops rather than the too-generic virtio_backend_ops. Especially since Xen uses backend for something completely different.

include/linux/virtio.h line 18

Quoted 8 lines
include/linux/virtio.h new file +7 -0
+
+/**
+ * virtqueue_ops - operations for virtqueue abstraction layer
+ * @new_vq: create a new virtqueue
+ *	config: the virtio_config_space field describing the queue
+ *	off: the offset in the config space of the queue configuration
+ *	len: the length of the virtio_config_space field

'off, len' are really a magic cookie. Why does the interface care about their meaning?

include/linux/virtio.h line 19

Quoted 2 lines
include/linux/virtio.h new file +1 -0
+ *	callback: the driver callback when the queue is used.

Missing callback return value description.

include/linux/virtio.h line 33

Quoted 4 lines
include/linux/virtio.h new file +3 -0
+ * @kick: update after add_buf
+ *	vq: the struct virtqueue
+ *	After one or more add_buf calls, invoke this to kick the virtio layer.

'the other side'

I'm not thrilled about reusing pci ids. Maybe the s390 can say whether this is a real issue.

Signature · 1 line
error compiling committee.c: too many arguments to function
maintainer
#104 lore raw

Re: [PATCH 1/6] virtio interace

In reply to Rusty Russell
Quoted 17 lines · Rusty Russell

+ * virtio_driver - operations for a virtio I/O driver
+ * @name: the name of the driver (KBUILD_MODNAME).
+ * @owner: the module which contains these routines (ie. THIS_MODULE).
+ * @id_table: the ids (we re-use PCI ids) serviced by this driver.
+ * @probe: the function to call when a device is found.  Returns a token for
+ *    remove, or PTR_ERR().
+ * @remove: the function when a device is removed.
+ */

include/linux/virtio.h new file +9 -0
+struct virtio_driver {
+       const char *name;
+       struct module *owner;
+       struct pci_device_id *id_table;
+       void *(*probe)(struct device *device,
+                      struct virtio_config_space *config,
+                      struct virtqueue_ops *vqops);
+       void (*remove)(void *dev);
+};

include/linux/virtio.h line 113

Quoted 10 lines
include/linux/virtio.h new file +10 -0
+
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+
+/* The particular virtio backend supplies these. */
+struct virtio_backend_ops {
+       int (*register_driver)(struct virtio_driver *drv);
+       void (*unregister_driver)(struct virtio_driver *drv);
+};
+extern struct virtio_backend_ops virtio_backend_ops;

This still seems a little awkward. From what I understand, you register a virtio_driver, which leads to a pci_driver (or whatever you are based on) to be registered behind the covers, so that the pci_device can be used directly as the virtio device.

I think there should instead be a pci_driver that automatically binds to all PCI based virtio imlpementations and creates a child device for the actual virtio_device. Then you can have the virtio_driver itself be based on a device_driver, and you can get rid of the global virtio_backend_ops. That will be useful when a virtual machine has two ways to get at the virtio devices, e.g. a KVM guest that has both hcall based probing for virtio devices and some other virtio devices that are exported through PCI.

	Arnd <><
#105 lore raw
In reply to a message not in the archive
Quoted 20 lines · Rusty Russell

Hi all,

This patch series attempts to come closer to unifying kvm and
lguest's
usage of virtio. As these two are the first implementations we've seen, I hope making them closer will make future ones closer too.

Drivers now unpack their own configuration: their probe()
methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I've abstracted out the lguest ring buffer code into a common
library.
The format has changed slightly (mainly because I had an epiphany about inter-guest I/O).

I also implemented a console (lguest needs one).

Quoted 9 lines

Finally, there is a working lguest implementation. Unfortunately,
lguest is being refactored for non-i386 ports, so the virtio patches sit at the end of the (quite long) for-2.6.24 patchqueue. Nonetheless, they can be found at http://lguest.ozlabs.org/patches (click on bz2 to get the series).

Cheers!
Rusty.

Superb job, it saved me the burden of try to merge the in-house virtio_backend.

I like the separation of the ring code, the improved descriptors and the notify too. Regarding the pci config space, I rather see config_ops type of operations to let the 390/xen/other implementations jump on our wagon.

Maybe change the offset/len type into a handle pointer and function pointers. The best would be to let them comment on that. I glimpsed over xen netfront.c and I think that the config space can be used without too many hassles
Dor.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): 46F2791A.8070601-atKUWr5tajBWk0Htik3J/[email protected]

#107 lore raw

Re: [Lguest] [PATCH 0/6] virtio with config abstraction and ringimplementation

Quoted 40 lines · Dor Laor
Quoted 27 lines · Rusty Russell

Hi all,

This patch series attempts to come closer to unifying kvm and
lguest's
usage of virtio. As these two are the first implementations we've seen, I hope making them closer will make future ones closer too.

Drivers now unpack their own configuration: their probe()
methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I've abstracted out the lguest ring buffer code into a common
library.
The format has changed slightly (mainly because I had an epiphany about inter-guest I/O).

I also implemented a console (lguest needs one).

Finally, there is a working lguest implementation.
Unfortunately,
lguest is being refactored for non-i386 ports, so the virtio patches sit at the end of the (quite long) for-2.6.24 patchqueue. Nonetheless, they can be found at http://lguest.ozlabs.org/patches (click on bz2 to get the series).

Quoted 3 lines

Cheers!
Rusty.

Superb job, it saved me the burden of try to merge the in-house virtio_backend.

I like the separation of the ring code, the improved descriptors and the notify too.
Regarding the pci config space, I rather see config_ops type of operations to let
the 390/xen/other implementations jump on our wagon.

Quoted 7 lines

Maybe change the offset/len type into a handle pointer and function pointers.
The best would be to let them comment on that. I glimpsed over xen netfront.c and I think that
the config space can be used without too many hassles Dor.

Of course I'll rebase what's left of my code over the new patches.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#108 lore raw

Re: [Lguest] [PATCH 0/6] virtio with config abstraction and ringimplementation

In reply to Dor Laor
Quoted 33 lines · Dor Laor
Quoted 27 lines · Rusty Russell

Hi all,

This patch series attempts to come closer to unifying kvm and
lguest's
usage of virtio. As these two are the first implementations we've seen, I hope making them closer will make future ones closer too.

Drivers now unpack their own configuration: their probe()
methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I've abstracted out the lguest ring buffer code into a common
library.
The format has changed slightly (mainly because I had an epiphany about inter-guest I/O).

I also implemented a console (lguest needs one).

Finally, there is a working lguest implementation.
Unfortunately,
lguest is being refactored for non-i386 ports, so the virtio patches sit at the end of the (quite long) for-2.6.24 patchqueue. Nonetheless, they can be found at http://lguest.ozlabs.org/patches (click on bz2 to get the series).

Quoted 3 lines

Cheers!
Rusty.

Superb job, it saved me the burden of try to merge the in-house virtio_backend.

Quoted 9 lines

I like the separation of the ring code, the improved descriptors and the notify too. Regarding the pci config space, I rather see config_ops type of operations to let the 390/xen/other implementations jump on our wagon.

Maybe change the offset/len type into a handle pointer and function pointers. The best would be to let them comment on that. I glimpsed over xen netfront.c and I think that the config space can be used without too many hassles
Dor.

Of course I'll rebase what's left of my code over the new patches.

#109 lore raw
In reply to Dor Laor
Quoted 11 lines · Dor Laor
Quoted 3 lines · Rusty Russell

Drivers now unpack their own configuration: their probe() methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I like the separation of the ring code, the improved descriptors and the notify too.
Regarding the pci config space, I rather see config_ops type of operations to let
the 390/xen/other implementations jump on our wagon.

It's possible to abstract at the find_config() level, but it's also not too bad to linearize any existing configuration. I chose to change the lguest device page to use a linearized format, but I could have adapted the old device info struct in the kernel without too much hassle:

FYI, here's the lguest snippet, for example:

+struct lguest_config {
+ struct virtio_config_space v;
+
+ /* Status pointer: 4 bytes, then comes the config space itself. */
+ u8 *status;
+};
...
+static void lguest_writeb(struct virtio_config_space *v, unsigned off, u8 b) +{
+ struct lguest_config *c = container_of(v, struct lguest_config, v);
+
+ c->status[4 + off] = b;
+}
+
+static u8 lguest_readb(struct virtio_config_space *v, unsigned off) +{
+ struct lguest_config *c = container_of(v, struct lguest_config, v);
+
+ return c->status[4 + off];
+}
+
+static void lguest_set_status(struct virtio_config_space *v, u32 status) +{
+ struct lguest_config *c = container_of(v, struct lguest_config, v);
+
+ memcpy(c->status, &status, sizeof(status));
+}
+
+static u32 lguest_get_status(struct virtio_config_space *v)
+{
+ struct lguest_config *c = container_of(v, struct lguest_config, v);
+ u32 status;
+
+ memcpy(&status, c->status, sizeof(status));
+ return status;
+}

#110 lore raw

PATCH 1/6 virtio interace

In reply to Rusty Russell

(Changes:
- renamed sync to kick as Dor suggested
- added new_vq and free_vq hooks to create virtqueues
- define a simple virtio driver, which uses PCI ids
- provide register/unregister_virtio_driver hooks)

This attempts to implement a "virtual I/O" layer which should allow common drivers to be efficiently used across most virtual I/O mechanisms. It will no-doubt need further enhancement.

The virtio drivers add and get I/O buffers; as the buffers are consumed the driver "interrupt" callbacks are invoked.

It also provides driver register and unregister hooks, which are simply overridden at run time (eg. for a guest kernel which supports KVM paravirt and lguest).

---
 drivers/virtio/Kconfig  |    3 +
 drivers/virtio/Makefile |    1 
 drivers/virtio/virtio.c |   20 ++++++++
 include/linux/virtio.h  |  114 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 138 insertions(+)

===================================================================

drivers/virtio/Kconfig new file +3 -0
@@ -0,0 +1,3 @@
+# Virtio always gets selected by whoever wants it.
+config VIRTIO
+	bool

===================================================================

drivers/virtio/Makefile new file +1 -0
@@ -0,0 +1,1 @@
+obj-$(CONFIG_VIRTIO) += virtio.o

===================================================================

drivers/virtio/virtio.c new file +20 -0
@@ -0,0 +1,20 @@
+#include <linux/virtio.h>
+
+struct virtio_backend_ops virtio_backend_ops;
+EXPORT_SYMBOL_GPL(virtio_backend_ops);
+
+/* register and unregister simply punt through to the specific backend. */
+int register_virtio_driver(struct virtio_driver *drv)
+{
+	if (!virtio_backend_ops.register_driver)
+		return -ENOSYS;
+
+	return virtio_backend_ops.register_driver(drv);
+}
+EXPORT_SYMBOL_GPL(register_virtio_driver);
+
+void unregister_virtio_driver(struct virtio_driver *drv)
+{
+	virtio_backend_ops.unregister_driver(drv);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_driver);

===================================================================

include/linux/virtio.h new file +114 -0

114 lines not on this page · raw message

#111 lore raw
In reply to Rusty Russell
Quoted 20 lines · Rusty Russell

Hi all,

This patch series attempts to come closer to unifying kvm and
lguest's
usage of virtio. As these two are the first implementations we've seen, I hope making them closer will make future ones closer too.

Drivers now unpack their own configuration: their probe()
methods are
uniform. The configuration mechanism is extensible and can be backed by PCI, a string of bytes, or something else.

I've abstracted out the lguest ring buffer code into a common
library.
The format has changed slightly (mainly because I had an epiphany about inter-guest I/O).

I also implemented a console (lguest needs one).

Quoted 9 lines

Finally, there is a working lguest implementation. Unfortunately,
lguest is being refactored for non-i386 ports, so the virtio patches sit at the end of the (quite long) for-2.6.24 patchqueue. Nonetheless, they can be found at http://lguest.ozlabs.org/patches (click on bz2 to get the series).

Cheers!
Rusty.

Superb job, it saved me the burden of try to merge the in-house virtio_backend.

I like the separation of the ring code, the improved descriptors and the notify too. Regarding the pci config space, I rather see config_ops type of operations to let the 390/xen/other implementations jump on our wagon.

Maybe change the offset/len type into a handle pointer and function pointers. The best would be to let them comment on that. I glimpsed over xen netfront.c and I think that the config space can be used without too many hassles
Dor.

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization