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

[Xen-changelog] [linux-2.6.18-xen] netback: support multiple extra info fragments passed from frontend


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-linux-2.6.18-xen <patchbot@xxxxxxx>
  • Date: Wed, 25 May 2016 14:11:02 +0000
  • Delivery-date: Wed, 25 May 2016 14:11:09 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Paul Durrant <paul.durrant@xxxxxxxxxx>
# Date 1464185023 -7200
#      Wed May 25 16:03:43 2016 +0200
# Node ID 4437d405cfd7099ea45ac2028338990730c24be0
# Parent  d98fd9aa81eaf7b0108fc1b2bd1d7bbd248b0e81
netback: support multiple extra info fragments passed from frontend

The code does not currently support a frontend passing multiple extra info
fragments to the backend in a tx request. The xenvif_get_extras() function
handles multiple extra_info fragments but make_tx_response() assumes there
is only ever a single extra info fragment.

This patch modifies xenvif_get_extras() to pass back a count of extra
info fragments, which is then passed to make_tx_response() (after
possibly being stashed in pending_tx_info for deferred responses).

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>

Adjust for legacy netback. Clear extra_count at the end of
netbk_tx_err()'s loop body.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Committed-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r d98fd9aa81ea -r 4437d405cfd7 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed May 25 16:01:00 2016 +0200
+++ b/drivers/xen/netback/netback.c     Wed May 25 16:03:43 2016 +0200
@@ -58,7 +58,8 @@ struct netbk_tx_pending_inuse {
 static void netif_idx_release(u16 pending_idx);
 static void make_tx_response(netif_t *netif, 
                             netif_tx_request_t *txp,
-                            s8       st);
+                            s8       st,
+                            unsigned int extra_count);
 static netif_rx_response_t *make_rx_response(netif_t *netif, 
                                             u16      id, 
                                             s8       st,
@@ -120,6 +121,7 @@ static inline int netif_page_index(struc
 
 static struct pending_tx_info {
        netif_tx_request_t req;
+       unsigned int extra_count;
        netif_t *netif;
 } pending_tx_info[MAX_PENDING_REQS];
 static u16 pending_ring[MAX_PENDING_REQS];
@@ -991,7 +993,8 @@ inline static void net_tx_action_dealloc
                netif = pending_tx_info[pending_idx].netif;
 
                make_tx_response(netif, &pending_tx_info[pending_idx].req, 
-                                NETIF_RSP_OKAY);
+                                NETIF_RSP_OKAY,
+                                pending_tx_info[pending_idx].extra_count);
 
                /* Ready for next use. */
                gnttab_reset_grant_page(mmap_pages[pending_idx]);
@@ -1004,15 +1007,17 @@ inline static void net_tx_action_dealloc
        }
 }
 
-static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
+static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end,
+                        unsigned int extra_count)
 {
        RING_IDX cons = netif->tx.req_cons;
 
        do {
-               make_tx_response(netif, txp, NETIF_RSP_ERROR);
+               make_tx_response(netif, txp, NETIF_RSP_ERROR, extra_count);
                if (cons == end)
                        break;
                txp = RING_GET_REQUEST(&netif->tx, cons++);
+               extra_count = 0;
        } while (1);
        netif->tx.req_cons = cons;
        netif_schedule_work(netif);
@@ -1030,7 +1035,8 @@ static void netbk_fatal_tx_err(netif_t *
 }
 
 static int netbk_count_requests(netif_t *netif, netif_tx_request_t *first,
-                               netif_tx_request_t *txp, int work_to_do)
+                               netif_tx_request_t *txp,
+                               unsigned int extra_count, int work_to_do)
 {
        RING_IDX cons = netif->tx.req_cons;
        int frags = 0, drop_err = 0;
@@ -1086,7 +1092,7 @@ static int netbk_count_requests(netif_t 
        } while ((txp++)->flags & NETTXF_more_data);
 
        if (drop_err) {
-               netbk_tx_err(netif, first, cons + frags);
+               netbk_tx_err(netif, first, cons + frags, extra_count);
                return drop_err;
        }
 
@@ -1116,6 +1122,7 @@ static gnttab_map_grant_ref_t *netbk_get
                memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
                netif_get(netif);
                pending_tx_info[pending_idx].netif = netif;
+               pending_tx_info[pending_idx].extra_count = 0;
                frags[i].page = (void *)pending_idx;
        }
 
@@ -1129,6 +1136,7 @@ static int netbk_tx_check_mop(struct sk_
        int pending_idx = *((u16 *)skb->data);
        netif_t *netif = pending_tx_info[pending_idx].netif;
        netif_tx_request_t *txp;
+       unsigned int extra_count;
        struct skb_shared_info *shinfo = skb_shinfo(skb);
        int nr_frags = shinfo->nr_frags;
        int i, err, start;
@@ -1137,7 +1145,8 @@ static int netbk_tx_check_mop(struct sk_
        err = mop->status;
        if (unlikely(err != GNTST_okay)) {
                txp = &pending_tx_info[pending_idx].req;
-               make_tx_response(netif, txp, NETIF_RSP_ERROR);
+               extra_count = pending_tx_info[pending_idx].extra_count;
+               make_tx_response(netif, txp, NETIF_RSP_ERROR, extra_count);
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
                netif_put(netif);
        } else {
@@ -1168,7 +1177,7 @@ static int netbk_tx_check_mop(struct sk_
 
                /* Error on this fragment: respond to client with an error. */
                txp = &pending_tx_info[pending_idx].req;
-               make_tx_response(netif, txp, NETIF_RSP_ERROR);
+               make_tx_response(netif, txp, NETIF_RSP_ERROR, 0);
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
                netif_put(netif);
 
@@ -1220,8 +1229,8 @@ static void netbk_fill_frags(struct sk_b
        }
 }
 
-int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
-                    int work_to_do)
+static int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
+                           unsigned int *extra_count, int work_to_do)
 {
        struct netif_extra_info extra;
        RING_IDX cons = netif->tx.req_cons;
@@ -1237,9 +1246,12 @@ int netbk_get_extras(netif_t *netif, str
                memcpy(&extra, RING_GET_REQUEST(&netif->tx, cons),
                       sizeof(extra));
                barrier();
+
+               netif->tx.req_cons = ++cons;
+               ++*extra_count;
+
                if (unlikely(!extra.type ||
                             extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
-                       netif->tx.req_cons = ++cons;
                        printk(KERN_ERR "%s: Invalid extra type: %d\n",
                               netif->dev->name, extra.type);
                        netbk_fatal_tx_err(netif);
@@ -1247,7 +1259,6 @@ int netbk_get_extras(netif_t *netif, str
                }
 
                memcpy(&extras[extra.type - 1], &extra, sizeof(extra));
-               netif->tx.req_cons = ++cons;
        } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
 
        return work_to_do;
@@ -1300,6 +1311,8 @@ static void net_tx_action(unsigned long 
        mop = tx_map_ops;
        while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
                !list_empty(&net_schedule_list)) {
+               unsigned int extra_count = 0;
+
                /* Get a netif from the list with work to do. */
                netif = poll_net_schedule_list();
                /*
@@ -1375,14 +1388,15 @@ static void net_tx_action(unsigned long 
 
                memset(extras, 0, sizeof(extras));
                if (txreq.flags & NETTXF_extra_info) {
-                       work_to_do = netbk_get_extras(netif, extras,
+                       work_to_do = netbk_get_extras(netif, extras, 
&extra_count,
                                                      work_to_do);
                        i = netif->tx.req_cons;
                        if (unlikely(work_to_do < 0))
                                continue;
                }
 
-               ret = netbk_count_requests(netif, &txreq, txfrags, work_to_do);
+               ret = netbk_count_requests(netif, &txreq, txfrags, extra_count,
+                                          work_to_do);
                if (unlikely(ret < 0))
                        continue;
 
@@ -1390,7 +1404,7 @@ static void net_tx_action(unsigned long 
 
                if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
-                       netbk_tx_err(netif, &txreq, i);
+                       netbk_tx_err(netif, &txreq, i, extra_count);
                        continue;
                }
 
@@ -1413,7 +1427,7 @@ static void net_tx_action(unsigned long 
                                GFP_ATOMIC | __GFP_NOWARN);
                if (unlikely(skb == NULL)) {
                        DPRINTK("Can't allocate a skb in start_xmit.\n");
-                       netbk_tx_err(netif, &txreq, i);
+                       netbk_tx_err(netif, &txreq, i, extra_count);
                        break;
                }
 
@@ -1439,6 +1453,7 @@ static void net_tx_action(unsigned long 
                memcpy(&pending_tx_info[pending_idx].req,
                       &txreq, sizeof(txreq));
                pending_tx_info[pending_idx].netif = netif;
+               pending_tx_info[pending_idx].extra_count = extra_count;
                *((u16 *)skb->data) = pending_idx;
 
                __skb_put(skb, data_len);
@@ -1598,7 +1613,8 @@ irqreturn_t netif_be_int(int irq, void *
 
 static void make_tx_response(netif_t *netif, 
                             netif_tx_request_t *txp,
-                            s8       st)
+                            s8 st,
+                            unsigned int extra_count)
 {
        RING_IDX i = netif->tx.rsp_prod_pvt;
        netif_tx_response_t *resp;
@@ -1608,7 +1624,7 @@ static void make_tx_response(netif_t *ne
        resp->id     = txp->id;
        resp->status = st;
 
-       if (txp->flags & NETTXF_extra_info)
+       while (extra_count--)
                RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
 
        netif->tx.rsp_prod_pvt = ++i;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

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