aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/xen-netback/netback.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 1844a47636b6..a773f2016bad 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1030,10 +1030,16 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
1030{ 1030{
1031 struct gnttab_map_grant_ref *gop_map = *gopp_map; 1031 struct gnttab_map_grant_ref *gop_map = *gopp_map;
1032 u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; 1032 u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
1033 /* This always points to the shinfo of the skb being checked, which
1034 * could be either the first or the one on the frag_list
1035 */
1033 struct skb_shared_info *shinfo = skb_shinfo(skb); 1036 struct skb_shared_info *shinfo = skb_shinfo(skb);
1037 /* If this is non-NULL, we are currently checking the frag_list skb, and
1038 * this points to the shinfo of the first one
1039 */
1040 struct skb_shared_info *first_shinfo = NULL;
1034 int nr_frags = shinfo->nr_frags; 1041 int nr_frags = shinfo->nr_frags;
1035 int i, err; 1042 int i, err;
1036 struct sk_buff *first_skb = NULL;
1037 1043
1038 /* Check status of header. */ 1044 /* Check status of header. */
1039 err = (*gopp_copy)->status; 1045 err = (*gopp_copy)->status;
@@ -1086,31 +1092,28 @@ check_frags:
1086 xenvif_idx_unmap(queue, pending_idx); 1092 xenvif_idx_unmap(queue, pending_idx);
1087 } 1093 }
1088 1094
1095 /* And if we found the error while checking the frag_list, unmap
1096 * the first skb's frags
1097 */
1098 if (first_shinfo) {
1099 for (j = 0; j < first_shinfo->nr_frags; j++) {
1100 pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]);
1101 xenvif_idx_unmap(queue, pending_idx);
1102 }
1103 }
1104
1089 /* Remember the error: invalidate all subsequent fragments. */ 1105 /* Remember the error: invalidate all subsequent fragments. */
1090 err = newerr; 1106 err = newerr;
1091 } 1107 }
1092 1108
1093 if (skb_has_frag_list(skb)) { 1109 if (skb_has_frag_list(skb) && !first_shinfo) {
1094 first_skb = skb; 1110 first_shinfo = skb_shinfo(skb);
1095 skb = shinfo->frag_list; 1111 shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
1096 shinfo = skb_shinfo(skb);
1097 nr_frags = shinfo->nr_frags; 1112 nr_frags = shinfo->nr_frags;
1098 1113
1099 goto check_frags; 1114 goto check_frags;
1100 } 1115 }
1101 1116
1102 /* There was a mapping error in the frag_list skb. We have to unmap
1103 * the first skb's frags
1104 */
1105 if (first_skb && err) {
1106 int j;
1107 shinfo = skb_shinfo(first_skb);
1108 for (j = 0; j < shinfo->nr_frags; j++) {
1109 pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
1110 xenvif_idx_unmap(queue, pending_idx);
1111 }
1112 }
1113
1114 *gopp_map = gop_map; 1117 *gopp_map = gop_map;
1115 return err; 1118 return err;
1116} 1119}