All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gregory Haskins <ghaskins@novell.com>
To: linux-kernel@vger.kernel.org
Cc: agraf@suse.de, pmullaney@novell.com, pmorreale@novell.com,
	anthony@codemonkey.ws, rusty@rustcorp.com.au,
	netdev@vger.kernel.org, kvm@vger.kernel.org
Subject: [RFC PATCH 11/17] venet: add scatter-gather support
Date: Tue, 31 Mar 2009 14:43:44 -0400	[thread overview]
Message-ID: <20090331184344.28333.53834.stgit@dev.haskins.net> (raw)
In-Reply-To: <20090331184057.28333.77287.stgit@dev.haskins.net>

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
---

 drivers/net/vbus-enet.c |  249 +++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/venet.h   |   39 +++++++
 2 files changed, 275 insertions(+), 13 deletions(-)

diff --git a/drivers/net/vbus-enet.c b/drivers/net/vbus-enet.c
index e698b3f..8e96c9c 100644
--- a/drivers/net/vbus-enet.c
+++ b/drivers/net/vbus-enet.c
@@ -42,6 +42,8 @@ static int rx_ringlen = 256;
 module_param(rx_ringlen, int, 0444);
 static int tx_ringlen = 256;
 module_param(tx_ringlen, int, 0444);
+static int sg_enabled = 1;
+module_param(sg_enabled, int, 0444);
 
 #undef PDEBUG             /* undef it, just in case */
 #ifdef VBUS_ENET_DEBUG
@@ -64,8 +66,17 @@ struct vbus_enet_priv {
 	struct vbus_enet_queue     rxq;
 	struct vbus_enet_queue     txq;
 	struct tasklet_struct      txtask;
+	struct {
+		int                sg:1;
+		int                tso:1;
+		int                ufo:1;
+		int                tso6:1;
+		int                ecn:1;
+	} flags;
 };
 
+static void vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force);
+
 static struct vbus_enet_priv *
 napi_to_priv(struct napi_struct *napi)
 {
@@ -199,6 +210,93 @@ rx_teardown(struct vbus_enet_priv *priv)
 	}
 }
 
+static int
+tx_setup(struct vbus_enet_priv *priv)
+{
+	struct ioq *ioq = priv->txq.queue;
+	struct ioq_iterator iter;
+	int i;
+	int ret;
+
+	if (!priv->flags.sg)
+		/*
+		 * There is nothing to do for a ring that is not using
+		 * scatter-gather
+		 */
+		return 0;
+
+	ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+	BUG_ON(ret < 0);
+
+	ret = ioq_iter_seek(&iter, ioq_seek_set, 0, 0);
+	BUG_ON(ret < 0);
+
+	/*
+	 * Now populate each descriptor with an empty SG descriptor
+	 */
+	for (i = 0; i < tx_ringlen; i++) {
+		struct venet_sg *vsg;
+		size_t iovlen = sizeof(struct venet_iov) * (MAX_SKB_FRAGS-1);
+		size_t len = sizeof(*vsg) + iovlen;
+
+		vsg = kzalloc(len, GFP_KERNEL);
+		if (!vsg)
+			return -ENOMEM;
+
+		iter.desc->cookie = (u64)vsg;
+		iter.desc->len    = len;
+		iter.desc->ptr    = (u64)__pa(vsg);
+
+		ret = ioq_iter_seek(&iter, ioq_seek_next, 0, 0);
+		BUG_ON(ret < 0);
+	}
+
+	return 0;
+}
+
+static void
+tx_teardown(struct vbus_enet_priv *priv)
+{
+	struct ioq *ioq = priv->txq.queue;
+	struct ioq_iterator iter;
+	int ret;
+
+	/* forcefully free all outstanding transmissions */
+	vbus_enet_tx_reap(priv, 1);
+
+	if (!priv->flags.sg)
+		/*
+		 * There is nothing else to do for a ring that is not using
+		 * scatter-gather
+		 */
+		return;
+
+	ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+	BUG_ON(ret < 0);
+
+	/* seek to position 0 */
+	ret = ioq_iter_seek(&iter, ioq_seek_set, 0, 0);
+	BUG_ON(ret < 0);
+
+	/*
+	 * free each valid descriptor
+	 */
+	while (iter.desc->cookie) {
+		struct venet_sg *vsg = (struct venet_sg *)iter.desc->cookie;
+
+		iter.desc->valid = 0;
+		wmb();
+
+		iter.desc->ptr = 0;
+		iter.desc->cookie = 0;
+
+		ret = ioq_iter_seek(&iter, ioq_seek_next, 0, 0);
+		BUG_ON(ret < 0);
+
+		kfree(vsg);
+	}
+}
+
 /*
  * Open and close
  */
@@ -403,14 +501,67 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
 	BUG_ON(ret < 0);
 	BUG_ON(iter.desc->sown);
 
-	/*
-	 * We simply put the skb right onto the ring.  We will get an interrupt
-	 * later when the data has been consumed and we can reap the pointers
-	 * at that time
-	 */
-	iter.desc->cookie = (u64)skb;
-	iter.desc->len = (u64)skb->len;
-	iter.desc->ptr = (u64)__pa(skb->data);
+	if (priv->flags.sg) {
+		struct venet_sg *vsg = (struct venet_sg *)iter.desc->cookie;
+		struct scatterlist sgl[MAX_SKB_FRAGS+1];
+		struct scatterlist *sg;
+		int count, maxcount = ARRAY_SIZE(sgl);
+
+		sg_init_table(sgl, maxcount);
+
+		memset(vsg, 0, sizeof(*vsg));
+
+		vsg->cookie = (u64)skb;
+		vsg->len    = skb->len;
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			vsg->flags      |= VENET_SG_FLAG_NEEDS_CSUM;
+			vsg->csum.start  = skb->csum_start - skb_headroom(skb);
+			vsg->csum.offset = skb->csum_offset;
+		}
+
+		if (skb_is_gso(skb)) {
+			struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+			vsg->flags |= VENET_SG_FLAG_GSO;
+
+			vsg->gso.hdrlen = skb_transport_header(skb) - skb->data;
+			vsg->gso.size = sinfo->gso_size;
+			if (sinfo->gso_type & SKB_GSO_TCPV4)
+				vsg->gso.type = VENET_GSO_TYPE_TCPV4;
+			else if (sinfo->gso_type & SKB_GSO_TCPV6)
+				vsg->gso.type = VENET_GSO_TYPE_TCPV6;
+			else if (sinfo->gso_type & SKB_GSO_UDP)
+				vsg->gso.type = VENET_GSO_TYPE_UDP;
+			else
+				panic("Virtual-Ethernet: unknown GSO type " \
+				      "0x%x\n", sinfo->gso_type);
+
+			if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+				vsg->flags |= VENET_SG_FLAG_ECN;
+		}
+
+		count = skb_to_sgvec(skb, sgl, 0, skb->len);
+
+		BUG_ON(count > maxcount);
+
+		for (sg = &sgl[0]; sg; sg = sg_next(sg)) {
+			struct venet_iov *iov = &vsg->iov[vsg->count++];
+
+			iov->len = sg->length;
+			iov->ptr = (u64)sg_phys(sg);
+		}
+
+	} else {
+		/*
+		 * non scatter-gather mode: simply put the skb right onto the
+		 * ring.
+		 */
+		iter.desc->cookie = (u64)skb;
+		iter.desc->len = (u64)skb->len;
+		iter.desc->ptr = (u64)__pa(skb->data);
+	}
+
 	iter.desc->valid  = 1;
 
 	priv->stats.tx_packets++;
@@ -466,7 +617,17 @@ vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
 	 * owned by the south-side
 	 */
 	while (iter.desc->valid && (!iter.desc->sown || force)) {
-		struct sk_buff *skb = (struct sk_buff *)iter.desc->cookie;
+		struct sk_buff *skb;
+
+		if (priv->flags.sg) {
+			struct venet_sg *vsg;
+
+			vsg = (struct venet_sg *)iter.desc->cookie;
+			skb = (struct sk_buff *)vsg->cookie;
+
+		} else {
+			skb = (struct sk_buff *)iter.desc->cookie;
+		}
 
 		PDEBUG("%lld: completed sending %d bytes\n",
 		       priv->vdev->id, skb->len);
@@ -567,6 +728,47 @@ tx_isr(struct ioq_notifier *notifier)
        tasklet_schedule(&priv->txtask);
 }
 
+static int
+vbus_enet_negcap(struct vbus_enet_priv *priv)
+{
+	int ret;
+	struct venet_capabilities caps;
+
+	memset(&caps, 0, sizeof(caps));
+
+	if (sg_enabled) {
+		caps.gid = VENET_CAP_GROUP_SG;
+		caps.bits |= (VENET_CAP_SG|VENET_CAP_TSO4|VENET_CAP_TSO6
+			      |VENET_CAP_ECN|VENET_CAP_UFO);
+	}
+
+	ret = devcall(priv, VENET_FUNC_NEGCAP, &caps, sizeof(caps));
+	if (ret < 0)
+		return ret;
+
+	if (caps.bits & VENET_CAP_SG) {
+		priv->flags.sg = true;
+
+		if (caps.bits & VENET_CAP_TSO4)
+			priv->flags.tso = true;
+		if (caps.bits & VENET_CAP_TSO6)
+			priv->flags.tso6 = true;
+		if (caps.bits & VENET_CAP_UFO)
+			priv->flags.ufo = true;
+		if (caps.bits & VENET_CAP_ECN)
+			priv->flags.ecn = true;
+
+		printk(KERN_INFO "VBUSENET %lld: " \
+		       "Detected GSO features %s%s%s%s\n", priv->vdev->id,
+		       priv->flags.tso  ? "t" : "-",
+		       priv->flags.tso6 ? "T" : "-",
+		       priv->flags.ufo  ? "u" : "-",
+		       priv->flags.ecn  ? "e" : "-");
+	}
+
+	return 0;
+}
+
 static struct net_device_ops vbus_enet_netdev_ops = {
 	.ndo_open          = vbus_enet_open,
 	.ndo_stop          = vbus_enet_stop,
@@ -606,12 +808,21 @@ vbus_enet_probe(struct vbus_device_proxy *vdev)
 	priv->dev  = dev;
 	priv->vdev = vdev;
 
+	ret = vbus_enet_negcap(priv);
+	if (ret < 0) {
+		printk(KERN_INFO "VENET: Error negotiating capabilities for " \
+		       "%lld\n",
+		       priv->vdev->id);
+		goto out_free;
+	}
+
 	tasklet_init(&priv->txtask, deferred_tx_isr, (unsigned long)priv);
 
 	queue_init(priv, &priv->rxq, VENET_QUEUE_RX, rx_ringlen, rx_isr);
 	queue_init(priv, &priv->txq, VENET_QUEUE_TX, tx_ringlen, tx_isr);
 
 	rx_setup(priv);
+	tx_setup(priv);
 
 	ioq_notify_enable(priv->rxq.queue, 0);  /* enable interrupts */
 	ioq_notify_enable(priv->txq.queue, 0);
@@ -633,6 +844,22 @@ vbus_enet_probe(struct vbus_device_proxy *vdev)
 
 	dev->features |= NETIF_F_HIGHDMA;
 
+	if (priv->flags.sg) {
+		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM|NETIF_F_FRAGLIST;
+
+		if (priv->flags.tso)
+			dev->features |= NETIF_F_TSO;
+
+		if (priv->flags.ufo)
+			dev->features |= NETIF_F_UFO;
+
+		if (priv->flags.tso6)
+			dev->features |= NETIF_F_TSO6;
+
+		if (priv->flags.ecn)
+			dev->features |= NETIF_F_TSO_ECN;
+	}
+
 	ret = register_netdev(dev);
 	if (ret < 0) {
 		printk(KERN_INFO "VENET: error %i registering device \"%s\"\n",
@@ -660,9 +887,9 @@ vbus_enet_remove(struct vbus_device_proxy *vdev)
 	napi_disable(&priv->napi);
 
 	rx_teardown(priv);
-	vbus_enet_tx_reap(priv, 1);
-
 	ioq_put(priv->rxq.queue);
+
+	tx_teardown(priv);
 	ioq_put(priv->txq.queue);
 
 	dev->ops->close(dev, 0);
diff --git a/include/linux/venet.h b/include/linux/venet.h
index ef6b199..1c96b90 100644
--- a/include/linux/venet.h
+++ b/include/linux/venet.h
@@ -35,8 +35,43 @@ struct venet_capabilities {
 	__u32 bits;
 };
 
-/* CAPABILITIES-GROUP 0 */
-/* #define VENET_CAP_FOO    0   (No capabilities defined yet, for now) */
+#define VENET_CAP_GROUP_SG 0
+
+/* CAPABILITIES-GROUP SG */
+#define VENET_CAP_SG     (1 << 0)
+#define VENET_CAP_TSO4   (1 << 1)
+#define VENET_CAP_TSO6   (1 << 2)
+#define VENET_CAP_ECN    (1 << 3)
+#define VENET_CAP_UFO    (1 << 4)
+
+struct venet_iov {
+	__u32 len;
+	__u64 ptr;
+};
+
+#define VENET_SG_FLAG_NEEDS_CSUM (1 << 0)
+#define VENET_SG_FLAG_GSO        (1 << 1)
+#define VENET_SG_FLAG_ECN        (1 << 2)
+
+struct venet_sg {
+	__u64            cookie;
+	__u32            flags;
+	__u32            len;     /* total length of all iovs */
+	struct {
+		__u16    start;	  /* csum starting position */
+		__u16    offset;  /* offset to place csum */
+	} csum;
+	struct {
+#define VENET_GSO_TYPE_TCPV4	0	/* IPv4 TCP (TSO) */
+#define VENET_GSO_TYPE_UDP	1	/* IPv4 UDP (UFO) */
+#define VENET_GSO_TYPE_TCPV6	2	/* IPv6 TCP */
+		__u8     type;
+		__u16    hdrlen;
+		__u16    size;
+	} gso;
+	__u32            count;   /* nr of iovs */
+	struct venet_iov iov[1];
+};
 
 #define VENET_FUNC_LINKUP   0
 #define VENET_FUNC_LINKDOWN 1


  parent reply	other threads:[~2009-03-31 18:45 UTC|newest]

Thread overview: 150+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-31 18:42 [RFC PATCH 00/17] virtual-bus Gregory Haskins
2009-03-31 18:42 ` [RFC PATCH 01/17] shm-signal: shared-memory signals Gregory Haskins
2009-03-31 20:44   ` Avi Kivity
2009-03-31 20:58     ` Gregory Haskins
2009-03-31 21:05       ` Avi Kivity
2009-04-01 12:12         ` Gregory Haskins
2009-04-01 12:24           ` Avi Kivity
2009-04-01 13:57             ` Gregory Haskins
2009-03-31 18:42 ` [RFC PATCH 02/17] vbus: add virtual-bus definitions Gregory Haskins
2009-04-02 16:06   ` Ben Hutchings
2009-04-02 18:13     ` Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 03/17] vbus: add connection-client helper infrastructure Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 04/17] vbus: add bus-registration notifiers Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 05/17] vbus: add a "vbus-proxy" bus model for vbus_driver objects Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 06/17] ioq: Add basic definitions for a shared-memory, lockless queue Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 07/17] ioq: add vbus helpers Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 08/17] venet: add the ABI definitions for an 802.x packet interface Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 09/17] net: Add vbus_enet driver Gregory Haskins
2009-03-31 20:39   ` Stephen Hemminger
2009-04-02 11:43     ` Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 10/17] venet-tap: Adds a "venet" compatible "tap" device to VBUS Gregory Haskins
2009-03-31 18:43 ` Gregory Haskins [this message]
2009-03-31 18:43 ` [RFC PATCH 12/17] venettap: add scatter-gather support Gregory Haskins
2009-03-31 18:43 ` [RFC PATCH 13/17] x86: allow the irq->vector translation to be determined outside of ioapic Gregory Haskins
2009-03-31 19:16   ` Alan Cox
2009-03-31 20:02     ` Gregory Haskins
2009-03-31 18:44 ` [RFC PATCH 14/17] kvm: add a reset capability Gregory Haskins
2009-03-31 19:22   ` Avi Kivity
2009-03-31 20:02     ` Gregory Haskins
2009-03-31 20:18       ` Avi Kivity
2009-03-31 20:37         ` Gregory Haskins
2009-03-31 18:44 ` [RFC PATCH 15/17] kvm: add dynamic IRQ support Gregory Haskins
2009-03-31 19:20   ` Avi Kivity
2009-03-31 19:39     ` Gregory Haskins
2009-03-31 20:13       ` Avi Kivity
2009-03-31 20:32         ` Gregory Haskins
2009-03-31 20:59           ` Avi Kivity
2009-03-31 18:44 ` [RFC PATCH 16/17] kvm: Add VBUS support to the host Gregory Haskins
2009-03-31 18:44 ` [RFC PATCH 17/17] kvm: Add guest-side support for VBUS Gregory Haskins
2009-03-31 20:18 ` [RFC PATCH 00/17] virtual-bus Andi Kleen
2009-04-01 12:03   ` Gregory Haskins
2009-04-01 13:23     ` Andi Kleen
2009-04-01 14:19       ` Gregory Haskins
2009-04-01 14:42         ` Gregory Haskins
2009-04-01 17:01         ` Andi Kleen
2009-04-01 18:45           ` Anthony Liguori
2009-04-01 20:40             ` Chris Wright
2009-04-01 21:11               ` Gregory Haskins
2009-04-01 21:28                 ` Chris Wright
2009-04-01 22:10                   ` Gregory Haskins
2009-04-02  6:00                     ` Chris Wright
2009-04-02  3:11               ` Herbert Xu
2009-04-01 21:09             ` Gregory Haskins
2009-04-02  0:29               ` Anthony Liguori
2009-04-02  3:11                 ` Gregory Haskins
2009-04-02  6:51               ` Avi Kivity
2009-04-02  8:52                 ` Herbert Xu
2009-04-02  9:02                   ` Avi Kivity
2009-04-02  9:16                     ` Herbert Xu
2009-04-02  9:27                       ` Avi Kivity
2009-04-02  9:29                         ` Herbert Xu
2009-04-02  9:33                           ` Herbert Xu
2009-04-02  9:38                           ` Avi Kivity
2009-04-02  9:41                             ` Herbert Xu
2009-04-02  9:43                               ` Avi Kivity
2009-04-02  9:44                                 ` Herbert Xu
2009-04-02 11:06                             ` Gregory Haskins
2009-04-02 11:59                               ` Avi Kivity
2009-04-02 12:30                                 ` Gregory Haskins
2009-04-02 12:43                                   ` Avi Kivity
2009-04-02 13:03                                     ` Gregory Haskins
2009-04-02 12:13                               ` Rusty Russell
2009-04-02 12:50                                 ` Gregory Haskins
2009-04-02 12:52                                   ` Gregory Haskins
2009-04-02 13:07                                   ` Avi Kivity
2009-04-02 13:22                                     ` Gregory Haskins
2009-04-02 13:27                                       ` Avi Kivity
2009-04-02 14:05                                         ` Gregory Haskins
2009-04-02 14:50                                     ` Herbert Xu
2009-04-02 15:00                                       ` Avi Kivity
2009-04-02 15:40                                         ` Herbert Xu
2009-04-02 15:57                                           ` Avi Kivity
2009-04-02 16:09                                             ` Herbert Xu
2009-04-02 16:54                                               ` Avi Kivity
2009-04-02 17:06                                                 ` Herbert Xu
2009-04-02 17:17                                                   ` Herbert Xu
2009-04-03 12:25                                                   ` Avi Kivity
2009-04-02 15:10                                 ` Michael S. Tsirkin
2009-04-03  4:43                                   ` Jeremy Fitzhardinge
2009-04-02 10:55                     ` Gregory Haskins
2009-04-02 11:48                       ` Avi Kivity
2009-04-03 10:58                     ` Gerd Hoffmann
2009-04-03 11:03                       ` Avi Kivity
2009-04-03 11:12                         ` Herbert Xu
2009-04-03 11:46                           ` Avi Kivity
2009-04-03 11:48                             ` Herbert Xu
2009-04-03 11:54                               ` Avi Kivity
2009-04-03 11:55                                 ` Herbert Xu
2009-04-03 12:02                                   ` Avi Kivity
2009-04-03 13:05                                     ` Herbert Xu
2009-04-03 11:18                       ` Andi Kleen
2009-04-03 11:34                         ` Herbert Xu
2009-04-03 11:46                         ` Avi Kivity
2009-04-03 11:28                       ` Gregory Haskins
2009-04-02 10:46                 ` Gregory Haskins
2009-04-02 11:43                   ` Avi Kivity
2009-04-02 12:22                     ` Gregory Haskins
2009-04-02 12:42                       ` Avi Kivity
2009-04-02 12:54                         ` Gregory Haskins
2009-04-02 13:08                           ` Avi Kivity
2009-04-02 13:36                             ` Gregory Haskins
2009-04-02 13:45                               ` Avi Kivity
2009-04-02 14:24                                 ` Gregory Haskins
2009-04-02 14:32                                   ` Avi Kivity
2009-04-02 14:41                                     ` Avi Kivity
2009-04-02 14:49                                       ` Anthony Liguori
2009-04-02 16:09                                         ` Anthony Liguori
2009-04-02 16:19                                           ` Avi Kivity
2009-04-02 18:18                                             ` Anthony Liguori
2009-04-03  1:11                                               ` Herbert Xu
2009-04-20 18:02                                               ` [kvm] " Alex Williamson
2009-04-20 18:02                                                 ` Alex Williamson
2009-04-03 12:03                                           ` Gregory Haskins
2009-04-03 12:15                                             ` Avi Kivity
2009-04-03 13:13                                               ` Gregory Haskins
2009-04-03 13:37                                                 ` Avi Kivity
2009-04-03 13:37                                                   ` Avi Kivity
2009-04-03 16:28                                                   ` Gregory Haskins
2009-04-03 16:28                                                     ` Gregory Haskins
2009-04-05 10:00                                                     ` Avi Kivity
2009-04-05 10:00                                                       ` Avi Kivity
2009-04-02  3:09             ` Herbert Xu
2009-04-02  6:46               ` Avi Kivity
2009-04-02  8:54                 ` Herbert Xu
2009-04-02  9:03                   ` Avi Kivity
2009-04-02  9:05                     ` Herbert Xu
2009-04-01 20:29           ` Gregory Haskins
2009-04-01 22:23             ` Andi Kleen
2009-04-01 23:05               ` Gregory Haskins
2009-04-01  6:08 ` Rusty Russell
2009-04-01 11:35   ` Gregory Haskins
2009-04-02  1:24     ` Rusty Russell
2009-04-02  2:27       ` Gregory Haskins
2009-04-01 16:10   ` Anthony Liguori
2009-04-05  3:44     ` Rusty Russell
2009-04-05  8:06       ` Avi Kivity
2009-04-05 14:13       ` Anthony Liguori
2009-04-05 16:10         ` Avi Kivity
2009-04-05 16:45           ` Anthony Liguori
2009-04-02  3:15   ` Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090331184344.28333.53834.stgit@dev.haskins.net \
    --to=ghaskins@novell.com \
    --cc=agraf@suse.de \
    --cc=anthony@codemonkey.ws \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pmorreale@novell.com \
    --cc=pmullaney@novell.com \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.