diff options
| author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-09-23 06:28:33 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-09-24 18:39:22 -0400 |
| commit | a43912ab1925788765208da5cd664b6f8e011d08 (patch) | |
| tree | 6f522dba1fd414b7da3999fa2da062d80a550874 | |
| parent | edf42a27e8e242e543716663e54aa2b592ea070a (diff) | |
tunnel: eliminate recursion field
It seems recursion field from "struct ip_tunnel" is not anymore needed.
recursion prevention is done at the upper level (in dev_queue_xmit()),
since we use HARD_TX_LOCK protection for tunnels.
This avoids a cache line ping pong on "struct ip_tunnel" : This structure
should be now mostly read on xmit and receive paths.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/net/ipip.h | 1 | ||||
| -rw-r--r-- | net/ipv4/ip_gre.c | 13 | ||||
| -rw-r--r-- | net/ipv4/ipip.c | 8 | ||||
| -rw-r--r-- | net/ipv6/ip6_tunnel.c | 7 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 8 |
5 files changed, 1 insertions, 36 deletions
diff --git a/include/net/ipip.h b/include/net/ipip.h index 5d3036fa1511..76e3ea6e2fe5 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h | |||
| @@ -12,7 +12,6 @@ struct ip_tunnel | |||
| 12 | struct ip_tunnel *next; | 12 | struct ip_tunnel *next; |
| 13 | struct net_device *dev; | 13 | struct net_device *dev; |
| 14 | 14 | ||
| 15 | int recursion; /* Depth of hard_start_xmit recursion */ | ||
| 16 | int err_count; /* Number of arrived ICMP errors */ | 15 | int err_count; /* Number of arrived ICMP errors */ |
| 17 | unsigned long err_time; /* Time when the last ICMP error arrived */ | 16 | unsigned long err_time; /* Time when the last ICMP error arrived */ |
| 18 | 17 | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d9645c94a067..41ada9904d31 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -66,10 +66,7 @@ | |||
| 66 | solution, but it supposes maintaing new variable in ALL | 66 | solution, but it supposes maintaing new variable in ALL |
| 67 | skb, even if no tunneling is used. | 67 | skb, even if no tunneling is used. |
| 68 | 68 | ||
| 69 | Current solution: t->recursion lock breaks dead loops. It looks | 69 | Current solution: HARD_TX_LOCK lock breaks dead loops. |
| 70 | like dev->tbusy flag, but I preferred new variable, because | ||
| 71 | the semantics is different. One day, when hard_start_xmit | ||
| 72 | will be multithreaded we will have to use skb->encapsulation. | ||
| 73 | 70 | ||
| 74 | 71 | ||
| 75 | 72 | ||
| @@ -678,11 +675,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 678 | __be32 dst; | 675 | __be32 dst; |
| 679 | int mtu; | 676 | int mtu; |
| 680 | 677 | ||
| 681 | if (tunnel->recursion++) { | ||
| 682 | stats->collisions++; | ||
| 683 | goto tx_error; | ||
| 684 | } | ||
| 685 | |||
| 686 | if (dev->type == ARPHRD_ETHER) | 678 | if (dev->type == ARPHRD_ETHER) |
| 687 | IPCB(skb)->flags = 0; | 679 | IPCB(skb)->flags = 0; |
| 688 | 680 | ||
| @@ -820,7 +812,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 820 | ip_rt_put(rt); | 812 | ip_rt_put(rt); |
| 821 | stats->tx_dropped++; | 813 | stats->tx_dropped++; |
| 822 | dev_kfree_skb(skb); | 814 | dev_kfree_skb(skb); |
| 823 | tunnel->recursion--; | ||
| 824 | return NETDEV_TX_OK; | 815 | return NETDEV_TX_OK; |
| 825 | } | 816 | } |
| 826 | if (skb->sk) | 817 | if (skb->sk) |
| @@ -888,7 +879,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 888 | nf_reset(skb); | 879 | nf_reset(skb); |
| 889 | 880 | ||
| 890 | IPTUNNEL_XMIT(); | 881 | IPTUNNEL_XMIT(); |
| 891 | tunnel->recursion--; | ||
| 892 | return NETDEV_TX_OK; | 882 | return NETDEV_TX_OK; |
| 893 | 883 | ||
| 894 | tx_error_icmp: | 884 | tx_error_icmp: |
| @@ -897,7 +887,6 @@ tx_error_icmp: | |||
| 897 | tx_error: | 887 | tx_error: |
| 898 | stats->tx_errors++; | 888 | stats->tx_errors++; |
| 899 | dev_kfree_skb(skb); | 889 | dev_kfree_skb(skb); |
| 900 | tunnel->recursion--; | ||
| 901 | return NETDEV_TX_OK; | 890 | return NETDEV_TX_OK; |
| 902 | } | 891 | } |
| 903 | 892 | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 62548cb0923c..08ccd344de7a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -402,11 +402,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 402 | __be32 dst = tiph->daddr; | 402 | __be32 dst = tiph->daddr; |
| 403 | int mtu; | 403 | int mtu; |
| 404 | 404 | ||
| 405 | if (tunnel->recursion++) { | ||
| 406 | stats->collisions++; | ||
| 407 | goto tx_error; | ||
| 408 | } | ||
| 409 | |||
| 410 | if (skb->protocol != htons(ETH_P_IP)) | 405 | if (skb->protocol != htons(ETH_P_IP)) |
| 411 | goto tx_error; | 406 | goto tx_error; |
| 412 | 407 | ||
| @@ -485,7 +480,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 485 | ip_rt_put(rt); | 480 | ip_rt_put(rt); |
| 486 | stats->tx_dropped++; | 481 | stats->tx_dropped++; |
| 487 | dev_kfree_skb(skb); | 482 | dev_kfree_skb(skb); |
| 488 | tunnel->recursion--; | ||
| 489 | return NETDEV_TX_OK; | 483 | return NETDEV_TX_OK; |
| 490 | } | 484 | } |
| 491 | if (skb->sk) | 485 | if (skb->sk) |
| @@ -523,7 +517,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 523 | nf_reset(skb); | 517 | nf_reset(skb); |
| 524 | 518 | ||
| 525 | IPTUNNEL_XMIT(); | 519 | IPTUNNEL_XMIT(); |
| 526 | tunnel->recursion--; | ||
| 527 | return NETDEV_TX_OK; | 520 | return NETDEV_TX_OK; |
| 528 | 521 | ||
| 529 | tx_error_icmp: | 522 | tx_error_icmp: |
| @@ -531,7 +524,6 @@ tx_error_icmp: | |||
| 531 | tx_error: | 524 | tx_error: |
| 532 | stats->tx_errors++; | 525 | stats->tx_errors++; |
| 533 | dev_kfree_skb(skb); | 526 | dev_kfree_skb(skb); |
| 534 | tunnel->recursion--; | ||
| 535 | return NETDEV_TX_OK; | 527 | return NETDEV_TX_OK; |
| 536 | } | 528 | } |
| 537 | 529 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 7d25bbe32110..c595bbe1ed99 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -1043,11 +1043,6 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1043 | struct net_device_stats *stats = &t->dev->stats; | 1043 | struct net_device_stats *stats = &t->dev->stats; |
| 1044 | int ret; | 1044 | int ret; |
| 1045 | 1045 | ||
| 1046 | if (t->recursion++) { | ||
| 1047 | stats->collisions++; | ||
| 1048 | goto tx_err; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | switch (skb->protocol) { | 1046 | switch (skb->protocol) { |
| 1052 | case htons(ETH_P_IP): | 1047 | case htons(ETH_P_IP): |
| 1053 | ret = ip4ip6_tnl_xmit(skb, dev); | 1048 | ret = ip4ip6_tnl_xmit(skb, dev); |
| @@ -1062,14 +1057,12 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1062 | if (ret < 0) | 1057 | if (ret < 0) |
| 1063 | goto tx_err; | 1058 | goto tx_err; |
| 1064 | 1059 | ||
| 1065 | t->recursion--; | ||
| 1066 | return NETDEV_TX_OK; | 1060 | return NETDEV_TX_OK; |
| 1067 | 1061 | ||
| 1068 | tx_err: | 1062 | tx_err: |
| 1069 | stats->tx_errors++; | 1063 | stats->tx_errors++; |
| 1070 | stats->tx_dropped++; | 1064 | stats->tx_dropped++; |
| 1071 | kfree_skb(skb); | 1065 | kfree_skb(skb); |
| 1072 | t->recursion--; | ||
| 1073 | return NETDEV_TX_OK; | 1066 | return NETDEV_TX_OK; |
| 1074 | } | 1067 | } |
| 1075 | 1068 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 0ae4f6448187..fcb539628847 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -626,11 +626,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 626 | struct in6_addr *addr6; | 626 | struct in6_addr *addr6; |
| 627 | int addr_type; | 627 | int addr_type; |
| 628 | 628 | ||
| 629 | if (tunnel->recursion++) { | ||
| 630 | stats->collisions++; | ||
| 631 | goto tx_error; | ||
| 632 | } | ||
| 633 | |||
| 634 | if (skb->protocol != htons(ETH_P_IPV6)) | 629 | if (skb->protocol != htons(ETH_P_IPV6)) |
| 635 | goto tx_error; | 630 | goto tx_error; |
| 636 | 631 | ||
| @@ -753,7 +748,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 753 | ip_rt_put(rt); | 748 | ip_rt_put(rt); |
| 754 | stats->tx_dropped++; | 749 | stats->tx_dropped++; |
| 755 | dev_kfree_skb(skb); | 750 | dev_kfree_skb(skb); |
| 756 | tunnel->recursion--; | ||
| 757 | return NETDEV_TX_OK; | 751 | return NETDEV_TX_OK; |
| 758 | } | 752 | } |
| 759 | if (skb->sk) | 753 | if (skb->sk) |
| @@ -794,7 +788,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 794 | nf_reset(skb); | 788 | nf_reset(skb); |
| 795 | 789 | ||
| 796 | IPTUNNEL_XMIT(); | 790 | IPTUNNEL_XMIT(); |
| 797 | tunnel->recursion--; | ||
| 798 | return NETDEV_TX_OK; | 791 | return NETDEV_TX_OK; |
| 799 | 792 | ||
| 800 | tx_error_icmp: | 793 | tx_error_icmp: |
| @@ -802,7 +795,6 @@ tx_error_icmp: | |||
| 802 | tx_error: | 795 | tx_error: |
| 803 | stats->tx_errors++; | 796 | stats->tx_errors++; |
| 804 | dev_kfree_skb(skb); | 797 | dev_kfree_skb(skb); |
| 805 | tunnel->recursion--; | ||
| 806 | return NETDEV_TX_OK; | 798 | return NETDEV_TX_OK; |
| 807 | } | 799 | } |
| 808 | 800 | ||
