* [PATCH 2/2] virtio_net: Defer skb allocation in receive path Date: Wed, 13 Jan 2010 12:53:38 -0800
From: Rusty Russell @ 2010-01-29 13:20 UTC (permalink / raw)
To: netdev; +Cc: David Miller, virtualization, Shirley Ma, Michael S. Tsirkin
In-Reply-To: <201001292349.05360.rusty@rustcorp.com.au>
From: Shirley Ma <mashirle@us.ibm.com>
virtio_net receives packets from its pre-allocated vring buffers, then it
delivers these packets to upper layer protocols as skb buffs. So it's not
necessary to pre-allocate skb for each mergable buffer, then frees extra
skbs when buffers are merged into a large packet. This patch has deferred
skb allocation in receiving packets for both big packets and mergeable buffers
to reduce skb pre-allocations and skb frees. It frees unused buffers by calling
detach_unused_buf in vring, so recv skb queue is not needed.
Signed-off-by: Shirley Ma <xma@us.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
drivers/net/virtio_net.c | 427 +++++++++++++++++++++++++++--------------------
1 file changed, 248 insertions(+), 179 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c708ecc..72b3f21 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -56,8 +56,7 @@ struct virtnet_info
/* Host will merge rx buffers for big packets (shake it! shake it!) */
bool mergeable_rx_bufs;
- /* Receive & send queues. */
- struct sk_buff_head recv;
+ /* Send queue. */
struct sk_buff_head send;
/* Work struct for refilling if we run low on memory. */
@@ -75,34 +74,44 @@ struct skb_vnet_hdr {
unsigned int num_sg;
};
+struct padded_vnet_hdr {
+ struct virtio_net_hdr hdr;
+ /*
+ * virtio_net_hdr should be in a separated sg buffer because of a
+ * QEMU bug, and data sg buffer shares same page with this header sg.
+ * This padding makes next sg 16 byte aligned after virtio_net_hdr.
+ */
+ char padding[6];
+};
+
static inline struct skb_vnet_hdr *skb_vnet_hdr(struct sk_buff *skb)
{
return (struct skb_vnet_hdr *)skb->cb;
}
-static void give_a_page(struct virtnet_info *vi, struct page *page)
-{
- page->private = (unsigned long)vi->pages;
- vi->pages = page;
-}
-
-static void trim_pages(struct virtnet_info *vi, struct sk_buff *skb)
+/*
+ * private is used to chain pages for big packets, put the whole
+ * most recent used list in the beginning for reuse
+ */
+static void give_pages(struct virtnet_info *vi, struct page *page)
{
- unsigned int i;
+ struct page *end;
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- give_a_page(vi, skb_shinfo(skb)->frags[i].page);
- skb_shinfo(skb)->nr_frags = 0;
- skb->data_len = 0;
+ /* Find end of list, sew whole thing into vi->pages. */
+ for (end = page; end->private; end = (struct page *)end->private);
+ end->private = (unsigned long)vi->pages;
+ vi->pages = page;
}
static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
{
struct page *p = vi->pages;
- if (p)
+ if (p) {
vi->pages = (struct page *)p->private;
- else
+ /* clear private here, it is used to chain pages */
+ p->private = 0;
+ } else
p = alloc_page(gfp_mask);
return p;
}
@@ -118,99 +127,142 @@ static void skb_xmit_done(struct virtqueue *svq)
netif_wake_queue(vi->dev);
}
-static void receive_skb(struct net_device *dev, struct sk_buff *skb,
- unsigned len)
+static void set_skb_frag(struct sk_buff *skb, struct page *page,
+ unsigned int offset, unsigned int *len)
{
- struct virtnet_info *vi = netdev_priv(dev);
- struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
- int err;
- int i;
-
- if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
- pr_debug("%s: short packet %i\n", dev->name, len);
- dev->stats.rx_length_errors++;
- goto drop;
- }
+ int i = skb_shinfo(skb)->nr_frags;
+ skb_frag_t *f;
+
+ f = &skb_shinfo(skb)->frags[i];
+ f->size = min((unsigned)PAGE_SIZE - offset, *len);
+ f->page_offset = offset;
+ f->page = page;
+
+ skb->data_len += f->size;
+ skb->len += f->size;
+ skb_shinfo(skb)->nr_frags++;
+ *len -= f->size;
+}
- if (vi->mergeable_rx_bufs) {
- unsigned int copy;
- char *p = page_address(skb_shinfo(skb)->frags[0].page);
+static struct sk_buff *page_to_skb(struct virtnet_info *vi,
+ struct page *page, unsigned int len)
+{
+ struct sk_buff *skb;
+ struct skb_vnet_hdr *hdr;
+ unsigned int copy, hdr_len, offset;
+ char *p;
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
- len -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
+ p = page_address(page);
- memcpy(&hdr->mhdr, p, sizeof(hdr->mhdr));
- p += sizeof(hdr->mhdr);
+ /* copy small packet so we can reuse these pages for small data */
+ skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
+ if (unlikely(!skb))
+ return NULL;
- copy = len;
- if (copy > skb_tailroom(skb))
- copy = skb_tailroom(skb);
+ hdr = skb_vnet_hdr(skb);
- memcpy(skb_put(skb, copy), p, copy);
+ if (vi->mergeable_rx_bufs) {
+ hdr_len = sizeof hdr->mhdr;
+ offset = hdr_len;
+ } else {
+ hdr_len = sizeof hdr->hdr;
+ offset = sizeof(struct padded_vnet_hdr);
+ }
- len -= copy;
+ memcpy(hdr, p, hdr_len);
- if (!len) {
- give_a_page(vi, skb_shinfo(skb)->frags[0].page);
- skb_shinfo(skb)->nr_frags--;
- } else {
- skb_shinfo(skb)->frags[0].page_offset +=
- sizeof(hdr->mhdr) + copy;
- skb_shinfo(skb)->frags[0].size = len;
- skb->data_len += len;
- skb->len += len;
- }
+ len -= hdr_len;
+ p += offset;
- while (--hdr->mhdr.num_buffers) {
- struct sk_buff *nskb;
+ copy = len;
+ if (copy > skb_tailroom(skb))
+ copy = skb_tailroom(skb);
+ memcpy(skb_put(skb, copy), p, copy);
- i = skb_shinfo(skb)->nr_frags;
- if (i >= MAX_SKB_FRAGS) {
- pr_debug("%s: packet too long %d\n", dev->name,
- len);
- dev->stats.rx_length_errors++;
- goto drop;
- }
+ len -= copy;
+ offset += copy;
- nskb = vi->rvq->vq_ops->get_buf(vi->rvq, &len);
- if (!nskb) {
- pr_debug("%s: rx error: %d buffers missing\n",
- dev->name, hdr->mhdr.num_buffers);
- dev->stats.rx_length_errors++;
- goto drop;
- }
+ while (len) {
+ set_skb_frag(skb, page, offset, &len);
+ page = (struct page *)page->private;
+ offset = 0;
+ }
- __skb_unlink(nskb, &vi->recv);
- vi->num--;
+ if (page)
+ give_pages(vi, page);
- skb_shinfo(skb)->frags[i] = skb_shinfo(nskb)->frags[0];
- skb_shinfo(nskb)->nr_frags = 0;
- kfree_skb(nskb);
+ return skb;
+}
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
+static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb)
+{
+ struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
+ struct page *page;
+ int num_buf, i, len;
+
+ num_buf = hdr->mhdr.num_buffers;
+ while (--num_buf) {
+ i = skb_shinfo(skb)->nr_frags;
+ if (i >= MAX_SKB_FRAGS) {
+ pr_debug("%s: packet too long\n", skb->dev->name);
+ skb->dev->stats.rx_length_errors++;
+ return -EINVAL;
+ }
- skb_shinfo(skb)->frags[i].size = len;
- skb_shinfo(skb)->nr_frags++;
- skb->data_len += len;
- skb->len += len;
+ page = vi->rvq->vq_ops->get_buf(vi->rvq, &len);
+ if (!page) {
+ pr_debug("%s: rx error: %d buffers missing\n",
+ skb->dev->name, hdr->mhdr.num_buffers);
+ skb->dev->stats.rx_length_errors++;
+ return -EINVAL;
}
- } else {
- len -= sizeof(hdr->hdr);
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+
+ set_skb_frag(skb, page, 0, &len);
+
+ --vi->num;
+ }
+ return 0;
+}
+
+static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct page *page;
+ struct skb_vnet_hdr *hdr;
- if (len <= MAX_PACKET_LEN)
- trim_pages(vi, skb);
+ if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+ pr_debug("%s: short packet %i\n", dev->name, len);
+ dev->stats.rx_length_errors++;
+ if (vi->mergeable_rx_bufs || vi->big_packets)
+ give_pages(vi, buf);
+ else
+ dev_kfree_skb(buf);
+ return;
+ }
- err = pskb_trim(skb, len);
- if (err) {
- pr_debug("%s: pskb_trim failed %i %d\n", dev->name,
- len, err);
+ if (!vi->mergeable_rx_bufs && !vi->big_packets) {
+ skb = buf;
+ len -= sizeof(struct virtio_net_hdr);
+ skb_trim(skb, len);
+ } else {
+ page = buf;
+ skb = page_to_skb(vi, page, len);
+ if (unlikely(!skb)) {
dev->stats.rx_dropped++;
- goto drop;
+ give_pages(vi, page);
+ return;
}
+ if (vi->mergeable_rx_bufs)
+ if (receive_mergeable(vi, skb)) {
+ dev_kfree_skb(skb);
+ return;
+ }
}
+ hdr = skb_vnet_hdr(skb);
skb->truesize += skb->data_len;
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
@@ -267,110 +319,119 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
frame_err:
dev->stats.rx_frame_errors++;
-drop:
dev_kfree_skb(skb);
}
-static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
+static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
{
struct sk_buff *skb;
- struct scatterlist sg[2+MAX_SKB_FRAGS];
- int num, err, i;
- bool oom = false;
-
- sg_init_table(sg, 2+MAX_SKB_FRAGS);
- do {
- struct skb_vnet_hdr *hdr;
+ struct skb_vnet_hdr *hdr;
+ struct scatterlist sg[2];
+ int err;
- skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
- if (unlikely(!skb)) {
- oom = true;
- break;
- }
+ skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
+ if (unlikely(!skb))
+ return -ENOMEM;
- skb_put(skb, MAX_PACKET_LEN);
+ skb_put(skb, MAX_PACKET_LEN);
- hdr = skb_vnet_hdr(skb);
- sg_set_buf(sg, &hdr->hdr, sizeof(hdr->hdr));
+ hdr = skb_vnet_hdr(skb);
+ sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr);
- if (vi->big_packets) {
- for (i = 0; i < MAX_SKB_FRAGS; i++) {
- skb_frag_t *f = &skb_shinfo(skb)->frags[i];
- f->page = get_a_page(vi, gfp);
- if (!f->page)
- break;
+ skb_to_sgvec(skb, sg + 1, 0, skb->len);
- f->page_offset = 0;
- f->size = PAGE_SIZE;
+ err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 2, skb);
+ if (err < 0)
+ dev_kfree_skb(skb);
- skb->data_len += PAGE_SIZE;
- skb->len += PAGE_SIZE;
+ return err;
+}
- skb_shinfo(skb)->nr_frags++;
- }
+static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
+{
+ struct scatterlist sg[MAX_SKB_FRAGS + 2];
+ struct page *first, *list = NULL;
+ char *p;
+ int i, err, offset;
+
+ /* page in sg[MAX_SKB_FRAGS + 1] is list tail */
+ for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
+ first = get_a_page(vi, gfp);
+ if (!first) {
+ if (list)
+ give_pages(vi, list);
+ return -ENOMEM;
}
+ sg_set_buf(&sg[i], page_address(first), PAGE_SIZE);
- num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
- skb_queue_head(&vi->recv, skb);
+ /* chain new page in list head to match sg */
+ first->private = (unsigned long)list;
+ list = first;
+ }
- err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
- if (err < 0) {
- skb_unlink(skb, &vi->recv);
- trim_pages(vi, skb);
- kfree_skb(skb);
- break;
- }
- vi->num++;
- } while (err >= num);
- if (unlikely(vi->num > vi->max))
- vi->max = vi->num;
- vi->rvq->vq_ops->kick(vi->rvq);
- return !oom;
+ first = get_a_page(vi, gfp);
+ if (!first) {
+ give_pages(vi, list);
+ return -ENOMEM;
+ }
+ p = page_address(first);
+
+ /* sg[0], sg[1] share the same page */
+ /* a separated sg[0] for virtio_net_hdr only during to QEMU bug*/
+ sg_set_buf(&sg[0], p, sizeof(struct virtio_net_hdr));
+
+ /* sg[1] for data packet, from offset */
+ offset = sizeof(struct padded_vnet_hdr);
+ sg_set_buf(&sg[1], p + offset, PAGE_SIZE - offset);
+
+ /* chain first in list head */
+ first->private = (unsigned long)list;
+ err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2,
+ first);
+ if (err < 0)
+ give_pages(vi, first);
+
+ return err;
}
-/* Returns false if we couldn't fill entirely (OOM). */
-static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
+static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
{
- struct sk_buff *skb;
- struct scatterlist sg[1];
+ struct page *page;
+ struct scatterlist sg;
int err;
- bool oom = false;
-
- if (!vi->mergeable_rx_bufs)
- return try_fill_recv_maxbufs(vi, gfp);
- do {
- skb_frag_t *f;
+ page = get_a_page(vi, gfp);
+ if (!page)
+ return -ENOMEM;
- skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
- if (unlikely(!skb)) {
- oom = true;
- break;
- }
+ sg_init_one(&sg, page_address(page), PAGE_SIZE);
- f = &skb_shinfo(skb)->frags[0];
- f->page = get_a_page(vi, gfp);
- if (!f->page) {
- oom = true;
- kfree_skb(skb);
- break;
- }
+ err = vi->rvq->vq_ops->add_buf(vi->rvq, &sg, 0, 1, page);
+ if (err < 0)
+ give_pages(vi, page);
- f->page_offset = 0;
- f->size = PAGE_SIZE;
+ return err;
+}
- skb_shinfo(skb)->nr_frags++;
+/* Returns false if we couldn't fill entirely (OOM). */
+static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
+{
+ int err;
+ bool oom = false;
- sg_init_one(sg, page_address(f->page), PAGE_SIZE);
- skb_queue_head(&vi->recv, skb);
+ do {
+ if (vi->mergeable_rx_bufs)
+ err = add_recvbuf_mergeable(vi, gfp);
+ else if (vi->big_packets)
+ err = add_recvbuf_big(vi, gfp);
+ else
+ err = add_recvbuf_small(vi, gfp);
- err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
if (err < 0) {
- skb_unlink(skb, &vi->recv);
- kfree_skb(skb);
+ oom = true;
break;
}
- vi->num++;
+ ++vi->num;
} while (err > 0);
if (unlikely(vi->num > vi->max))
vi->max = vi->num;
@@ -408,15 +469,14 @@ static void refill_work(struct work_struct *work)
static int virtnet_poll(struct napi_struct *napi, int budget)
{
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
- struct sk_buff *skb = NULL;
+ void *buf;
unsigned int len, received = 0;
again:
while (received < budget &&
- (skb = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
- __skb_unlink(skb, &vi->recv);
- receive_skb(vi->dev, skb, len);
- vi->num--;
+ (buf = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
+ receive_buf(vi->dev, buf, len);
+ --vi->num;
received++;
}
@@ -496,9 +556,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
/* Encode metadata header at front. */
if (vi->mergeable_rx_bufs)
- sg_set_buf(sg, &hdr->mhdr, sizeof(hdr->mhdr));
+ sg_set_buf(sg, &hdr->mhdr, sizeof hdr->mhdr);
else
- sg_set_buf(sg, &hdr->hdr, sizeof(hdr->hdr));
+ sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr);
hdr->num_sg = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
return vi->svq->vq_ops->add_buf(vi->svq, sg, hdr->num_sg, 0, skb);
@@ -916,8 +976,7 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->features |= NETIF_F_HW_VLAN_FILTER;
}
- /* Initialize our empty receive and send queues. */
- skb_queue_head_init(&vi->recv);
+ /* Initialize our empty send queue. */
skb_queue_head_init(&vi->send);
err = register_netdev(dev);
@@ -952,25 +1011,35 @@ free:
return err;
}
+static void free_unused_bufs(struct virtnet_info *vi)
+{
+ void *buf;
+ while (1) {
+ buf = vi->rvq->vq_ops->detach_unused_buf(vi->rvq);
+ if (!buf)
+ break;
+ if (vi->mergeable_rx_bufs || vi->big_packets)
+ give_pages(vi, buf);
+ else
+ dev_kfree_skb(buf);
+ --vi->num;
+ }
+ BUG_ON(vi->num != 0);
+}
+
static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
- struct sk_buff *skb;
/* Stop all the virtqueues. */
vdev->config->reset(vdev);
- /* Free our skbs in send and recv queues, if any. */
- while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
- kfree_skb(skb);
- vi->num--;
- }
+ /* Free our skbs in send queue, if any. */
__skb_queue_purge(&vi->send);
- BUG_ON(vi->num != 0);
-
unregister_netdev(vi->dev);
cancel_delayed_work_sync(&vi->refill);
+ free_unused_bufs(vi);
vdev->config->del_vqs(vi->vdev);
^ permalink raw reply related
* Re: fwmark based routing stopped working in 2.6.32
From: Patrick McHardy @ 2010-01-29 13:21 UTC (permalink / raw)
To: Nebojsa Trpkovic; +Cc: linux-net, Linux Netdev List
In-Reply-To: <4B62DF02.4010405@trpkovic.com>
[-- Attachment #1: Type: text/plain, Size: 4387 bytes --]
Nebojsa Trpkovic wrote:
> hello.
>
> I have two ADSL links on eth2 and eth3.
>
> ADSL1 (eth2) with IP 10.5.18.18 is default gateway in main routing table.
>
> ADSL2 (eth3) with IP 10.5.18.22 is used just for marked packets:
> ###################################################
> #!/bin/bash
> ip route add default via 10.5.18.22 dev eth3 table 20
> ip rule add fwmark 0x351 table 20
> ip rule add fwmark 0x352 table 20
> ip rule add fwmark 0x353 table 20
> ip route flush cache
> ###################################################
>
> everything worked fine for years using kernels 2.6.24 and 2.6.29.
> recently I upgraded to 2.6.32-r2 and traffic through ADSL2 stopped.
>
> the moment I delete table 20 and ip rules, everything works fine:
> I can set both ADSL1 or ADSL2 as default gateway and they will work.
>
> again, the moment I start making routing decision considering firewall
> marks, I get traffic only on ADSL1 (main table default gw) interface.
>
> I've found out that when I mark ICMP protocol with 0x351 fwmark and try
> too ping something, ping packets are sent via eth3 indeed:
> iptraf detailed eth3 statistics shows that there are constatnly outgoing
> ICMP packages.
>
> even more interesting is fact that there is exactly the same number of
> incoming ICMP packages, but my ping output is empty:
> there is no "Destination Host Unreachable" or similar - nothing.
>
> this leeds me to believe that ICMP packages are routed right, I receive
> some answer, but those answer packages are discarded.
>
> so, I've flushed all firewall rules except marking for ICMP, and added
> explicit
> ###################################################
> iptables -t mangle -A OUTPUT -p ICMP -j MARK --set-mark 0x351
> ###################################################
> that didn't help.
>
> I've added explicit rule
> ###################################################
> iptables -I INPUT -i eth3 -j ACCEPT
> ###################################################
> that didn't help.
>
> I've checked, and my source route verification is turned off for these
> ifaces:
> ###################################################
> etc # sysctl net.ipv4.conf.default.rp_filter
> net.ipv4.conf.default.rp_filter = 1
> etc # sysctl net.ipv4.conf.eth2.rp_filter
> net.ipv4.conf.eth2.rp_filter = 0
> etc # sysctl net.ipv4.conf.eth3.rp_filter
> net.ipv4.conf.eth3.rp_filter = 0
> ###################################################
> changing that to "=1" doesn't solve the problem.
>
> tcpdump on eth3 after 3 pings to 216.239.34.10
> ###################################################
> ping -I eth3 -c3 216.239.34.10
> PING 216.239.34.10 (216.239.34.10) from 10.5.18.21 eth3: 56(84) bytes of
> data.
>
> --- 216.239.34.10 ping statistics ---
> 3 packets transmitted, 0 received, 100% packet loss, time 2006ms
> ###################################################
> ###################################################
> 13:24:23.556436 00:23:54:07:e9:6a > 00:90:d0:da:d2:06, ethertype IPv4
> (0x0800), length 98: 10.5.18.21 > 216.239.34.10: ICMP echo request, id
> 51300, seq 1, length 64
> 13:24:23.605304 00:90:d0:da:d2:06 > 00:23:54:07:e9:6a, ethertype IPv4
> (0x0800), length 98: 216.239.34.10 > 10.5.18.21: ICMP echo reply, id
> 51300, seq 1, length 64
> 13:24:24.555536 00:23:54:07:e9:6a > 00:90:d0:da:d2:06, ethertype IPv4
> (0x0800), length 98: 10.5.18.21 > 216.239.34.10: ICMP echo request, id
> 51300, seq 2, length 64
> 13:24:24.603520 00:90:d0:da:d2:06 > 00:23:54:07:e9:6a, ethertype IPv4
> (0x0800), length 98: 216.239.34.10 > 10.5.18.21: ICMP echo reply, id
> 51300, seq 2, length 64
> 13:24:25.563105 00:23:54:07:e9:6a > 00:90:d0:da:d2:06, ethertype IPv4
> (0x0800), length 98: 10.5.18.21 > 216.239.34.10: ICMP echo request, id
> 51300, seq 3, length 64
> 13:24:25.610497 00:90:d0:da:d2:06 > 00:23:54:07:e9:6a, ethertype IPv4
> (0x0800), length 98: 216.239.34.10 > 10.5.18.21: ICMP echo reply, id
> 51300, seq 3, length 64
> ###################################################
>
> so, I'm definitely getting those packets back, but system ignoress them.
>
> any idea what could go wrong and why does my system discard packages
> from eth3 if they are not routed by main ruting table?
>
> any info on what could be changed between kernels 2.6.29 and 2.6.32
> regarding this issue?
Please try this patch. It might need a few minor changes to apply
cleanly.
[-- Attachment #2: 01.diff --]
[-- Type: text/x-patch, Size: 2870 bytes --]
commit 28f6aeea3f12d37bd258b2c0d5ba891bff4ec479
Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date: Fri Dec 25 17:30:22 2009 -0800
net: restore ip source validation
when using policy routing and the skb mark:
there are cases where a back path validation requires us
to use a different routing table for src ip validation than
the one used for mapping ingress dst ip.
One such a case is transparent proxying where we pretend to be
the destination system and therefore the local table
is used for incoming packets but possibly a main table would
be used on outbound.
Make the default behavior to allow the above and if users
need to turn on the symmetry via sysctl src_valid_mark
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 699e85c..b230492 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -81,6 +81,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
#define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
#define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER)
+#define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK)
#define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
ACCEPT_SOURCE_ROUTE)
#define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 877ba03..bd27fbc 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -482,6 +482,7 @@ enum
NET_IPV4_CONF_ARP_ACCEPT=21,
NET_IPV4_CONF_ARP_NOTIFY=22,
NET_IPV4_CONF_ACCEPT_LOCAL=23,
+ NET_IPV4_CONF_SRC_VMARK=24,
__NET_IPV4_CONF_MAX
};
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5cdbc10..040c4f0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1397,6 +1397,7 @@ static struct devinet_sysctl_table {
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
"accept_source_route"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
+ DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 3323168..82dbf71 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -252,6 +252,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
no_addr = in_dev->ifa_list == NULL;
rpf = IN_DEV_RPFILTER(in_dev);
accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
+ if (mark && !IN_DEV_SRC_VMARK(in_dev))
+ fl.mark = 0;
}
rcu_read_unlock();
^ permalink raw reply related
* [PATCH] xfrm: avoid spinlock in get_acqseq()
From: Eric Dumazet @ 2010-01-29 14:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Use atomic_inc_return() in get_acqseq() to avoid taking a spinlock
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 4744b1f..e2aacf0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3019,12 +3019,11 @@ static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_e
static u32 get_acqseq(void)
{
u32 res;
- static u32 acqseq;
- static DEFINE_SPINLOCK(acqseq_lock);
+ static atomic_t acqseq;
- spin_lock_bh(&acqseq_lock);
- res = (++acqseq ? : ++acqseq);
- spin_unlock_bh(&acqseq_lock);
+ do {
+ res = atomic_inc_return(&acqseq);
+ } while (!res);
return res;
}
^ permalink raw reply related
* Re: [PATCH v2 2/2] virtio_net: Defer skb allocation in receive path
From: Michael S. Tsirkin @ 2010-01-29 14:05 UTC (permalink / raw)
To: Shirley Ma; +Cc: Amit Shah, Rusty Russell, Avi Kivity, netdev, kvm
In-Reply-To: <1263429475.29594.8.camel@localhost.localdomain>
On Wed, Jan 13, 2010 at 04:37:55PM -0800, Shirley Ma wrote:
> On Thu, 2010-01-14 at 00:48 +0200, Michael S. Tsirkin wrote:
> > On Wed, Jan 13, 2010 at 02:23:48PM -0800, Shirley Ma wrote:
> > > On Wed, 2010-01-13 at 23:37 +0200, Michael S. Tsirkin wrote:
> > > > Yes, separate patch is best.
> > >
> > > The send side patch is done, I will submit it when this patch has
> > > been reviewed. :)
> >
> >
> > Hey, why wait :)
> >
>
> Because: the send side patch is built on top of this patch and uses
> free_unused_bufs() func.
>
> Thanks
> Shirley
Now that's in, how does the send patch look?
--
MST
^ permalink raw reply
* macvlan on top mlx4 fails
From: Daniel Lezcano @ 2010-01-29 14:31 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Linux Netdev List
Hi all,
I am trying to have a macvlan on top of an ethernet driver infiniband
emulation communicating with the macvlan on anoher host with the same
configuration. But I am not able to ping them through the ip address
assigned to each macvlan.
On the host1 (s1):
s1:~> ifconfig
eth1 Link encap:Ethernet HWaddr 00:1A:64:44:B5:FB
inet addr:9.114.244.95 Bcast:9.114.247.255 Mask:255.255.248.0
inet6 addr: fe80::21a:64ff:fe44:b5fb/64 Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:5355123 errors:0 dropped:0 overruns:0 frame:0
TX packets:2193023 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:791518554 (754.8 Mb) TX bytes:18432872954 (17578.9 Mb)
ib0 Link encap:UNSPEC HWaddr
80-00-00-48-FE-80-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.0.95 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::202:c903:1:1b1d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:2044 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:272 errors:0 dropped:5 overruns:0 carrier:0
collisions:0 txqueuelen:256
RX bytes:27870 (27.2 Kb) TX bytes:27150 (26.5 Kb)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:170697 errors:0 dropped:0 overruns:0 frame:0
TX packets:170697 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:61678890 (58.8 Mb) TX bytes:61678890 (58.8 Mb)
mc1 Link encap:Ethernet HWaddr 86:D7:44:D4:DC:C0
inet addr:1.2.3.5 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::84d7:44ff:fed4:dcc0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:11903 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:851808 (831.8 Kb) TX bytes:468 (468.0 b)
s2:~ # ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:1a:64:44:b5:22 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc
pfifo_fast state UNKNOWN qlen 1000
link/ether 00:1a:64:44:b5:23 brd ff:ff:ff:ff:ff:ff
4: ib0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 2044 qdisc pfifo_fast
state UP qlen 256
link/infiniband
80:00:00:48:fe:80:00:00:00:00:00:41:00:02:c9:03:00:01:1e:bd brd
00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
5: ib1: <BROADCAST,MULTICAST> mtu 2044 qdisc noop state DOWN qlen 256
link/infiniband
80:00:00:49:fe:80:00:00:00:00:00:00:00:02:c9:03:00:01:1e:be brd
00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
49: mc1@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UNKNOWN
link/ether be:7e:6e:dd:58:c0 brd ff:ff:ff:ff:ff:ff
On the host2 (s2):
s2:~ # ifconfig
eth1 Link encap:Ethernet HWaddr 00:1A:64:44:B5:23
inet addr:9.114.244.96 Bcast:9.114.247.255 Mask:255.255.248.0
inet6 addr: fe80::21a:64ff:fe44:b523/64 Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:967848 errors:0 dropped:0 overruns:0 frame:0
TX packets:100977 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1535677477 (1464.5 Mb) TX bytes:61077758 (58.2 Mb)
ib0 Link encap:UNSPEC HWaddr
80-00-00-48-FE-80-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.0.96 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::202:c903:1:1ebd/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:2044 Metric:1
RX packets:58 errors:0 dropped:0 overruns:0 frame:0
TX packets:34 errors:0 dropped:5 overruns:0 carrier:0
collisions:0 txqueuelen:256
RX bytes:7305 (7.1 Kb) TX bytes:4145 (4.0 Kb)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:580 errors:0 dropped:0 overruns:0 frame:0
TX packets:580 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:43888 (42.8 Kb) TX bytes:43888 (42.8 Kb)
mc1 Link encap:Ethernet HWaddr BE:7E:6E:DD:58:C0
inet addr:1.2.3.4 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::bc7e:6eff:fedd:58c0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12411 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:886732 (865.9 Kb) TX bytes:594 (594.0 b)
s1:~ # ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen
1000
link/ether 00:1a:64:44:b5:fa brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc
pfifo_fast state UNKNOWN qlen 1000
link/ether 00:1a:64:44:b5:fb brd ff:ff:ff:ff:ff:ff
4: ib0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 2044 qdisc pfifo_fast
state UP qlen 256
link/infiniband
80:00:00:48:fe:80:00:00:00:00:00:41:00:02:c9:03:00:01:1b:1d brd
00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
5: ib1: <BROADCAST,MULTICAST> mtu 2044 qdisc noop state DOWN qlen 256
link/infiniband
80:00:00:49:fe:80:00:00:00:00:00:00:00:02:c9:03:00:01:1b:1e brd
00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
85: mc1@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UNKNOWN
link/ether 86:d7:44:d4:dc:c0 brd ff:ff:ff:ff:ff:ff
The ping result:
s2:~ # ping 1.2.3.5
PING 1.2.3.5 (1.2.3.5) 56(84) bytes of data.
From 1.2.3.4: icmp_seq=2 Destination Host Unreachable
From 1.2.3.4 icmp_seq=2 Destination Host Unreachable
From 1.2.3.4 icmp_seq=3 Destination Host Unreachable
From 1.2.3.4 icmp_seq=4 Destination Host Unreachable
^C
--- 1.2.3.5 ping statistics ---
5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4010ms
, pipe 3
The arp cache:
Address HWtype HWaddress Flags Mask
Iface
1.2.3.5 (incomplete)
mc1
When doing a tcpdump on s2 host, I have arp who-as request:
09:14:20.764389 arp who-has 1.2.3.5 tell 1.2.3.4
09:14:20.764394 arp who-has 1.2.3.5 tell 1.2.3.4
09:14:20.764427 arp who-has 1.2.3.5 tell 1.2.3.4
But doing the same tcpdump on the s1 host I don't see there arp request.
The output of lscpi:
s2:~ # lspci
0000:00:01.0 RAID bus controller: IBM Obsidian chipset SCSI controller
(rev 02)
0001:00:01.0 USB Controller: NEC Corporation USB (rev 43)
0001:00:01.1 USB Controller: NEC Corporation USB (rev 43)
0001:00:01.2 USB Controller: NEC Corporation USB 2.0 (rev 04)
0002:00:01.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02)
0003:01:00.0 InfiniBand: Mellanox Technologies MT25418 [ConnectX IB DDR,
PCIe 2.0 2.5GT/s] (rev a0)
I am a newbie on infiniband so I was wondering if I did something wrong
or if this is unsupported.
Thanks in advance.
-- Daniel
ps : I was not able to find the email of the mlx4 driver maintainer.
^ permalink raw reply
* Re: macvlan on top mlx4 fails
From: Patrick McHardy @ 2010-01-29 14:47 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: Linux Netdev List
In-Reply-To: <4B62F12F.9020302@fr.ibm.com>
Daniel Lezcano wrote:
> Hi all,
>
> I am trying to have a macvlan on top of an ethernet driver infiniband
> emulation communicating with the macvlan on anoher host with the same
> configuration. But I am not able to ping them through the ip address
> assigned to each macvlan.
>
> On the host1 (s1):
>
> ...
> s2:~ # ping 1.2.3.5
> PING 1.2.3.5 (1.2.3.5) 56(84) bytes of data.
> From 1.2.3.4: icmp_seq=2 Destination Host Unreachable
> From 1.2.3.4 icmp_seq=2 Destination Host Unreachable
> From 1.2.3.4 icmp_seq=3 Destination Host Unreachable
> From 1.2.3.4 icmp_seq=4 Destination Host Unreachable
> ^C
> --- 1.2.3.5 ping statistics ---
> 5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4010ms
> , pipe 3
>
> The arp cache:
>
> Address HWtype HWaddress Flags Mask Iface
> 1.2.3.5 (incomplete) mc1
>
>
> When doing a tcpdump on s2 host, I have arp who-as request:
>
>
> 09:14:20.764389 arp who-has 1.2.3.5 tell 1.2.3.4
> 09:14:20.764394 arp who-has 1.2.3.5 tell 1.2.3.4
> 09:14:20.764427 arp who-has 1.2.3.5 tell 1.2.3.4
>
>
> But doing the same tcpdump on the s1 host I don't see there arp request.
>
> The output of lscpi:
>
> s2:~ # lspci
> 0000:00:01.0 RAID bus controller: IBM Obsidian chipset SCSI controller
> (rev 02)
> 0001:00:01.0 USB Controller: NEC Corporation USB (rev 43)
> 0001:00:01.1 USB Controller: NEC Corporation USB (rev 43)
> 0001:00:01.2 USB Controller: NEC Corporation USB 2.0 (rev 04)
> 0002:00:01.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev
> 02)
> 0003:01:00.0 InfiniBand: Mellanox Technologies MT25418 [ConnectX IB DDR,
> PCIe 2.0 2.5GT/s] (rev a0)
>
>
> I am a newbie on infiniband so I was wondering if I did something wrong
> or if this is unsupported.
Well, I don't know much about infiniband myself. On which device
are you running tcpdump? In case its the eth-device, does running
tcpdump directly on top of the ib-devices make any difference?
Perhaps its not properly propagating the promiscous mode flag or
the secondary unicast addresses.
^ permalink raw reply
* Re: macvlan on top mlx4 fails
From: Daniel Lezcano @ 2010-01-29 14:55 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Linux Netdev List
In-Reply-To: <4B62F4F7.9080701@trash.net>
Patrick McHardy wrote:
> Daniel Lezcano wrote:
>> Hi all,
>>
>> I am trying to have a macvlan on top of an ethernet driver infiniband
>> emulation communicating with the macvlan on anoher host with the same
>> configuration. But I am not able to ping them through the ip address
>> assigned to each macvlan.
>>
>> On the host1 (s1):
>>
>> ...
>> s2:~ # ping 1.2.3.5
>> PING 1.2.3.5 (1.2.3.5) 56(84) bytes of data.
>> From 1.2.3.4: icmp_seq=2 Destination Host Unreachable
>> From 1.2.3.4 icmp_seq=2 Destination Host Unreachable
>> From 1.2.3.4 icmp_seq=3 Destination Host Unreachable
>> From 1.2.3.4 icmp_seq=4 Destination Host Unreachable
>> ^C
>> --- 1.2.3.5 ping statistics ---
>> 5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4010ms
>> , pipe 3
>>
>> The arp cache:
>>
>> Address HWtype HWaddress Flags Mask Iface
>> 1.2.3.5 (incomplete) mc1
>>
>>
>> When doing a tcpdump on s2 host, I have arp who-as request:
>>
>>
>> 09:14:20.764389 arp who-has 1.2.3.5 tell 1.2.3.4
>> 09:14:20.764394 arp who-has 1.2.3.5 tell 1.2.3.4
>> 09:14:20.764427 arp who-has 1.2.3.5 tell 1.2.3.4
>>
>>
>> But doing the same tcpdump on the s1 host I don't see there arp request.
>>
>> The output of lscpi:
>>
>> s2:~ # lspci
>> 0000:00:01.0 RAID bus controller: IBM Obsidian chipset SCSI controller
>> (rev 02)
>> 0001:00:01.0 USB Controller: NEC Corporation USB (rev 43)
>> 0001:00:01.1 USB Controller: NEC Corporation USB (rev 43)
>> 0001:00:01.2 USB Controller: NEC Corporation USB 2.0 (rev 04)
>> 0002:00:01.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev
>> 02)
>> 0003:01:00.0 InfiniBand: Mellanox Technologies MT25418 [ConnectX IB DDR,
>> PCIe 2.0 2.5GT/s] (rev a0)
>>
>>
>> I am a newbie on infiniband so I was wondering if I did something wrong
>> or if this is unsupported.
>
> Well, I don't know much about infiniband myself. On which device
> are you running tcpdump?
I did:
tcpdump -i any arp dst or src 1.2.3.5
In case its the eth-device, does running
> tcpdump directly on top of the ib-devices make any difference?
Yes, right. The arp request are seen on eth1 but not on the ib.
> Perhaps its not properly propagating the promiscous mode flag or
> the secondary unicast addresses.
Is it possible to check that ?
Thanks.
^ permalink raw reply
* Re: macvlan on top mlx4 fails
From: Patrick McHardy @ 2010-01-29 15:03 UTC (permalink / raw)
To: Daniel Lezcano; +Cc: Linux Netdev List
In-Reply-To: <4B62F6FA.9070000@fr.ibm.com>
Daniel Lezcano wrote:
> Patrick McHardy wrote:
>> Daniel Lezcano wrote:
>>> Hi all,
>>>
>>> I am trying to have a macvlan on top of an ethernet driver infiniband
>>> emulation communicating with the macvlan on anoher host with the same
>>> configuration. But I am not able to ping them through the ip address
>>> assigned to each macvlan.
>>>
>>> On the host1 (s1):
>>>
>>> ...
>>> s2:~ # ping 1.2.3.5
>>> PING 1.2.3.5 (1.2.3.5) 56(84) bytes of data.
>>> From 1.2.3.4: icmp_seq=2 Destination Host Unreachable
>>> From 1.2.3.4 icmp_seq=2 Destination Host Unreachable
>>> From 1.2.3.4 icmp_seq=3 Destination Host Unreachable
>>> From 1.2.3.4 icmp_seq=4 Destination Host Unreachable
>>> ^C
>>> --- 1.2.3.5 ping statistics ---
>>> 5 packets transmitted, 0 received, +4 errors, 100% packet loss, time
>>> 4010ms
>>> , pipe 3
>>>
>>> The arp cache:
>>>
>>> Address HWtype HWaddress Flags Mask Iface
>>> 1.2.3.5 (incomplete) mc1
>>>
>>>
>>> When doing a tcpdump on s2 host, I have arp who-as request:
>>>
>>>
>>> 09:14:20.764389 arp who-has 1.2.3.5 tell 1.2.3.4
>>> 09:14:20.764394 arp who-has 1.2.3.5 tell 1.2.3.4
>>> 09:14:20.764427 arp who-has 1.2.3.5 tell 1.2.3.4
>>>
>>>
>>> But doing the same tcpdump on the s1 host I don't see there arp request.
>>>
>>> The output of lscpi:
>>>
>>> s2:~ # lspci
>>> 0000:00:01.0 RAID bus controller: IBM Obsidian chipset SCSI controller
>>> (rev 02)
>>> 0001:00:01.0 USB Controller: NEC Corporation USB (rev 43)
>>> 0001:00:01.1 USB Controller: NEC Corporation USB (rev 43)
>>> 0001:00:01.2 USB Controller: NEC Corporation USB 2.0 (rev 04)
>>> 0002:00:01.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev
>>> 02)
>>> 0003:01:00.0 InfiniBand: Mellanox Technologies MT25418 [ConnectX IB DDR,
>>> PCIe 2.0 2.5GT/s] (rev a0)
>>>
>>>
>>> I am a newbie on infiniband so I was wondering if I did something wrong
>>> or if this is unsupported.
>>
>> Well, I don't know much about infiniband myself. On which device
>> are you running tcpdump?
>
> I did:
>
> tcpdump -i any arp dst or src 1.2.3.5
>
> In case its the eth-device, does running
>> tcpdump directly on top of the ib-devices make any difference?
>
> Yes, right. The arp request are seen on eth1 but not on the ib.
That would be fine unless I'm misunderstanding your setup - with
macvlan bound to eth1 they should be visible on both eth1 any the
macvlan device.
I'm guessing that you have a filter misconfiguration. You need
arp_ignore=1 and possibly rp_filter=0.
>> Perhaps its not properly propagating the promiscous mode flag or
>> the secondary unicast addresses.
>
> Is it possible to check that ?
If the devices are not already in promiscous mode, you should see
"device XXX entered promiscuous mode" for both devices in the
ring buffer.
^ permalink raw reply
* Re: [PATCH] tcp: fix ICMP-RTO war
From: Denys Fedoryshchenko @ 2010-01-29 15:15 UTC (permalink / raw)
To: Damian Lukowski; +Cc: Ilpo Järvinen, Netdev, David Miller
In-Reply-To: <4B62D0DE.9050706@tvk.rwth-aachen.de>
On Friday 29 January 2010 14:13:18 Damian Lukowski wrote:
> Denys Fedoryshchenko schrieb:
> > On Wednesday 27 January 2010 14:36:18 you wrote:
> >> Unless they are for a different connection? We might have to print sk
> >> (%p) in all those printouts to be sure which maps to which. If a peer
> >> becomes unreachable, it may well have multiple connections open (this
> >> was a proxy, iirc?).
> >
> > Ok i will try to do that today.
> >
> > Most probably different connections, on this proxy i have 10-15k
> > established connections at peak time.
http://www.nuclearcat.com/files/report1.txt
http://www.nuclearcat.com/files/report2.txt
Here with %p and sk.
^ permalink raw reply
* Re: [2.6.33-rc5] kernel BUG at include/net/netns/generic.h:41!
From: Eric Dumazet @ 2010-01-29 15:22 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: Luca Tettamanti, linux-kernel, netdev
In-Reply-To: <b6fcc0a1001290217l4edb0a0btbafa0c26b6f14ad5@mail.gmail.com>
Le vendredi 29 janvier 2010 à 12:17 +0200, Alexey Dobriyan a écrit :
> On Fri, Jan 29, 2010 at 11:48 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> > with recent kernels I'm seeing this BUG - triggered by racoon - at boot:
> >
> > NET: Registered protocol family 15
> > ------------[ cut here ]------------
> > kernel BUG at /home/kronos/src/linux-2.6.git/include/net/netns/generic.h:43!
> > invalid opcode: 0000 [#1] PREEMPT SMP
> > last sysfs file: /sys/kernel/uevent_seqnum
> > CPU 1
> > Pid: 1941, comm: racoon Not tainted 2.6.33-rc5-00271-gbe8cde8-dirty #238 F3Sa /F3Sa
> > RIP: 0010:[<ffffffffa03035be>] [<ffffffffa03035be>] pfkey_create+0x36/0x18b [af_key]
>
> Does it triggers after succesfull boot if you do
>
> rmmod af_key; modprobe af_key
>
> a couple of times?
>
> Post .config, just in case.
I am looking at ipsec_pfkey_init()
We call sock_register(&pfkey_family_ops) before pfkey_net_id being
initialized (by the call to register_pernet_subsys(&pfkey_net_ops);
As soon as sock_register(&pfkey_family_ops) is done, another thread can
open a socket and call pfkey_create() -> crash
We should change order of initializations somehow
^ permalink raw reply
* Re: [PATCH] xfrm: avoid spinlock in get_acqseq()
From: Benjamin LaHaise @ 2010-01-29 15:11 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1264773952.3184.22.camel@edumazet-laptop>
Hi Eric,
On Fri, Jan 29, 2010 at 03:05:52PM +0100, Eric Dumazet wrote:
> Use atomic_inc_return() in get_acqseq() to avoid taking a spinlock
> + static atomic_t acqseq;
I think that needs to be:
static atomic_t acqseq = ATOMIC_INIT(0);
Cheers,
-ben
^ permalink raw reply
* Re: [PATCH] xfrm: avoid spinlock in get_acqseq()
From: Eric Dumazet @ 2010-01-29 16:00 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: David Miller, netdev
In-Reply-To: <20100129151149.GD20701@kvack.org>
Le vendredi 29 janvier 2010 à 10:11 -0500, Benjamin LaHaise a écrit :
> Hi Eric,
>
> On Fri, Jan 29, 2010 at 03:05:52PM +0100, Eric Dumazet wrote:
> > Use atomic_inc_return() in get_acqseq() to avoid taking a spinlock
> > + static atomic_t acqseq;
>
> I think that needs to be:
> static atomic_t acqseq = ATOMIC_INIT(0);
>
> Cheers,
>
> -ben
Not sure its needed now that atomic_t is an integral 32bits type for all
arches, or a cleanup patch is wanted :)
Thanks !
./security/tomoyo/realpath.c:412:static atomic_t tomoyo_dynamic_memory_size;
./arch/sh/kernel/perf_event.c:41:static atomic_t num_events;
./arch/um/kernel/smp.c:199:static atomic_t scf_started;
./arch/um/kernel/smp.c:200:static atomic_t scf_finished;
./arch/ia64/kernel/mca.c:1287: static atomic_t mca_count;
./arch/ia64/kernel/mca.c:1661: static atomic_t slaves;
./arch/ia64/kernel/mca.c:1662: static atomic_t monarchs;
./arch/ia64/kernel/crash.c:24:static atomic_t kdump_cpu_frozen;
./arch/x86/mm/mmio-mod.c:62:static atomic_t mmiotrace_enabled;
./arch/x86/mm/mmio-mod.c:237: static atomic_t next_id;
./arch/x86/kernel/cpu/perf_event.c:714:static atomic_t active_events;
./arch/x86/kernel/cpu/mcheck/mce.c:238:static atomic_t mce_paniced;
./arch/x86/kernel/cpu/mcheck/mce.c:241:static atomic_t mce_fake_paniced;
./arch/x86/kernel/cpu/mcheck/mce.c:614:static atomic_t mce_executing;
./arch/x86/kernel/cpu/mcheck/mce.c:619:static atomic_t mce_callin;
./arch/x86/kernel/cpu/mcheck/mce.c:727:static atomic_t global_nwo;
./arch/x86/kernel/tboot.c:297:static atomic_t ap_wfs_count;
./arch/x86/kernel/reboot.c:724:static atomic_t waiting_for_crash_ipi;
./arch/blackfin/kernel/irqchip.c:17:static atomic_t irq_err_count;
./arch/microblaze/kernel/of_device.c:14: static atomic_t bus_no_reg_magic;
./arch/powerpc/platforms/iseries/viopath.c:74:static atomic_t event_buffer_available[VIO_MAX_SUBTYPES];
./arch/powerpc/kernel/of_device.c:15: static atomic_t bus_no_reg_magic;
./arch/powerpc/kernel/perf_event.c:959:static atomic_t num_events;
./mm/memcontrol.c:1283:static atomic_t memcg_drain_count;
./virt/kvm/kvm_main.c:75:static atomic_t hardware_enable_failed;
./net/netfilter/nfnetlink_log.c:71:static atomic_t global_seq;
./net/decnet/af_decnet.c:158:static atomic_t decnet_memory_allocated;
./net/llc/llc_conn.c:775:static atomic_t llc_sock_nr;
./net/core/netpoll.c:41:static atomic_t trapped;
./net/sctp/socket.c:116:static atomic_t sctp_memory_allocated;
./net/sunrpc/sched.c:238: static atomic_t rpc_pid;
./fs/ocfs2/stack_user.c:160:static atomic_t ocfs2_control_opened;
./fs/notify/inotify/inotify.c:37:static atomic_t inotify_cookie;
./fs/notify/inotify/inotify_user.c:62:static atomic_t inotify_grp_num;
./fs/afs/rxrpc.c:20:static atomic_t afs_outstanding_calls;
./fs/afs/rxrpc.c:21:static atomic_t afs_outstanding_skbs;
./fs/afs/super.c:59:static atomic_t afs_count_active_inodes;
./fs/quota/quota.c:558: static atomic_t seq;
./fs/dlm/user.c:29:static atomic_t dlm_monitor_opened;
./fs/ecryptfs/miscdev.c:31:static atomic_t ecryptfs_num_miscdev_opens;
./kernel/rcutree.c:1575:static atomic_t rcu_barrier_cpu_count;
./kernel/trace/trace.c:807:static atomic_t trace_record_cmdline_disabled __read_mostly;
./kernel/trace/trace_mmiotrace.c:26:static atomic_t dropped_count;
./kernel/slow-work.c:85:static atomic_t slow_work_thread_count;
./kernel/slow-work.c:86:static atomic_t vslow_work_executing_count;
./kernel/rtmutex-tester.c:24:static atomic_t rttest_event;
./kernel/async.c:83:static atomic_t entry_count;
./kernel/async.c:84:static atomic_t thread_count;
./kernel/perf_event.c:45:static atomic_t nr_events __read_mostly;
./kernel/perf_event.c:46:static atomic_t nr_mmap_events __read_mostly;
./kernel/perf_event.c:47:static atomic_t nr_comm_events __read_mostly;
./kernel/perf_event.c:48:static atomic_t nr_task_events __read_mostly;
./kernel/profile.c:42:static atomic_t *prof_buffer;
./kernel/rcutorture.c:121:static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
./kernel/rcutorture.c:122:static atomic_t n_rcu_torture_alloc;
./kernel/rcutorture.c:123:static atomic_t n_rcu_torture_alloc_fail;
./kernel/rcutorture.c:124:static atomic_t n_rcu_torture_free;
./kernel/rcutorture.c:125:static atomic_t n_rcu_torture_mberror;
./kernel/rcutorture.c:126:static atomic_t n_rcu_torture_error;
./kernel/stop_machine.c:39:static atomic_t thread_ack;
./kernel/kgdb.c:124:static atomic_t passive_cpu_wait[NR_CPUS];
./kernel/kgdb.c:125:static atomic_t cpu_in_kgdb[NR_CPUS];
./kernel/time/timer_stats.c:119:static atomic_t overflow_count;
./drivers/dma/ppc4xx/adma.c:106:static atomic_t ppc440spe_adma_err_irq_ref;
./drivers/s390/cio/css.c:470:static atomic_t css_eval_scheduled;
./drivers/s390/cio/cio.c:960:static atomic_t chpid_reset_count;
./drivers/pci/hotplug/cpci_hotplug_core.c:59:static atomic_t extracting;
./drivers/char/rocket.c:114:static atomic_t rp_num_ports_open; /* Number of serial ports open */
./drivers/char/ipmi/ipmi_msghandler.c:4044:static atomic_t stop_operation;
./drivers/md/md.c:160:static atomic_t md_event_count;
./drivers/ieee1394/raw1394.c:79:static atomic_t iso_buffer_size;
./drivers/usb/serial/io_edgeport.c:196:static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
./drivers/net/pppol2tp.c:229:static atomic_t pppol2tp_tunnel_count;
./drivers/net/pppol2tp.c:230:static atomic_t pppol2tp_session_count;
./drivers/net/vmxnet3/vmxnet3_drv.c:45:static atomic_t devices_found;
./drivers/watchdog/bcm47xx_wdt.c:52:static atomic_t ticks;
./drivers/staging/batman-adv/routing.c:46:static atomic_t data_ready_cond;
./drivers/scsi/lpfc/lpfc_debugfs.c:1214:static atomic_t lpfc_debugfs_hba_count;
./drivers/scsi/scsi_transport_fc.c:484:static atomic_t fc_event_seq;
./drivers/scsi/hosts.c:43:static atomic_t scsi_host_next_hn; /* host_no for next new host */
./drivers/scsi/scsi_transport_iscsi.c:84:static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
./drivers/scsi/qla2xxx/qla_dfs.c:13:static atomic_t qla2x00_dfs_root_count;
./drivers/crypto/hifn_795x.c:54:static atomic_t hifn_dev_number;
^ permalink raw reply
* [PATCH] xfrm: Change initializations order in ipsec_pfkey_init()
From: Eric Dumazet @ 2010-01-29 16:33 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: Luca Tettamanti, linux-kernel, netdev, David Miller
In-Reply-To: <1264778549.3184.28.camel@edumazet-laptop>
Le vendredi 29 janvier 2010 à 16:22 +0100, Eric Dumazet a écrit :
> Le vendredi 29 janvier 2010 à 12:17 +0200, Alexey Dobriyan a écrit :
> > On Fri, Jan 29, 2010 at 11:48 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> > > with recent kernels I'm seeing this BUG - triggered by racoon - at boot:
> > >
> > > NET: Registered protocol family 15
> > > ------------[ cut here ]------------
> > > kernel BUG at /home/kronos/src/linux-2.6.git/include/net/netns/generic.h:43!
> > > invalid opcode: 0000 [#1] PREEMPT SMP
> > > last sysfs file: /sys/kernel/uevent_seqnum
> > > CPU 1
> > > Pid: 1941, comm: racoon Not tainted 2.6.33-rc5-00271-gbe8cde8-dirty #238 F3Sa /F3Sa
> > > RIP: 0010:[<ffffffffa03035be>] [<ffffffffa03035be>] pfkey_create+0x36/0x18b [af_key]
> >
> > Does it triggers after succesfull boot if you do
> >
> > rmmod af_key; modprobe af_key
> >
> > a couple of times?
> >
> > Post .config, just in case.
>
> I am looking at ipsec_pfkey_init()
>
> We call sock_register(&pfkey_family_ops) before pfkey_net_id being
> initialized (by the call to register_pernet_subsys(&pfkey_net_ops);
>
> As soon as sock_register(&pfkey_family_ops) is done, another thread can
> open a socket and call pfkey_create() -> crash
>
> We should change order of initializations somehow
>
Something like this (compiled but not tested) patch ?
Should probably be sent to stable team...
[PATCH] xfrm: Change initializations order in ipsec_pfkey_init()
Before allowing other threads to create PF_KEY sockets, we must make
sure pfkey_net_id is properly initialized.
That means calling register_pernet_subsys(&pfkey_net_ops) before
sock_register(&pfkey_family_ops)
Reported-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/key/af_key.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 76fa6fe..e399ddf 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3807,21 +3807,24 @@ static int __init ipsec_pfkey_init(void)
if (err != 0)
goto out;
- err = sock_register(&pfkey_family_ops);
- if (err != 0)
- goto out_unregister_key_proto;
err = xfrm_register_km(&pfkeyv2_mgr);
if (err != 0)
- goto out_sock_unregister;
+ goto out_unregister_key_proto;
+
err = register_pernet_subsys(&pfkey_net_ops);
if (err != 0)
goto out_xfrm_unregister_km;
+
+ err = sock_register(&pfkey_family_ops);
+ if (err != 0)
+ goto out_unregister_pernet;
out:
return err;
+
+out_unregister_pernet:
+ unregister_pernet_subsys(&pfkey_net_ops);
out_xfrm_unregister_km:
xfrm_unregister_km(&pfkeyv2_mgr);
-out_sock_unregister:
- sock_unregister(PF_KEY);
out_unregister_key_proto:
proto_unregister(&key_proto);
goto out;
^ permalink raw reply related
* Re: [PATCH] xfrm: avoid spinlock in get_acqseq()
From: Benjamin LaHaise @ 2010-01-29 17:01 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1264780819.3184.33.camel@edumazet-laptop>
On Fri, Jan 29, 2010 at 05:00:19PM +0100, Eric Dumazet wrote:
> Not sure its needed now that atomic_t is an integral 32bits type for all
> arches, or a cleanup patch is wanted :)
>
> Thanks !
Ah, yes, it looks like things have changed in this area a bit over time.
I'll do up a cleanup patch for this.
-ben
^ permalink raw reply
* [RFC] NAPI as kobject proposal
From: Stephen Hemminger @ 2010-01-29 18:18 UTC (permalink / raw)
To: David Miller; +Cc: netdev
The NAPI interface structure in current kernels is managed by the driver.
As part of receive packet steering there is a requirement to add an
additional parameter to this for the CPU map. And this map needs to
have an API to set it.
The right way to do this in the kernel model is to make NAPI into
a kobject and associate it back with the network device (parent).
This isn't wildly difficult but does change some of the API for
network device drivers because:
1. They need to handle another possible error on setup
2. NAPI object needs to be dynamically allocated
separately (not as part of netdev_priv)
3. Driver should pass index that can be uses as part of
name (easier than scanning)
Eventually, there will be:
/sys/class/net/eth0/napi0/
weight
cpumap
So here is a starting point patch that shows how the API might look like.
---
include/linux/netdevice.h | 20 ++++++++++++++------
net/core/dev.c | 28 ++++++++++++++++++++++++++--
2 files changed, 40 insertions(+), 8 deletions(-)
--- a/include/linux/netdevice.h 2010-01-29 10:00:55.820739116 -0800
+++ b/include/linux/netdevice.h 2010-01-29 10:15:33.098863437 -0800
@@ -378,6 +378,8 @@ struct napi_struct {
struct list_head dev_list;
struct sk_buff *gro_list;
struct sk_buff *skb;
+
+ struct kobject kobj;
};
enum {
@@ -1037,25 +1039,31 @@ static inline void *netdev_priv(const st
#define SET_NETDEV_DEVTYPE(net, devtype) ((net)->dev.type = (devtype))
/**
- * netif_napi_add - initialize a napi context
+ * netif_napi_init - initialize a napi context
* @dev: network device
* @napi: napi context
+ * @index: queue number
* @poll: polling function
* @weight: default weight
*
- * netif_napi_add() must be used to initialize a napi context prior to calling
+ * netif_napi_init() must be used to create a napi context prior to calling
* *any* of the other napi related functions.
+ *
+ * in case of error, the context is not left in napi_list so it can
+ * be cleaned up by free_netdev, but is not valid for use.
*/
-void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
- int (*poll)(struct napi_struct *, int), int weight);
+extern int netif_napi_init(struct net_device *dev, struct napi_struct *napi,
+ unsigned index,
+ int (*poll)(struct napi_struct *, int), int weight);
/**
- * netif_napi_del - remove a napi context
+ * netif_napi_del - free a napi context
* @napi: napi context
*
* netif_napi_del() removes a napi context from the network device napi list
+ * and frees it.
*/
-void netif_napi_del(struct napi_struct *napi);
+extern void netif_napi_del(struct napi_struct *napi);
struct napi_gro_cb {
/* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */
--- a/net/core/dev.c 2010-01-29 10:00:55.810739850 -0800
+++ b/net/core/dev.c 2010-01-29 10:14:53.388864572 -0800
@@ -2926,9 +2926,24 @@ void napi_complete(struct napi_struct *n
}
EXPORT_SYMBOL(napi_complete);
-void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
+static void release_napi(struct kobject *kobj)
+{
+ struct napi_struct *napi
+ = container_of(kobj, struct napi_struct, kobj);
+ kfree(napi);
+}
+
+static struct kobj_type napi_ktype = {
+ /* insert future sysfs hooks ... */
+ .release = release_napi,
+};
+
+int netif_napi_init(struct net_device *dev, struct napi_struct *napi,
+ unsigned index,
int (*poll)(struct napi_struct *, int), int weight)
{
+ int err;
+
INIT_LIST_HEAD(&napi->poll_list);
napi->gro_count = 0;
napi->gro_list = NULL;
@@ -2941,9 +2956,16 @@ void netif_napi_add(struct net_device *d
spin_lock_init(&napi->poll_lock);
napi->poll_owner = -1;
#endif
+
+ err = kobject_init_and_add(&napi->kobj, &napi_ktype,
+ &dev->dev.kobj, "napi%d", index);
+ if (err)
+ return err;
+
set_bit(NAPI_STATE_SCHED, &napi->state);
+ return 0;
}
-EXPORT_SYMBOL(netif_napi_add);
+EXPORT_SYMBOL(netif_napi_init);
void netif_napi_del(struct napi_struct *napi)
{
@@ -2960,6 +2982,8 @@ void netif_napi_del(struct napi_struct *
napi->gro_list = NULL;
napi->gro_count = 0;
+
+ kobject_put(&napi->kobj);
}
EXPORT_SYMBOL(netif_napi_del);
^ permalink raw reply
* Re: [PATCH 3/3] net: macvtap driver
From: Arnd Bergmann @ 2010-01-29 19:49 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: David Miller, Stephen Hemminger, Patrick McHardy, Herbert Xu,
Or Gerlitz, netdev, bridge, linux-kernel
In-Reply-To: <20100129112141.GA6548@redhat.com>
On Friday 29 January 2010, Michael S. Tsirkin wrote:
> > That may well be, I haven't tried vlan. What do you think it should do
> > then?
>
> Look at eth_type for a more complete packet parsing.
ok. I initially called that but it crashed because the skb was not initialized
properly at that point. I'll have a look.
> > > > +/*
> > > > + * provide compatibility with generic tun/tap interface
> > > > + */
> > > > +static long macvtap_ioctl(struct file *file, unsigned int cmd,
> > > > + unsigned long arg)
> > > > +{
> > >
> > > All of these seem to be stubs, and tun has many more that you didn't
> > > stub out. So, why do you bother to support any ioctls at all?
> >
> > Again, minimum features to get things going. qemu fails to open
> > the device if these ioctls are not implemented, but any of the
> > more advanced features are left out.
>
> This is strange, could be application bug. E.g. send buf size is
> relatively new and apps should handle failure gracefully. IMO,
> returning success and ignoring the value is not a good idea. How about
> we just fix qemu? What about other apps?
Ok, I'll go through the ioctls again and make sure they behave correctly
they way you said. I haven't tried against against anything but qemu and
cat.
Arnd
^ permalink raw reply
* Re: [RFC] [PATCH] Optimize TCP sendmsg in favour of fast devices?
From: Rick Jones @ 2010-01-29 19:56 UTC (permalink / raw)
To: Krishna Kumar2
Cc: Herbert Xu, David Miller, eric.dumazet, ilpo.jarvinen, netdev
In-Reply-To: <OFA813CB35.7FC6144E-ON652576BA.003C3B2C-652576BA.003CB215@in.ibm.com>
Krishna Kumar2 wrote:
>>Herbert Xu <herbert@gondor.apana.org.au> wrote on 01/29/2010 02:36:25 PM:
>>
>>
>>>I ran 5 serial netperf's with 16K and another 5 serial netperfs
>>>with 64K I/O sizes, and the aggregate result is:
>>>
>>>0. Driver unsets F_SG but sets F_GSO:
>>> Original code with 16K: 19471.65
>>> New code with 16K: 19409.70
>>> Original code with 64K: 21357.23
>>> New code with 64K: 22050.42
>>
>>OK this is more in line with what I was expecting, namely that
>>enabling GSO is actually beneficial even without SG.
>>
>>It would be good to get the CPU utilisation figures so we can
>>see the complete picture.
>
>
> Same 5 runs of single netperf's:
>
> 0. Driver unsets F_SG but sets F_GSO:
> Org (16K): BW: 18180.71 SD: 13.485
> New (16K): BW: 18113.15 SD: 13.551
> Org (64K): BW: 21980.28 SD: 10.306
> New (64K): BW: 21386.59 SD: 10.447
>
> 1. Driver unsets F_SG, and with GSO off
> Org (16K): BW: 10894.62 SD: 26.591
> New (16K): BW: 7262.10 SD: 35.340
> Org (64K): BW: 12396.41 SD: 23.357
> New (64K): BW: 7853.02 SD: 32.405
>
>
> 2. Driver unsets F_SG and uses ethtool to set GSO:
> Org (16K): BW: 18094.11 SD: 13.603
> New (16K): BW: 17952.38 SD: 13.743
> Org (64K): BW: 21540.78 SD: 10.771
> New (64K): BW: 21818.35 SD: 10.598
Just a slight change in service demand there... For those unfamiliar,
service demand in netperf is the microseconds of non-idle CPU time per
KB of data transferred. Smaller is better.
happy benchmarking,
rick jones
^ permalink raw reply
* RFC: Convert printks with net_device to dev_<level>
From: Joe Perches @ 2010-01-29 20:01 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Greg Kroah-Hartman
I've been playing with a cocci script and some additional
scripts to automate a conversion of printk and pr_<level>
logging messages with a reference to a struct net_device
to dev_<level>(&net_device->dev, ...)
A sample conversion:
- printk(KERN_INFO "%s: Using MII transceiver %d, status %4.4x.\n",
- dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
+ dev_info(&dev->dev, "Using MII transceiver %d, status %04x\n",
+ tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
I submitted conversions for drivers/net/tulip/.
I did not convert any calls with KERN_DEBUG.
http://patchwork.ozlabs.org/patch/43889/
The logging messages are a bit more verbose/complete.
Code size increases a small amount.
Is this sort of conversion useful?
Should more conversions be submitted?
Would it be useful to convert the KERN_DEBUG calls?
Any automated conversion could use:
printk(KERN_DEBUG "%s: ...", dev->name
dev_printk(KERN_DEBUG, &dev->dev, "...
^ permalink raw reply
* Re: [RFC] [PATCH] Optimize TCP sendmsg in favour of fast devices?
From: Rick Jones @ 2010-01-29 20:02 UTC (permalink / raw)
To: Herbert Xu
Cc: Krishna Kumar2, David Miller, eric.dumazet, ilpo.jarvinen, netdev
In-Reply-To: <20100129113346.GB1309@gondor.apana.org.au>
Herbert Xu wrote:
> On Fri, Jan 29, 2010 at 04:45:01PM +0530, Krishna Kumar2 wrote:
>
>>Same 5 runs of single netperf's:
>>
>>0. Driver unsets F_SG but sets F_GSO:
>> Org (16K): BW: 18180.71 SD: 13.485
>> New (16K): BW: 18113.15 SD: 13.551
>> Org (64K): BW: 21980.28 SD: 10.306
>> New (64K): BW: 21386.59 SD: 10.447
>>
>>1. Driver unsets F_SG, and with GSO off
>> Org (16K): BW: 10894.62 SD: 26.591
>> New (16K): BW: 7262.10 SD: 35.340
>> Org (64K): BW: 12396.41 SD: 23.357
>> New (64K): BW: 7853.02 SD: 32.405
>>
>>
>>2. Driver unsets F_SG and uses ethtool to set GSO:
>> Org (16K): BW: 18094.11 SD: 13.603
>> New (16K): BW: 17952.38 SD: 13.743
>> Org (64K): BW: 21540.78 SD: 10.771
>> New (64K): BW: 21818.35 SD: 10.598
>
>
> Hmm, any idea what is causing case 0 to be different from case 2?
> In particular, the 64K performance in case 0 appears to be a
> regression but in case 2 it's showing up as an improvement.
>
> AFAICS these two cases should produce identical results, or is
> this just jitter across tests?
To get some idea of run to run variation, and one does not want to run
multiple explicit netperf commands and do later statistical work, one
can add global command line arguments to netperf:
netperf ... -i 30,3 -I 99,<width> ...
which will tell netperf to run at least 3 iterations (that is the
minimum minimum netperf will do) and no more than 30 iterations (that is
the maximum maximum netperf will do) attempting to be 99% confident that
the mean for throughput (and the CPU utilization if -c and/or -C are
present and a global -r is not) is within +/- width/2% For example:
netperf -H remote -i 30,3 -I 99,0.5 -c -C
will attempt to be 99% certain that the means it reports for throughput,
local and remote CPU utilization is within +/- 0.25% of the actual mean.
If, after 30 iterations it has not achieved that confidence, it will
emit warnings giving the width of the confidence intervals it has achieved.
happy benchmarking,
rick jones
^ permalink raw reply
* Re: RFC: Convert printks with net_device to dev_<level>
From: Ben Hutchings @ 2010-01-29 20:25 UTC (permalink / raw)
To: Joe Perches; +Cc: netdev, David Miller, Greg Kroah-Hartman
In-Reply-To: <1264795286.25140.72.camel@Joe-Laptop.home>
On Fri, 2010-01-29 at 12:01 -0800, Joe Perches wrote:
> I've been playing with a cocci script and some additional
> scripts to automate a conversion of printk and pr_<level>
> logging messages with a reference to a struct net_device
> to dev_<level>(&net_device->dev, ...)
>
> A sample conversion:
>
> - printk(KERN_INFO "%s: Using MII transceiver %d, status %4.4x.\n",
> - dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
> + dev_info(&dev->dev, "Using MII transceiver %d, status %04x\n",
> + tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
[...]
My understanding is that dev_* should be given a bus device (pci_device,
usb_device, ...), not a class device (net_device). Of course, the net
device name is rather useful as well. In sfc we print both once the net
device is registered.
It might be useful to add netdev_* print macros along the lines of:
#define netdev_name(dev) \
(((dev)->reg_state == NETREG_REGISTERED) ? (dev)->name : "")
#define netdev_info(dev, fmt, ...) \
dev_info((dev)->dev.parent, "%s " fmt, \
netdev_name(dev), __VA_ARGS__)
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: IPV6_DONTFRAG sockopt etc.
From: Brian Haley @ 2010-01-29 21:14 UTC (permalink / raw)
To: Pekka Savola; +Cc: netdev
In-Reply-To: <alpine.LRH.2.00.1001291138310.29525@netcore.fi>
Hi Pekka,
Pekka Savola wrote:
> Hello,
>
> There appear to be a couple of sockopts in RFC3542 that aren't
> implemented yet (they're #if 0'd in the code)
>
> #define IPV6_RECVPATHMTU 60
> #define IPV6_PATHMTU 61
> #define IPV6_DONTFRAG 62
> #define IPV6_USE_MIN_MTU 63
>
> In one particular app, I would have found IPV6_DONTFRAG useful.
Here's a possible patch for IPV6_DONTFRAG, compiled, but untested,
if you have some time. Of course it might not be of much use
without IPV6_RECVPATHMTU since you won't know what to reduce the
send() to - that would probably require different code in
ip6_append_data(), etc. Like I said, untested.
-Brian
RFC: Implement IPV6_DONTFRAG socket option, RFC 3542.
Signed-off-by: Brian Haley <brian.haley@hp.com>
---
diff --git a/include/linux/in6.h b/include/linux/in6.h
index bd55c6e..8a2b8bb 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -224,7 +224,9 @@ struct in6_flowlabel_req {
#if 0 /* not yet */
#define IPV6_RECVPATHMTU 60
#define IPV6_PATHMTU 61
+#endif
#define IPV6_DONTFRAG 62
+#if 0 /* not yet */
#define IPV6_USE_MIN_MTU 63
#endif
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e0cc9a7..102f3fe 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -340,15 +340,17 @@ struct ipv6_pinfo {
} rxopt;
/* sockopt flags */
- __u8 recverr:1,
+ __u16 recverr:1,
sndflow:1,
pmtudisc:2,
ipv6only:1,
- srcprefs:3; /* 001: prefer temporary address
+ srcprefs:3, /* 001: prefer temporary address
* 010: prefer public address
* 100: prefer care-of address
*/
+ dontfrag:1;
__u8 tclass;
+ __u8 padding;
__u32 dst_cookie;
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ccab594..f8d61d7 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -500,7 +500,8 @@ extern int ip6_append_data(struct sock *sk,
struct ipv6_txoptions *opt,
struct flowi *fl,
struct rt6_info *rt,
- unsigned int flags);
+ unsigned int flags,
+ int dontfrag);
extern int ip6_push_pending_frames(struct sock *sk);
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index d65381c..42a0eb6 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -44,7 +44,8 @@ extern int datagram_send_ctl(struct net *net,
struct msghdr *msg,
struct flowi *fl,
struct ipv6_txoptions *opt,
- int *hlimit, int *tclass);
+ int *hlimit, int *tclass,
+ int *dontfrag);
#define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index e6f9cdf..582f043 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -496,7 +496,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
int datagram_send_ctl(struct net *net,
struct msghdr *msg, struct flowi *fl,
struct ipv6_txoptions *opt,
- int *hlimit, int *tclass)
+ int *hlimit, int *tclass, int *dontfrag)
{
struct in6_pktinfo *src_info;
struct cmsghdr *cmsg;
@@ -736,6 +736,25 @@ int datagram_send_ctl(struct net *net,
break;
}
+
+ case IPV6_DONTFRAG:
+ {
+ int df;
+
+ err = -EINVAL;
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+ goto exit_f;
+ }
+
+ df = *(int *)CMSG_DATA(cmsg);
+ if (df < 0 || df > 1)
+ goto exit_f;
+
+ err = 0;
+ *dontfrag = df;
+
+ break;
+ }
default:
LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
cmsg->cmsg_type);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 217dbc2..c3f9e59 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -486,7 +486,7 @@ route_done:
len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), hlimit,
np->tclass, NULL, &fl, (struct rt6_info*)dst,
- MSG_DONTWAIT);
+ MSG_DONTWAIT, np->dontfrag);
if (err) {
ip6_flush_pending_frames(sk);
goto out_put;
@@ -565,7 +565,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl,
- (struct rt6_info*)dst, MSG_DONTWAIT);
+ (struct rt6_info*)dst, MSG_DONTWAIT,
+ np->dontfrag);
if (err) {
ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index e41eba8..62c9329 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -359,7 +359,8 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval,
msg.msg_control = (void*)(fl->opt+1);
flowi.oif = 0;
- err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, &junk);
+ err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk,
+ &junk, &junk);
if (err)
goto done;
err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index eb6d097..61e0157 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1105,7 +1105,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
int offset, int len, int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
- struct rt6_info *rt, unsigned int flags)
+ struct rt6_info *rt, unsigned int flags, int dontfrag)
{
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
@@ -1197,6 +1197,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
+toobig:
ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen);
return -EMSGSIZE;
}
@@ -1219,15 +1220,21 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
*/
inet->cork.length += length;
- if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
- (rt->u.dst.dev->features & NETIF_F_UFO)) {
-
- err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len,
- fragheaderlen, transhdrlen, mtu,
- flags);
- if (err)
- goto error;
- return 0;
+ if (length > mtu) {
+ int proto = sk->sk_protocol;
+ if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW))
+ goto toobig;
+
+ if (proto == IPPROTO_UDP &&
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
+
+ err = ip6_ufo_append_data(sk, getfrag, from, length,
+ hh_len, fragheaderlen,
+ transhdrlen, mtu, flags);
+ if (err)
+ goto error;
+ return 0;
+ }
}
if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 430454e..c0006fb 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -450,7 +450,8 @@ sticky_done:
msg.msg_controllen = optlen;
msg.msg_control = (void*)(opt+1);
- retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk);
+ retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk,
+ &junk);
if (retv)
goto done;
update:
@@ -766,6 +767,10 @@ pref_skip_coa:
break;
}
+ case IPV6_DONTFRAG:
+ np->dontfrag = valbool;
+ retv = 0;
+ break;
}
release_sock(sk);
@@ -1114,6 +1119,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val |= IPV6_PREFER_SRC_HOME;
break;
+ case IPV6_DONTFRAG:
+ val = np->dontfrag;
+ break;
+
default:
return -ENOPROTOOPT;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed31c37..2018322 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -732,6 +732,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
int addr_len = msg->msg_namelen;
int hlimit = -1;
int tclass = -1;
+ int dontfrag = -1;
u16 proto;
int err;
@@ -810,7 +811,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions);
- err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass);
+ err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
+ &tclass, &dontfrag);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -879,6 +881,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (tclass < 0)
tclass = np->tclass;
+ if (dontfrag < 0) {
+ dontfrag = np->dontfrag;
+ if (dontfrag < 0)
+ dontfrag = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
@@ -889,7 +897,7 @@ back_from_confirm:
lock_sock(sk);
err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
- msg->msg_flags);
+ msg->msg_flags, dontfrag);
if (err)
ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 34efb35..0568778 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -912,6 +912,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
int ulen = len;
int hlimit = -1;
int tclass = -1;
+ int dontfrag = -1;
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int err;
int connected = 0;
@@ -1042,7 +1043,8 @@ do_udp_sendmsg:
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(*opt);
- err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, &tclass);
+ err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
+ &tclass, &dontfrag);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -1113,6 +1115,12 @@ do_udp_sendmsg:
if (tclass < 0)
tclass = np->tclass;
+ if (dontfrag < 0) {
+ dontfrag = np->dontfrag;
+ if (dontfrag < 0)
+ dontfrag = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
back_from_confirm:
@@ -1136,7 +1144,7 @@ do_append_data:
err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
sizeof(struct udphdr), hlimit, tclass, opt, &fl,
(struct rt6_info*)dst,
- corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+ corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
if (err)
udp_v6_flush_pending_frames(sk);
else if (!corkreq)
^ permalink raw reply related
* Re: [PATCH net-next-2.6] packet: Add GSO/checksum offload support to af_packet sockets
From: Sridhar Samudrala @ 2010-01-29 21:25 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, Rusty Russell, Michael S. Tsirkin, netdev
In-Reply-To: <20100129085343.GB23140@gondor.apana.org.au>
On Fri, 2010-01-29 at 21:53 +1300, Herbert Xu wrote:
> On Tue, Jan 26, 2010 at 12:30:19PM -0800, Sridhar Samudrala wrote:
> >
> > + if (po->vnet_hdr) {
> > + err = -EINVAL;
> > + if (dev->type != ARPHRD_ETHER)
> > + goto out_unlock;
>
> We shouldn't have Ethernet-specific code in AF_PACKET. What's
> more, just because the device type is Ethernet it doesn't mean
> that the packet is going to have an Ethernet header.
This check is to dis-allow processing of packets with virtio_net_hdr
destined for non-ethernet devices.
Is it OK if i add a check in packet_bind() to not allow binding to
a non-ethernet device when PACKET_VNET_HDR option is set?
I need to figure out a way to set the skb protocol correctly based
on the packet. Any clues?
Michael has posted a prototype patch that addresses this. Do you
agree with this approach?
http://lkml.org/lkml/2010/1/6/56
Did you get a chance to look at my other patch that adds a check
for VLAN packets in skb_gso_segment() to address a bug when sending
large VLAN packets from a guest?
http://thread.gmane.org/gmane.linux.network/150198
Thanks
Sridhar
^ permalink raw reply
* Re: [PATCH net-next-2.6] packet: Add GSO/checksum offload support to af_packet sockets
From: Herbert Xu @ 2010-01-29 21:36 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: David Miller, Rusty Russell, Michael S. Tsirkin, netdev
In-Reply-To: <1264800308.15980.395.camel@w-sridhar.beaverton.ibm.com>
On Fri, Jan 29, 2010 at 01:25:08PM -0800, Sridhar Samudrala wrote:
>
> This check is to dis-allow processing of packets with virtio_net_hdr
> destined for non-ethernet devices.
> Is it OK if i add a check in packet_bind() to not allow binding to
> a non-ethernet device when PACKET_VNET_HDR option is set?
>
> I need to figure out a way to set the skb protocol correctly based
> on the packet. Any clues?
IMHO the skb protocol should be set by whatever is invoking the
sendmsg call. After all they would know what the L2 header is
and should be able to deduce the protocol correctly.
Adding all this logic into AF_PACKET is just a hack.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] tcp: fix ICMP-RTO war
From: Damian Lukowski @ 2010-01-29 21:45 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: Ilpo Järvinen, Netdev, David Miller
In-Reply-To: <201001291715.57557.denys@visp.net.lb>
Denys Fedoryshchenko schrieb:
> On Friday 29 January 2010 14:13:18 Damian Lukowski wrote:
>> Denys Fedoryshchenko schrieb:
>>> On Wednesday 27 January 2010 14:36:18 you wrote:
>>>> Unless they are for a different connection? We might have to print sk
>>>> (%p) in all those printouts to be sure which maps to which. If a peer
>>>> becomes unreachable, it may well have multiple connections open (this
>>>> was a proxy, iirc?).
>>> Ok i will try to do that today.
>>>
>>> Most probably different connections, on this proxy i have 10-15k
>>> established connections at peak time.
> http://www.nuclearcat.com/files/report1.txt
> http://www.nuclearcat.com/files/report2.txt
>
> Here with %p and sk.
Ok, thanks for testing.
So it is ec0f3440 causing the trouble. Are there still objections
on the lower bound check in __tcp_set_rto()? Well, I will submit
an updated patch and you can make comments there.
Regards
Damian
^ permalink raw reply
* Re: PROBLEM: reproducible crash KVM+nf_conntrack all recent 2.6 kernels
From: Jon Masters @ 2010-01-29 21:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Patrick McHardy, linux-kernel, netdev, netfilter-devel
In-Reply-To: <1264762655.2793.409.camel@tonnant>
On Fri, 2010-01-29 at 05:57 -0500, Jon Masters wrote:
> On Fri, 2010-01-29 at 10:10 +0100, Eric Dumazet wrote:
>
> > Jon, do you have multiple network namespace active on your machine, when
> > crash occurs ?
>
> I don't believe so. I just built in Jason's latest kgdb/kdb patches and
> am going to give them a whirl to see if I can get anything more out of
> this panic than I currently have.
So, the latest crash was in here:
/* delete all expectations for this conntrack */
void nf_ct_remove_expectations(struct nf_conn *ct)
{
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_expect *exp;
struct hlist_node *n, *next;
/* Optimization: most connection never expect any others. */
if (!help)
return;
hlist_for_each_entry_safe(exp, n, next, &help->expectations,
lnode) {
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
}
}
EXPORT_SYMBOL_GPL(nf_ct_remove_expectations);
Specifically, in that hlist_for_each_entry_safe iteration, the list of
expectations is already NULL:
at net/netfilter/nf_conntrack_expect.c:174
174 hlist_for_each_entry_safe(exp, n, next,
&help->expectations, lnode) {
(gdb) bt
#0 nf_ct_remove_expectations (ct=<value optimized out>)
at net/netfilter/nf_conntrack_expect.c:174
#1 0xffffffff813e4db9 in destroy_conntrack (nfct=0xffffffff81b04e60)
at net/netfilter/nf_conntrack_core.c:202
#2 0xffffffff813e2af8 in nf_conntrack_destroy (nfct=<value optimized
out>)
at net/netfilter/core.c:243
#3 0xffffffff813bc209 in nf_conntrack_put (skb=0xffff88018fb97f00)
at include/linux/skbuff.h:1924
#4 skb_release_head_state (skb=0xffff88018fb97f00) at
net/core/skbuff.c:402
#5 0xffffffff813bbf6b in skb_release_all (skb=0xffff88018fb97f00)
at net/core/skbuff.c:420
#6 __kfree_skb (skb=0xffff88018fb97f00) at net/core/skbuff.c:435
#7 0xffffffff813bc070 in kfree_skb (skb=0xffff88018fb97f00)
at net/core/skbuff.c:456
#8 0xffffffffa03fa0a1 in ?? ()
#9 0x0000000000000050 in ?? ()
#10 0xffff8801de810780 in ?? ()
#11 0x0000000000000000 in ?? ()
(gdb) frame 1
#1 0xffffffff813e4db9 in destroy_conntrack (nfct=0xffffffff81b04e60)
at net/netfilter/nf_conntrack_core.c:202
202 nf_ct_remove_expectations(ct);
(gdb) print ct
$5 = (struct nf_conn *) 0xffffffff81b04e60
(gdb) print ct->
ct_general ext mark proto status tuplehash
ct_net lock master secmark timeout
(gdb) print ct->ext
$10 = (struct nf_ct_ext *) 0xffff8801de3369c0
(gdb) print (struct nf_conn_help *)(ct->ext +
ct->ext->offset[NF_CT_EXT_HELPER])
$22 = (struct nf_conn_help *) 0xffff8801de337a40
(gdb) print $22->helper
$23 = (struct nf_conntrack_helper *) 0xffff8801de337a00
(gdb) print $22->help
$24 = {ct_ftp_info = {seq_aft_nl = {{0, 0}, {269970752, 4294936578}},
seq_aft_nl_num = {323805184, 32555}}, ct_pptp_info = {
sstate = PPTP_SESSION_NONE, cstate = PPTP_CALL_NONE, pac_call_id =
27968,
pns_call_id = 4119, keymap = {0x7f2b134ce000, 0xb65e2965}},
ct_h323_info = {sig_port = {0, 0}, rtp_port = {{0, 0}, {27968, 4119},
{
34818, 65535}, {57344, 4940}}, {timeout = 32555, tpkt_len =
{32555,
0}}}, ct_sane_info = {state = SANE_STATE_NORMAL}, ct_sip_info =
{
register_cseq = 0, invite_cseq = 0}}
(gdb) print $22->expectations
$25 = {first = 0x0}
(gdb) print $22->expecting
$26 = "\000\000"
(gdb) print $22->helper->hnode
$28 = {next = 0xffff8801de3379c0, pprev = 0x0}
(gdb) print $22->helper->name
$31 = 0xffff880210176d40 "\300\235\363\020\002\210\377\377\020\027\b\022
\002\210\377\377p\236\363\020\002\210\377\377T", <incomplete sequence
\337>
(gdb) print $22->helper->me
$32 = (struct module *) 0x7f2b134cf000
(gdb) print $22->helper->tuple
$36 = {src = {u3 = {all = {0, 0, 0, 0}, ip = 0, ip6 = {0, 0, 0, 0}, in =
{
s_addr = 0}, in6 = {in6_u = {u6_addr8 = '\000' <repeats 15
times>,
u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, u6_addr32 = {0, 0, 0,
0}}}},
u = {all = 0, tcp = {port = 0}, udp = {port = 0}, icmp = {id = 0},
dccp = {
port = 0}, sctp = {port = 0}, gre = {key = 0}}, l3num = 0}, dst
= {
u3 = {all = {0, 3727915520, 4294936577, 0}, ip = 0, ip6 = {0,
3727915520,
4294936577, 0}, in = {s_addr = 0}, in6 = {in6_u = {
u6_addr8 = "\000\000\000\000\000z3\336\001\210\377\377\000\000
\000",
u6_addr16 = {0, 0, 31232, 56883, 34817, 65535, 0, 0},
u6_addr32 = {
0, 3727915520, 4294936577, 0}}}}, u = {all = 0, tcp = {port
= 0},
udp = {port = 0}, icmp = {type = 0 '\000', code = 0 '\000'}, dccp
= {
port = 0}, sctp = {port = 0}, gre = {key = 0}}, protonum = 0
'\000',
dir = 0 '\000'}}
Jon.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox