[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Add a new style of passing GSO packets to frontends.



feature-gso-tcpv4-prefix uses precedes the packet data passed to
the frontend with a ring entry that contains the necessary
metadata. This style of GSO passing is required for Citrix
Windows PV Drivers.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 drivers/xen/netback/common.h     |    3 +-
 drivers/xen/netback/netback.c    |   43 ++++++++++++++++++++++++++++++++++---
 drivers/xen/netback/xenbus.c     |   17 +++++++++++---
 include/xen/interface/io/netif.h |    4 +++
 4 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h
index 857778c..1cbc4ff 100644
--- a/drivers/xen/netback/common.h
+++ b/drivers/xen/netback/common.h
@@ -82,7 +82,8 @@ struct xen_netif {
        int smart_poll;
 
        /* Internal feature information. */
-       u8 can_queue:1; /* can queue packets for receiver? */
+       u8 can_queue:1;     /* can queue packets for receiver? */
+       u8 gso_prefix:1;    /* use a prefix segment for GSO information */
 
        /* Allow netif_be_start_xmit() to peek ahead in the rx request
         * ring.  This is a prediction of what rx_req_cons will be once
diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c
index c8f5c1b..93f0686 100644
--- a/drivers/xen/netback/netback.c
+++ b/drivers/xen/netback/netback.c
@@ -313,8 +313,12 @@ int netif_be_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
 
        netbk = &xen_netbk[netif->group];
 
+       /* Drop the packet if the netif is not up or there is no carrier. */
+       if (unlikely(!netif_schedulable(netif)))
+               goto drop;
+
        /* Drop the packet if the target domain has no receive buffers. */
-       if (unlikely(!netif_schedulable(netif) || netbk_queue_full(netif)))
+       if (unlikely(netbk_queue_full(netif)))
                goto drop;
 
        /*
@@ -432,6 +436,7 @@ static void netbk_gop_frag_copy(struct xen_netif *netif,
                        /* Overflowed this request, go to the next one */
                        req = RING_GET_REQUEST(&netif->rx, 
netif->rx.req_cons++);
                        meta = npo->meta + npo->meta_prod++;
+                       meta->gso_size = 0;
                        meta->size = 0;
                        meta->id = req->id;
                        npo->copy_off = 0;
@@ -492,9 +497,23 @@ static int netbk_gop_skb(struct sk_buff *skb,
 
        old_meta_prod = npo->meta_prod;
 
+       /* Set up a GSO prefix descriptor, if necessary */
+       if (skb_shinfo(skb)->gso_size && netif->gso_prefix) {
+               req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons++);
+               meta = npo->meta + npo->meta_prod++;
+               meta->gso_size = skb_shinfo(skb)->gso_size;
+               meta->size = 0;
+               meta->id = req->id;
+       }
+
        req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons++);
        meta = npo->meta + npo->meta_prod++;
-       meta->gso_size = skb_shinfo(skb)->gso_size;
+
+       if (!netif->gso_prefix)
+               meta->gso_size = skb_shinfo(skb)->gso_size;
+       else
+               meta->gso_size = 0;
+
        meta->size = 0;
        meta->id = req->id;
        npo->copy_off = 0;
@@ -506,7 +525,7 @@ static int netbk_gop_skb(struct sk_buff *skb,
                            offset_in_page(skb->data), 1);
 
        /* Leave a gap for the GSO descriptor. */
-       if (skb_shinfo(skb)->gso_size)
+       if (skb_shinfo(skb)->gso_size && !netif->gso_prefix)
                netif->rx.req_cons++;
 
        for (i = 0; i < nr_frags; i++) {
@@ -623,6 +642,21 @@ static void net_rx_action(unsigned long data)
 
                netif = netdev_priv(skb->dev);
 
+               if (netbk->meta[npo.meta_cons].gso_size && netif->gso_prefix) {
+                       resp = RING_GET_RESPONSE(&netif->rx,
+                                               netif->rx.rsp_prod_pvt++);
+
+                       resp->flags = NETRXF_gso_prefix | NETRXF_more_data;
+
+                       resp->offset = netbk->meta[npo.meta_cons].gso_size;
+                       resp->id = netbk->meta[npo.meta_cons].id;
+                       resp->status = sco->meta_slots_used;
+
+                       npo.meta_cons++;
+                       sco->meta_slots_used--;
+               }
+
+
                netif->stats.tx_bytes += skb->len;
                netif->stats.tx_packets++;
 
@@ -633,6 +667,7 @@ static void net_rx_action(unsigned long data)
                        flags = 0;
                else
                        flags = NETRXF_more_data;
+
                if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */
                        flags |= NETRXF_csum_blank | NETRXF_data_validated;
                else if (skb->ip_summed == CHECKSUM_UNNECESSARY)
@@ -645,7 +680,7 @@ static void net_rx_action(unsigned long data)
                                        netbk->meta[npo.meta_cons].size,
                                        flags);
 
-               if (netbk->meta[npo.meta_cons].gso_size) {
+               if (netbk->meta[npo.meta_cons].gso_size && !netif->gso_prefix) {
                        struct xen_netif_extra_info *gso =
                                (struct xen_netif_extra_info *)
                                RING_GET_RESPONSE(&netif->rx,
diff --git a/drivers/xen/netback/xenbus.c b/drivers/xen/netback/xenbus.c
index ba7b1de..74c035b 100644
--- a/drivers/xen/netback/xenbus.c
+++ b/drivers/xen/netback/xenbus.c
@@ -465,16 +465,25 @@ static int connect_rings(struct backend_info *be)
                        be->netif->dev->mtu = ETH_DATA_LEN;
        }
 
-       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", "%d",
-                        &val) < 0)
+       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4",
+                       "%d", &val) < 0)
                val = 0;
        if (val) {
                be->netif->features |= NETIF_F_TSO;
                be->netif->dev->features |= NETIF_F_TSO;
        }
 
+       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix",
+                       "%d", &val) < 0)
+               val = 0;
+       if (val) {
+               be->netif->features |= NETIF_F_TSO;
+               be->netif->dev->features |= NETIF_F_TSO;
+               be->netif->gso_prefix = 1;
+       }
+
        if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
-                        "%d", &val) < 0)
+                       "%d", &val) < 0)
                val = 0;
        if (val) {
                be->netif->features &= ~NETIF_F_IP_CSUM;
@@ -482,7 +491,7 @@ static int connect_rings(struct backend_info *be)
        }
 
        if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-smart-poll",
-                        "%d", &val) < 0)
+                       "%d", &val) < 0)
                val = 0;
        if (val)
                be->netif->smart_poll = 1;
diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h
index 518481c..8309344 100644
--- a/include/xen/interface/io/netif.h
+++ b/include/xen/interface/io/netif.h
@@ -131,6 +131,10 @@ struct xen_netif_rx_request {
 #define _NETRXF_extra_info     (3)
 #define  NETRXF_extra_info     (1U<<_NETRXF_extra_info)
 
+/* GSO Prefix descriptor. */
+#define _NETRXF_gso_prefix     (4)
+#define  NETRXF_gso_prefix     (1U<<_NETRXF_gso_prefix)
+
 struct xen_netif_rx_response {
     uint16_t id;
     uint16_t offset;       /* Offset in page of start of received packet  */
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.