diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b9de31e..1809728 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -122,9 +122,13 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON(skb->dev != dev); /* Drop the packet if vif is not ready */ - if (vif->task == NULL || !xenvif_schedulable(vif)) + if (vif->task == NULL || !xenvif_schedulable(vif)){ + if (net_ratelimit()) + netdev_warn(vif->dev, "?!? %s dropping packet vif not ready ! min_slots_needed:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d\n", __FUNCTION__, min_slots_needed, vif->rx.sring->req_prod, vif->rx.req_cons); + goto drop; - + } + /* At best we'll need one slot for the header and one for each * frag. */ @@ -133,16 +137,19 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) /* If the skb is GSO then we'll also need an extra slot for the * metadata. */ - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || - skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso(skb)) min_slots_needed++; /* If the skb can't possibly fit in the remaining slots * then turn off the queue to give the ring a chance to * drain. */ - if (!xenvif_rx_ring_slots_available(vif, min_slots_needed)) + if (!xenvif_rx_ring_slots_available(vif, min_slots_needed)){ + if (net_ratelimit()) + netdev_warn(vif->dev, "?!? %s stopping queue ! min_slots_needed:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d\n", __FUNCTION__, min_slots_needed, vif->rx.sring->req_prod, vif->rx.req_cons); + xenvif_stop_queue(vif); + } skb_queue_tail(&vif->rx_queue, skb); xenvif_kick_thread(vif); diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 98de8ab..2f86a63 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -157,6 +157,8 @@ bool xenvif_rx_ring_slots_available(struct xenvif *vif, int needed) mb(); } while (vif->rx.sring->req_prod != prod); + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s slotsavailable: false vif->rx.sring->req_prod:%d vif->rx.req_cons:%d vif->rx.sring->req_event:%d needed:%d",__FUNCTION__, vif->rx.sring->req_prod, vif->rx.req_cons, vif->rx.sring->req_event, needed);} + return false; } @@ -215,7 +217,9 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif, struct xenvif_rx_meta *meta; struct xen_netif_rx_request *req; + if((vif->rx.req_cons + 1 > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s before req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d", __FUNCTION__, npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons + 1);} req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s after req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d req->gref:%d req->id:%d", __FUNCTION__, npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons, req->gref, req->id);} meta = npo->meta + npo->meta_prod++; meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; @@ -241,7 +245,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, struct gnttab_copy *copy_gop; struct xenvif_rx_meta *meta; unsigned long bytes; - int gso_type; + int gso_type = XEN_NETIF_GSO_TYPE_NONE; /* Data must not cross a page boundary. */ BUG_ON(size + offset > PAGE_SIZE<rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 1 npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d npo->copy_gref:%d", __FUNCTION__,npo->meta_prod, vif->rx.sring->req_prod, vif->rx.req_cons, npo->copy_gref);} meta = get_next_rx_buffer(vif, npo); + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 2 npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d npo->copy_gref:%d", __FUNCTION__,npo->meta_prod, vif->rx.sring->req_prod, vif->rx.req_cons, npo->copy_gref);} + } if (npo->copy_off + bytes > MAX_BUFFER_OFFSET) @@ -300,16 +306,17 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, } /* Leave a gap for the GSO descriptor. */ - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) - gso_type = XEN_NETIF_GSO_TYPE_TCPV4; - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) - gso_type = XEN_NETIF_GSO_TYPE_TCPV6; - else - gso_type = XEN_NETIF_GSO_TYPE_NONE; + if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + gso_type = XEN_NETIF_GSO_TYPE_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + gso_type = XEN_NETIF_GSO_TYPE_TCPV6; + } - if (*head && ((1 << gso_type) & vif->gso_mask)) + if (*head && ((1 << gso_type) & vif->gso_mask)){ vif->rx.req_cons++; - + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 3 npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d npo->copy_gref:%d", __FUNCTION__,npo->meta_prod, vif->rx.sring->req_prod, vif->rx.req_cons, skb_shinfo(skb)->gso_type, npo->copy_gref);} + } *head = 0; /* There must be something in this buffer now. */ } @@ -339,37 +346,37 @@ static int xenvif_gop_skb(struct sk_buff *skb, int head = 1; int old_meta_prod; int gso_type; - int gso_size; old_meta_prod = npo->meta_prod; - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { - gso_type = XEN_NETIF_GSO_TYPE_TCPV4; - gso_size = skb_shinfo(skb)->gso_size; - } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { - gso_type = XEN_NETIF_GSO_TYPE_TCPV6; - gso_size = skb_shinfo(skb)->gso_size; - } else { - gso_type = XEN_NETIF_GSO_TYPE_NONE; - gso_size = 0; + gso_type = XEN_NETIF_GSO_TYPE_NONE; + if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + gso_type = XEN_NETIF_GSO_TYPE_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + gso_type = XEN_NETIF_GSO_TYPE_TCPV6; } /* Set up a GSO prefix descriptor, if necessary */ if ((1 << gso_type) & vif->gso_prefix_mask) { + if((vif->rx.req_cons + 1 > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 1 before req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d gso_size:%d nr_frags:%d", __FUNCTION__,npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons + 1, skb_shinfo(skb)->gso_type, skb_shinfo(skb)->gso_size, nr_frags);} req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 1 after req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d gso_size:%d nr_frags:%d req->gref:%d req->id:%d", __FUNCTION__,npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons , skb_shinfo(skb)->gso_type, skb_shinfo(skb)->gso_size, nr_frags, req->gref, req->id);} meta = npo->meta + npo->meta_prod++; meta->gso_type = gso_type; - meta->gso_size = gso_size; + meta->gso_size = skb_shinfo(skb)->gso_size; meta->size = 0; meta->id = req->id; } - + if((vif->rx.req_cons + 1 > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 2 before req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d gso_size:%d nr_frags:%d", __FUNCTION__,npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons + 1, skb_shinfo(skb)->gso_type, skb_shinfo(skb)->gso_size, nr_frags);} req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 2 after req npo->meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d gso_size:%d nr_frags:%d req->gref:%d req->id:%d", __FUNCTION__,npo->meta_prod , vif->rx.sring->req_prod, vif->rx.req_cons, skb_shinfo(skb)->gso_type, skb_shinfo(skb)->gso_size, nr_frags, req->gref, req->id);} + meta = npo->meta + npo->meta_prod++; if ((1 << gso_type) & vif->gso_mask) { meta->gso_type = gso_type; - meta->gso_size = gso_size; + meta->gso_size = skb_shinfo(skb)->gso_size; } else { meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; meta->gso_size = 0; @@ -380,6 +387,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, npo->copy_off = 0; npo->copy_gref = req->gref; + data = skb->data; while (data < skb_tail_pointer(skb)) { unsigned int offset = offset_in_page(data); @@ -401,6 +409,8 @@ static int xenvif_gop_skb(struct sk_buff *skb, &head); } + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s Me here 3 npo->meta_prod:%d old_meta_prod:%d vif->rx.sring->req_prod:%d vif->rx.req_cons:%d gso_type:%d gso_size:%d nr_frags:%d req->gref:%d req->id:%d", __FUNCTION__,npo->meta_prod , old_meta_prod,vif->rx.sring->req_prod, vif->rx.req_cons, skb_shinfo(skb)->gso_type, skb_shinfo(skb)->gso_size, nr_frags, req->gref, req->id);} + return npo->meta_prod - old_meta_prod; } @@ -420,11 +430,14 @@ static int xenvif_check_gop(struct xenvif *vif, int nr_meta_slots, for (i = 0; i < nr_meta_slots; i++) { copy_op = npo->copy + npo->copy_cons++; if (copy_op->status != GNTST_okay) { - netdev_dbg(vif->dev, + if (net_ratelimit()){ + netdev_warn(vif->dev, "Bad status %d from copy to DOM%d.\n", copy_op->status, vif->domid); status = XEN_NETIF_RSP_ERROR; - } + netdev_warn(vif->dev, "?!? %s status err? status:%d i:%d nr_meta_slots:%d copy_op->status:%d npo->copy_cons:%d \n", __FUNCTION__,status, i, nr_meta_slots, copy_op->status, npo->copy_cons ); + } + } } return status; @@ -451,8 +464,14 @@ static void xenvif_add_frag_responses(struct xenvif *vif, int status, flags = XEN_NETRXF_more_data; offset = 0; + + if(status > 10000 || status < 0){ + if (net_ratelimit()) + netdev_warn(vif->dev, "?!? %s status err? status:%d i:%d nr_meta_slots:%d flags:%d size:%d\n", __FUNCTION__,status, i, nr_meta_slots, flags, meta[i].size); + } make_rx_response(vif, meta[i].id, status, offset, meta[i].size, flags); + } } @@ -501,12 +520,15 @@ static void xenvif_rx_action(struct xenvif *vif) size = skb_frag_size(&skb_shinfo(skb)->frags[i]); max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE); } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || - skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso(skb) && + (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || + skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) max_slots_needed++; /* If the skb may not fit then bail out now */ if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { + + skb_queue_head(&vif->rx_queue, skb); need_to_notify = 1; break; @@ -514,6 +536,9 @@ static void xenvif_rx_action(struct xenvif *vif) sco = (struct skb_cb_overlay *)skb->cb; sco->meta_slots_used = xenvif_gop_skb(skb, &npo); + + + BUG_ON(sco->meta_slots_used > max_slots_needed); __skb_queue_tail(&rxq, skb); @@ -521,8 +546,10 @@ static void xenvif_rx_action(struct xenvif *vif) BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); - if (!npo.copy_prod) + if (!npo.copy_prod){ + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s go to done .. vif->rx.sring->req_prod:%d vif->rx.req_cons:%d", __FUNCTION__, vif->rx.sring->req_prod, vif->rx.req_cons);} goto done; + } BUG_ON(npo.copy_prod > MAX_GRANT_COPY_OPS); gnttab_batch_copy(vif->grant_copy_op, npo.copy_prod); @@ -551,6 +578,8 @@ static void xenvif_rx_action(struct xenvif *vif) status = xenvif_check_gop(vif, sco->meta_slots_used, &npo); + + if (sco->meta_slots_used == 1) flags = 0; else @@ -563,6 +592,12 @@ static void xenvif_rx_action(struct xenvif *vif) flags |= XEN_NETRXF_data_validated; offset = 0; + + if(status > 10000 || status < 0){ + if (net_ratelimit()) + netdev_warn(vif->dev, "?!? %s status err? status:%d meta_slots_used:%d flags:%d size:%d ip_summed:%d is_gso:%d skb_shinfo(skb)->gso_type:%d vif->meta[npo.meta_cons].gso_type:%d nr_frags:%d npo.copy_prod:%d, npo.meta_cons:%d\n", __FUNCTION__,status, sco->meta_slots_used, flags, skb_is_gso(skb) , skb_shinfo(skb)->gso_type, vif->meta[npo.meta_cons].gso_type, vif->meta[npo.meta_cons].size, skb->ip_summed, skb_shinfo(skb)->nr_frags , npo.copy_prod, npo.meta_cons); + } + resp = make_rx_response(vif, vif->meta[npo.meta_cons].id, status, offset, vif->meta[npo.meta_cons].size, @@ -600,8 +635,10 @@ static void xenvif_rx_action(struct xenvif *vif) } done: - if (need_to_notify) + if (need_to_notify){ + if((vif->rx.req_cons > vif->rx.sring->req_prod) && net_ratelimit()){netdev_warn(vif->dev, "?!? %s need to notify .. vif->rx.sring->req_prod:%d vif->rx.req_cons:%d", __FUNCTION__, vif->rx.sring->req_prod, vif->rx.req_cons);} notify_remote_via_irq(vif->rx_irq); + } } void xenvif_check_rx_xenvif(struct xenvif *vif) @@ -705,7 +742,7 @@ static int xenvif_count_requests(struct xenvif *vif, */ if (!drop_err && slots >= XEN_NETBK_LEGACY_SLOTS_MAX) { if (net_ratelimit()) - netdev_dbg(vif->dev, + netdev_warn(vif->dev, "Too many slots (%d) exceeding limit (%d), dropping packet\n", slots, XEN_NETBK_LEGACY_SLOTS_MAX); drop_err = -E2BIG; @@ -713,7 +750,6 @@ static int xenvif_count_requests(struct xenvif *vif, if (drop_err) txp = &dropped_tx; - memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots), sizeof(*txp)); @@ -728,7 +764,7 @@ static int xenvif_count_requests(struct xenvif *vif, */ if (!drop_err && txp->size > first->size) { if (net_ratelimit()) - netdev_dbg(vif->dev, + netdev_warn(vif->dev, "Invalid tx request, slot size %u > remaining size %u\n", txp->size, first->size); drop_err = -EIO; @@ -823,6 +859,12 @@ static struct gnttab_copy *xenvif_get_requests(struct xenvif *vif, gop->dest.offset = dst_offset; gop->dest.u.gmfn = virt_to_mfn(page_address(page)); + if(txp->gref > 10000 || txp->gref <=0){ + if (net_ratelimit()) + netdev_warn(vif->dev, "?!? %s ref out of bounds? gref:%d srcdomid:%d dstdomid:%d slot:%d nr_slots:%d\n",__FUNCTION__, txp->gref, vif->domid, DOMID_SELF, slot, nr_slots); + } + + if (dst_offset + txp->size > PAGE_SIZE) { /* This page can only merge a portion * of tx request. Do not increment any @@ -1000,7 +1042,6 @@ static int xenvif_get_extras(struct xenvif *vif, xenvif_fatal_tx_err(vif); return -EBADR; } - memcpy(&extra, RING_GET_REQUEST(&vif->tx, cons), sizeof(extra)); if (unlikely(!extra.type || @@ -1393,6 +1434,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) break; idx = vif->tx.req_cons; + rmb(); /* Ensure that we see the request before we copy it. */ memcpy(&txreq, RING_GET_REQUEST(&vif->tx, idx), sizeof(txreq)); @@ -1422,8 +1464,9 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) idx += ret; if (unlikely(txreq.size < ETH_HLEN)) { - netdev_dbg(vif->dev, - "Bad packet size: %d\n", txreq.size); + if (net_ratelimit()) + netdev_warn(vif->dev, + "Bad packet size: %d\n", txreq.size); xenvif_tx_err(vif, &txreq, idx); break; } @@ -1448,8 +1491,9 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) skb = alloc_skb(data_len + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC | __GFP_NOWARN); if (unlikely(skb == NULL)) { - netdev_dbg(vif->dev, - "Can't allocate a skb in start_xmit.\n"); + if (net_ratelimit()) + netdev_warn(vif->dev, + "Can't allocate a skb in start_xmit.\n"); xenvif_tx_err(vif, &txreq, idx); break; } @@ -1544,7 +1588,8 @@ static int xenvif_tx_submit(struct xenvif *vif) /* Check the remap error code. */ if (unlikely(xenvif_tx_check_gop(vif, skb, &gop))) { - netdev_dbg(vif->dev, "netback grant failed.\n"); + if (net_ratelimit()) + netdev_warn(vif->dev, "netback grant failed.\n"); skb_shinfo(skb)->nr_frags = 0; kfree_skb(skb); continue; @@ -1581,8 +1626,9 @@ static int xenvif_tx_submit(struct xenvif *vif) skb_reset_network_header(skb); if (checksum_setup(vif, skb)) { - netdev_dbg(vif->dev, - "Can't setup checksum in net_tx_action\n"); + if (net_ratelimit()) + netdev_warn(vif->dev, + "Can't setup checksum in net_tx_action\n"); kfree_skb(skb); continue; }