On Fri, 2011-02-04 at 10:12 +0000, Jean Baptiste Favre wrote:
> Hello Ian,
> Applyed your patches.
Thanks.
> Now, I've:
> # ping -s86 10.0.0.1
> PING 10.0.0.1 (10.0.0.1): 86 data bytes
> __netif_receive_skb dropping skb proto 0x20
>
>
> So problem seems to occur in net/core/dev.c file, according to the patch
> bellow
Interesting. the number printed in the warning is type == skb->protocol
== 0x20 which is not a valid protocol that I can find anywhere (nor is
0x2000 in case I'm mixing my endianesses up). Neither is 0x20 it a valid
Ethernet frame length (min 64) so it's not that sort of confusion
AFAICT.
skb->protocol is initialised in sky2_status_intr with the return value
of "eth_type_trans(skb, dev)" which as far as I can tell cannot return
0x20.
The domU network configuration is using the sky2 device directly, no
bridging, VLAN, tunnels or anything else like that?
Please can you post the output of "ethtool -k <sky2-device>".
If either tx or rx checksumming are enabled please can you try disabling
them ("ethtool -K <sky2-device> [tx|rx] off"). This setting controls the
code path in sky2_skb_rx which can go either to netif_receive_skb or
napi_gro_receive.
The tcpdump captures from both ends would still be interesting to see.
The following patch enhances the previous one with a few checks for
protocol 0x20 getting set.
Ian.
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7d85a38..727922f 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2339,6 +2339,7 @@ static struct sk_buff *receive_copy(struct sky2_port
*sky2,
re->skb->ip_summed = CHECKSUM_NONE;
skb_put(skb, length);
}
+ WARN(skb == NULL, "sky2: receive_copy failed netdev_alloc_skb_ip_align
length %u\n", length);
return skb;
}
@@ -2386,10 +2387,15 @@ static struct sk_buff *receive_new(struct sky2_port
*sky2,
nre.skb = sky2_rx_alloc(sky2);
if (unlikely(!nre.skb))
+ {
+ WARN(1, "sky2: receive_new failed sky2_rx_alloc\n");
goto nobuf;
-
+ }
if (sky2_rx_map_skb(sky2->hw->pdev, &nre, hdr_space))
+ {
+ WARN(1, "sky2: receive_new failed sky2_rx_map_skb\n");
goto nomap;
+ }
skb = re->skb;
sky2_rx_unmap_skb(sky2->hw->pdev, re);
@@ -2600,6 +2606,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int
to_do, u16 idx)
}
skb->protocol = eth_type_trans(skb, dev);
+ WARN_ONCE(skb->protocol == 0x20, "sky2_status_intr:
skb->protocol is 0x20. ip_summed is %d\n", skb->ip_summed);
sky2_skb_rx(sky2, status, skb);
diff --git a/net/core/dev.c b/net/core/dev.c
index 54277df..5d786b6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1516,6 +1516,7 @@ int dev_forward_skb(struct net_device *dev, struct
sk_buff *skb)
if (unlikely(!(dev->flags & IFF_UP) ||
(skb->len > (dev->mtu + dev->hard_header_len +
VLAN_HLEN)))) {
+ printk(KERN_CRIT "dev_forward_skb dropping skb\n");
atomic_long_inc(&dev->rx_dropped);
kfree_skb(skb);
return NET_RX_DROP;
@@ -1524,6 +1525,7 @@ int dev_forward_skb(struct net_device *dev, struct
sk_buff *skb)
skb->tstamp.tv64 = 0;
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, dev);
+ WARN_ONCE(skb->protocol == 0x20, "dev_forward_skb protocol 0x20
ip_summed %d\n", skb->ip_summed);
return netif_rx(skb);
}
EXPORT_SYMBOL_GPL(dev_forward_skb);
@@ -2700,6 +2702,7 @@ enqueue:
local_irq_restore(flags);
+ printk(KERN_CRIT "enqueue_to_backlog dropping skb\n");
atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
return NET_RX_DROP;
@@ -3010,6 +3013,8 @@ static int __netif_receive_skb(struct sk_buff *skb)
int ret = NET_RX_DROP;
__be16 type;
+ WARN_ONCE(type == 0x20, "__netif_receive_skb protocol 0x20 ip summed %d
at line %d\n", skb->ip_summed, __LINE__);
+
if (!netdev_tstamp_prequeue)
net_timestamp_check(skb);
@@ -3111,6 +3116,7 @@ ncls:
}
type = skb->protocol;
+ WARN_ONCE(type == 0x20, "__netif_receive_skb protocol 0x20 ip summed %d
at line %d\n", skb->ip_summed, __LINE__);
list_for_each_entry_rcu(ptype,
&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
if (ptype->type == type && (ptype->dev == null_or_orig ||
@@ -3125,6 +3131,7 @@ ncls:
if (pt_prev) {
ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
} else {
+ printk(KERN_CRIT "__netif_receive_skb dropping skb proto %#x ip
summed %d\n", type, skb->ip_summed);
atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
/* Jamal, now you will not able to escape explaining
@@ -3447,6 +3454,7 @@ gro_result_t napi_frags_finish(struct napi_struct *napi,
struct sk_buff *skb,
case GRO_NORMAL:
case GRO_HELD:
skb->protocol = eth_type_trans(skb, skb->dev);
+ WARN_ONCE(skb->protocol == 0x20, "napi_frags_finish protocol
0x20 ip_summed %d\n", skb->ip_summed);
if (ret == GRO_HELD)
skb_gro_pull(skb, -ETH_HLEN);
@@ -3498,6 +3506,7 @@ struct sk_buff *napi_frags_skb(struct napi_struct *napi)
* special handling. We'll fix it up properly at the end.
*/
skb->protocol = eth->h_proto;
+ WARN_ONCE(skb->protocol == 0x20, "napi_frags_skb protocol 0x20
ip_summed %d\n", skb->ip_summed);
out:
return skb;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|