diff options
Diffstat (limited to 'drivers/net/xen-netback/netback.c')
-rw-r--r-- | drivers/net/xen-netback/netback.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 880d0d63e872..3f44b522b831 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -810,23 +810,17 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size) | |||
810 | static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue, | 810 | static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue, |
811 | struct sk_buff *skb, | 811 | struct sk_buff *skb, |
812 | struct xen_netif_tx_request *txp, | 812 | struct xen_netif_tx_request *txp, |
813 | struct gnttab_map_grant_ref *gop) | 813 | struct gnttab_map_grant_ref *gop, |
814 | unsigned int frag_overflow, | ||
815 | struct sk_buff *nskb) | ||
814 | { | 816 | { |
815 | struct skb_shared_info *shinfo = skb_shinfo(skb); | 817 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
816 | skb_frag_t *frags = shinfo->frags; | 818 | skb_frag_t *frags = shinfo->frags; |
817 | u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; | 819 | u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; |
818 | int start; | 820 | int start; |
819 | pending_ring_idx_t index; | 821 | pending_ring_idx_t index; |
820 | unsigned int nr_slots, frag_overflow = 0; | 822 | unsigned int nr_slots; |
821 | 823 | ||
822 | /* At this point shinfo->nr_frags is in fact the number of | ||
823 | * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX. | ||
824 | */ | ||
825 | if (shinfo->nr_frags > MAX_SKB_FRAGS) { | ||
826 | frag_overflow = shinfo->nr_frags - MAX_SKB_FRAGS; | ||
827 | BUG_ON(frag_overflow > MAX_SKB_FRAGS); | ||
828 | shinfo->nr_frags = MAX_SKB_FRAGS; | ||
829 | } | ||
830 | nr_slots = shinfo->nr_frags; | 824 | nr_slots = shinfo->nr_frags; |
831 | 825 | ||
832 | /* Skip first skb fragment if it is on same page as header fragment. */ | 826 | /* Skip first skb fragment if it is on same page as header fragment. */ |
@@ -841,13 +835,6 @@ static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *que | |||
841 | } | 835 | } |
842 | 836 | ||
843 | if (frag_overflow) { | 837 | if (frag_overflow) { |
844 | struct sk_buff *nskb = xenvif_alloc_skb(0); | ||
845 | if (unlikely(nskb == NULL)) { | ||
846 | if (net_ratelimit()) | ||
847 | netdev_err(queue->vif->dev, | ||
848 | "Can't allocate the frag_list skb.\n"); | ||
849 | return NULL; | ||
850 | } | ||
851 | 838 | ||
852 | shinfo = skb_shinfo(nskb); | 839 | shinfo = skb_shinfo(nskb); |
853 | frags = shinfo->frags; | 840 | frags = shinfo->frags; |
@@ -1175,9 +1162,10 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1175 | unsigned *copy_ops, | 1162 | unsigned *copy_ops, |
1176 | unsigned *map_ops) | 1163 | unsigned *map_ops) |
1177 | { | 1164 | { |
1178 | struct gnttab_map_grant_ref *gop = queue->tx_map_ops, *request_gop; | 1165 | struct gnttab_map_grant_ref *gop = queue->tx_map_ops; |
1179 | struct sk_buff *skb; | 1166 | struct sk_buff *skb, *nskb; |
1180 | int ret; | 1167 | int ret; |
1168 | unsigned int frag_overflow; | ||
1181 | 1169 | ||
1182 | while (skb_queue_len(&queue->tx_queue) < budget) { | 1170 | while (skb_queue_len(&queue->tx_queue) < budget) { |
1183 | struct xen_netif_tx_request txreq; | 1171 | struct xen_netif_tx_request txreq; |
@@ -1265,6 +1253,29 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1265 | break; | 1253 | break; |
1266 | } | 1254 | } |
1267 | 1255 | ||
1256 | skb_shinfo(skb)->nr_frags = ret; | ||
1257 | if (data_len < txreq.size) | ||
1258 | skb_shinfo(skb)->nr_frags++; | ||
1259 | /* At this point shinfo->nr_frags is in fact the number of | ||
1260 | * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX. | ||
1261 | */ | ||
1262 | frag_overflow = 0; | ||
1263 | nskb = NULL; | ||
1264 | if (skb_shinfo(skb)->nr_frags > MAX_SKB_FRAGS) { | ||
1265 | frag_overflow = skb_shinfo(skb)->nr_frags - MAX_SKB_FRAGS; | ||
1266 | BUG_ON(frag_overflow > MAX_SKB_FRAGS); | ||
1267 | skb_shinfo(skb)->nr_frags = MAX_SKB_FRAGS; | ||
1268 | nskb = xenvif_alloc_skb(0); | ||
1269 | if (unlikely(nskb == NULL)) { | ||
1270 | kfree_skb(skb); | ||
1271 | xenvif_tx_err(queue, &txreq, idx); | ||
1272 | if (net_ratelimit()) | ||
1273 | netdev_err(queue->vif->dev, | ||
1274 | "Can't allocate the frag_list skb.\n"); | ||
1275 | break; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1268 | if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { | 1279 | if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { |
1269 | struct xen_netif_extra_info *gso; | 1280 | struct xen_netif_extra_info *gso; |
1270 | gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; | 1281 | gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; |
@@ -1272,6 +1283,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1272 | if (xenvif_set_skb_gso(queue->vif, skb, gso)) { | 1283 | if (xenvif_set_skb_gso(queue->vif, skb, gso)) { |
1273 | /* Failure in xenvif_set_skb_gso is fatal. */ | 1284 | /* Failure in xenvif_set_skb_gso is fatal. */ |
1274 | kfree_skb(skb); | 1285 | kfree_skb(skb); |
1286 | kfree_skb(nskb); | ||
1275 | break; | 1287 | break; |
1276 | } | 1288 | } |
1277 | } | 1289 | } |
@@ -1294,9 +1306,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1294 | 1306 | ||
1295 | (*copy_ops)++; | 1307 | (*copy_ops)++; |
1296 | 1308 | ||
1297 | skb_shinfo(skb)->nr_frags = ret; | ||
1298 | if (data_len < txreq.size) { | 1309 | if (data_len < txreq.size) { |
1299 | skb_shinfo(skb)->nr_frags++; | ||
1300 | frag_set_pending_idx(&skb_shinfo(skb)->frags[0], | 1310 | frag_set_pending_idx(&skb_shinfo(skb)->frags[0], |
1301 | pending_idx); | 1311 | pending_idx); |
1302 | xenvif_tx_create_map_op(queue, pending_idx, &txreq, gop); | 1312 | xenvif_tx_create_map_op(queue, pending_idx, &txreq, gop); |
@@ -1310,13 +1320,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, | |||
1310 | 1320 | ||
1311 | queue->pending_cons++; | 1321 | queue->pending_cons++; |
1312 | 1322 | ||
1313 | request_gop = xenvif_get_requests(queue, skb, txfrags, gop); | 1323 | gop = xenvif_get_requests(queue, skb, txfrags, gop, |
1314 | if (request_gop == NULL) { | 1324 | frag_overflow, nskb); |
1315 | kfree_skb(skb); | ||
1316 | xenvif_tx_err(queue, &txreq, idx); | ||
1317 | break; | ||
1318 | } | ||
1319 | gop = request_gop; | ||
1320 | 1325 | ||
1321 | __skb_queue_tail(&queue->tx_queue, skb); | 1326 | __skb_queue_tail(&queue->tx_queue, skb); |
1322 | 1327 | ||
@@ -1536,7 +1541,6 @@ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success) | |||
1536 | smp_wmb(); | 1541 | smp_wmb(); |
1537 | queue->dealloc_prod++; | 1542 | queue->dealloc_prod++; |
1538 | } while (ubuf); | 1543 | } while (ubuf); |
1539 | wake_up(&queue->dealloc_wq); | ||
1540 | spin_unlock_irqrestore(&queue->callback_lock, flags); | 1544 | spin_unlock_irqrestore(&queue->callback_lock, flags); |
1541 | 1545 | ||
1542 | if (likely(zerocopy_success)) | 1546 | if (likely(zerocopy_success)) |
@@ -1566,13 +1570,13 @@ static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue) | |||
1566 | smp_rmb(); | 1570 | smp_rmb(); |
1567 | 1571 | ||
1568 | while (dc != dp) { | 1572 | while (dc != dp) { |
1569 | BUG_ON(gop - queue->tx_unmap_ops > MAX_PENDING_REQS); | 1573 | BUG_ON(gop - queue->tx_unmap_ops >= MAX_PENDING_REQS); |
1570 | pending_idx = | 1574 | pending_idx = |
1571 | queue->dealloc_ring[pending_index(dc++)]; | 1575 | queue->dealloc_ring[pending_index(dc++)]; |
1572 | 1576 | ||
1573 | pending_idx_release[gop-queue->tx_unmap_ops] = | 1577 | pending_idx_release[gop - queue->tx_unmap_ops] = |
1574 | pending_idx; | 1578 | pending_idx; |
1575 | queue->pages_to_unmap[gop-queue->tx_unmap_ops] = | 1579 | queue->pages_to_unmap[gop - queue->tx_unmap_ops] = |
1576 | queue->mmap_pages[pending_idx]; | 1580 | queue->mmap_pages[pending_idx]; |
1577 | gnttab_set_unmap_op(gop, | 1581 | gnttab_set_unmap_op(gop, |
1578 | idx_to_kaddr(queue, pending_idx), | 1582 | idx_to_kaddr(queue, pending_idx), |