[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
rpms/kernel/devel kernel-2.6.spec, 1.2473, 1.2474 linux-2.6-lockdep-fixes.patch, 1.12, 1.13
- From: fedora-cvs-commits redhat com
- To: fedora-cvs-commits redhat com
- Subject: rpms/kernel/devel kernel-2.6.spec, 1.2473, 1.2474 linux-2.6-lockdep-fixes.patch, 1.12, 1.13
- Date: Sat, 29 Jul 2006 01:24:02 -0400
Author: davej
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv27082
Modified Files:
kernel-2.6.spec linux-2.6-lockdep-fixes.patch
Log Message:
ipv6 lockdep fix
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2473
retrieving revision 1.2474
diff -u -r1.2473 -r1.2474
--- kernel-2.6.spec 28 Jul 2006 21:56:09 -0000 1.2473
+++ kernel-2.6.spec 29 Jul 2006 05:23:54 -0000 1.2474
@@ -1663,6 +1663,9 @@
%endif
%changelog
+* Sat Jul 29 2006 Dave Jones <davej redhat com>
+- lockdep fix: ipv6
+
* Fri Jul 28 2006 Don Zickus <dzickus redhat com>
- Refreshed NFS caching patches
- tweaked some ppc64 kdump config options
linux-2.6-lockdep-fixes.patch:
b/include/net/ip6_route.h | 12 +-
b/include/net/ipv6.h | 3
b/net/dccp/ipv6.c | 4
b/net/ipv6/af_inet6.c | 2
b/net/ipv6/inet6_connection_sock.c | 2
b/net/ipv6/ip6_output.c | 120 +++++++++++++++++---------
b/net/ipv6/tcp_ipv6.c | 4
b/net/ipv6/udp.c | 3
linux-2.6.17-mm6/include/net/sock.h | 33 ++++++-
linux-2.6.18-rc1/drivers/input/serio/libps2.c | 6 -
linux-2.6.18-rc1/fs/inotify_user.c | 20 +++-
linux-2.6.18-rc1/include/linux/libps2.h | 12 ++
linux-2.6.18-rc1/net/socket.c | 8 +
13 files changed, 169 insertions(+), 60 deletions(-)
Index: linux-2.6-lockdep-fixes.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-lockdep-fixes.patch,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- linux-2.6-lockdep-fixes.patch 24 Jul 2006 22:22:50 -0000 1.12
+++ linux-2.6-lockdep-fixes.patch 29 Jul 2006 05:23:55 -0000 1.13
@@ -482,3 +482,391 @@
Please read the FAQ at http://www.tux.org/lkml/
+From davej Sat Jul 29 00:35:14 2006
+Return-path: <linux-kernel-owner+davej=40kernelslacker org-S1161468AbWG2Edz vger kernel org>
+X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on
+ nwo.kernelslacker.org
+X-Spam-Level:
+X-Spam-Status: No, score=-101.8 required=5.0 tests=AWL,BAYES_00,
+ USER_IN_WHITELIST autolearn=ham version=3.1.3
+Envelope-to: davej kernelslacker org
+Delivery-date: Sat, 29 Jul 2006 05:34:29 +0100
+Received: from testure.choralone.org [194.9.77.134]
+ by nwo.kernelslacker.org with IMAP (fetchmail-6.3.4)
+ for <davej localhost> (single-drop); Sat, 29 Jul 2006 00:35:14 -0400 (EDT)
+Received: from vger.kernel.org ([209.132.176.167])
+ by testure.choralone.org with esmtp (Exim 4.62)
+ (envelope-from <linux-kernel-owner+davej=40kernelslacker org-S1161468AbWG2Edz vger kernel org>)
+ id 1G6gWy-0002hG-HE
+ for davej kernelslacker org; Sat, 29 Jul 2006 05:34:29 +0100
+Received: (majordomo vger kernel org) by vger.kernel.org via listexpand
+ id S1161468AbWG2Edz (ORCPT <rfc822;davej kernelslacker org>);
+ Sat, 29 Jul 2006 00:33:55 -0400
+Received: (majordomo vger kernel org) by vger.kernel.org id S1161464AbWG2Edz
+ (ORCPT <rfc822;linux-kernel-outgoing>);
+ Sat, 29 Jul 2006 00:33:55 -0400
+Received: from rhun.apana.org.au ([64.62.148.172]:63751 "EHLO
+ arnor.apana.org.au") by vger.kernel.org with ESMTP id S1161466AbWG2Edy
+ (ORCPT <rfc822;linux-kernel vger kernel org>);
+ Sat, 29 Jul 2006 00:33:54 -0400
+Received: from gondolin.me.apana.org.au ([192.168.0.6])
+ by arnor.apana.org.au with esmtp (Exim 4.50 #1 (Debian))
+ id 1G6gWD-0007H2-SX; Sat, 29 Jul 2006 14:33:41 +1000
+Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian))
+ id 1G6gVx-0001px-00; Sat, 29 Jul 2006 14:33:25 +1000
+Date: Sat, 29 Jul 2006 14:33:25 +1000
+To: "David S. Miller" <davem davemloft net>,
+ YOSHIFUJI Hideaki <yoshfuji linux-ipv6 org>,
+ Matt Domsch <Matt_Domsch dell com>
+Cc: linux-kernel vger kernel org, netdev vger kernel org
+Subject: [IPV6]: Audit all ip6_dst_lookup/ip6_dst_store calls
+Message-ID: <20060729043325 GA7035 gondor apana org au>
+References: <20060728194531 GA17744 lists us dell com>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+In-Reply-To: <20060728194531 GA17744 lists us dell com>
+User-Agent: Mutt/1.5.9i
+From: Herbert Xu <herbert gondor apana org au>
+Sender: linux-kernel-owner vger kernel org
+Precedence: bulk
+X-Mailing-List: linux-kernel vger kernel org
+Status: RO
+Content-Length: 10664
+Lines: 334
+
+On Fri, Jul 28, 2006 at 07:45:31PM +0000, Matt Domsch wrote:
+> Triggered on Fedora rawhide kernel-2.6.17-1.2462.fc6 x86_64 which is
+> based on 2.6.18rc2-git6. IPv6 was in use at the time.
+>
+> =================================
+> [ INFO: inconsistent lock state ]
+> ---------------------------------
+> inconsistent {softirq-on-W} -> {in-softirq-R} usage.
+> swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
+> (&sk->sk_dst_lock){---?}, at: [<ffffffff80418ef3>]
+> sk_dst_check+0x26/0x12b
+> {softirq-on-W} state was registered at:
+> [<ffffffff802a874d>] lock_acquire+0x4a/0x69
+> [<ffffffff802672a1>] _write_lock+0x24/0x31
+> [<ffffffff8044a26b>] ip4_datagram_connect+0x2e1/0x350
+> [<ffffffff80451214>] inet_dgram_connect+0x57/0x65
+> [<ffffffff8041652a>] sys_connect+0x7d/0xa4
+> [<ffffffff8025ff0d>] system_call+0x7d/0x83
+
+Thanks for the report. This is actually a false positive because
+by these two paths can't intersect since one is a UDP while the other
+is TCP.
+
+However, here is a patch which should shut up the validator as well
+as removing unnecessary locking from most callers of ip6_dst_lookup.
+
+[IPV6]: Audit all ip6_dst_lookup/ip6_dst_store calls
+
+The current users of ip6_dst_lookup can be divided into two classes:
+
+1) The caller holds no locks and is in user-context (UDP).
+2) The caller does not want to lookup the dst cache at all.
+
+The second class covers everyone except UDP because most people do
+the cache lookup directly before calling ip6_dst_lookup. This patch
+adds ip6_sk_dst_lookup for the first class.
+
+Similarly ip6_dst_store users can be divded into those that need to
+take the socket dst lock and those that don't. This patch adds
+__ip6_dst_store for those (everyone except UDP/datagram) that don't
+need an extra lock.
+
+Signed-off-by: Herbert Xu <herbert gondor apana org au>
+
+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
+--
+diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
+index ab29daf..96b0e66 100644
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -139,16 +139,22 @@ extern rwlock_t rt6_lock;
+ /*
+ * Store a destination cache entry in a socket
+ */
+-static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+- struct in6_addr *daddr)
++static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
++ struct in6_addr *daddr)
+ {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct rt6_info *rt = (struct rt6_info *) dst;
+
+- write_lock(&sk->sk_dst_lock);
+ sk_setup_caps(sk, dst);
+ np->daddr_cache = daddr;
+ np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
++}
++
++static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
++ struct in6_addr *daddr)
++{
++ write_lock(&sk->sk_dst_lock);
++ __ip6_dst_store(sk, dst, daddr);
+ write_unlock(&sk->sk_dst_lock);
+ }
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index a8fdf79..ece7e8a 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -468,6 +468,9 @@ extern void ip6_flush_pending_frames(s
+ extern int ip6_dst_lookup(struct sock *sk,
+ struct dst_entry **dst,
+ struct flowi *fl);
++extern int ip6_sk_dst_lookup(struct sock *sk,
++ struct dst_entry **dst,
++ struct flowi *fl);
+
+ /*
+ * skb processing functions
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index 9f3d4d7..610c722 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -230,7 +230,7 @@ static int dccp_v6_connect(struct sock *
+ ipv6_addr_copy(&np->saddr, saddr);
+ inet->rcv_saddr = LOOPBACK4_IPV6;
+
+- ip6_dst_store(sk, dst, NULL);
++ __ip6_dst_store(sk, dst, NULL);
+
+ icsk->icsk_ext_hdr_len = 0;
+ if (np->opt != NULL)
+@@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv
+ * comment in that function for the gory details. -acme
+ */
+
+- ip6_dst_store(newsk, dst, NULL);
++ __ip6_dst_store(newsk, dst, NULL);
+ newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
+ NETIF_F_TSO);
+ newdp6 = (struct dccp6_sock *)newsk;
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 5a0ba58..ac85e9c 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock
+ return err;
+ }
+
+- ip6_dst_store(sk, dst, NULL);
++ __ip6_dst_store(sk, dst, NULL);
+ }
+
+ return 0;
+diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
+index 5c950cc..bf49107 100644
+--- a/net/ipv6/inet6_connection_sock.c
++++ b/net/ipv6/inet6_connection_sock.c
+@@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb,
+ return err;
+ }
+
+- ip6_dst_store(sk, dst, NULL);
++ __ip6_dst_store(sk, dst, NULL);
+ }
+
+ skb->dst = dst_clone(dst);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 3bc74ce..5e74a37 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -723,48 +723,51 @@ fail:
+ return err;
+ }
+
+-int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
++static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
++ struct dst_entry *dst,
++ struct flowi *fl)
+ {
+- int err = 0;
++ struct ipv6_pinfo *np = inet6_sk(sk);
++ struct rt6_info *rt = (struct rt6_info *)dst;
+
+- *dst = NULL;
+- if (sk) {
+- struct ipv6_pinfo *np = inet6_sk(sk);
+-
+- *dst = sk_dst_check(sk, np->dst_cookie);
+- if (*dst) {
+- struct rt6_info *rt = (struct rt6_info*)*dst;
+-
+- /* Yes, checking route validity in not connected
+- * case is not very simple. Take into account,
+- * that we do not support routing by source, TOS,
+- * and MSG_DONTROUTE --ANK (980726)
+- *
+- * 1. If route was host route, check that
+- * cached destination is current.
+- * If it is network route, we still may
+- * check its validity using saved pointer
+- * to the last used address: daddr_cache.
+- * We do not want to save whole address now,
+- * (because main consumer of this service
+- * is tcp, which has not this problem),
+- * so that the last trick works only on connected
+- * sockets.
+- * 2. oif also should be the same.
+- */
+- if (((rt->rt6i_dst.plen != 128 ||
+- !ipv6_addr_equal(&fl->fl6_dst,
+- &rt->rt6i_dst.addr))
+- && (np->daddr_cache == NULL ||
+- !ipv6_addr_equal(&fl->fl6_dst,
+- np->daddr_cache)))
+- || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
+- dst_release(*dst);
+- *dst = NULL;
+- }
+- }
++ if (!dst)
++ goto out;
++
++ /* Yes, checking route validity in not connected
++ * case is not very simple. Take into account,
++ * that we do not support routing by source, TOS,
++ * and MSG_DONTROUTE --ANK (980726)
++ *
++ * 1. If route was host route, check that
++ * cached destination is current.
++ * If it is network route, we still may
++ * check its validity using saved pointer
++ * to the last used address: daddr_cache.
++ * We do not want to save whole address now,
++ * (because main consumer of this service
++ * is tcp, which has not this problem),
++ * so that the last trick works only on connected
++ * sockets.
++ * 2. oif also should be the same.
++ */
++ if (((rt->rt6i_dst.plen != 128 ||
++ !ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr))
++ && (np->daddr_cache == NULL ||
++ !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache)))
++ || (fl->oif && fl->oif != dst->dev->ifindex)) {
++ dst_release(dst);
++ dst = NULL;
+ }
+
++out:
++ return dst;
++}
++
++static int ip6_dst_lookup_tail(struct sock *sk,
++ struct dst_entry **dst, struct flowi *fl)
++{
++ int err;
++
+ if (*dst == NULL)
+ *dst = ip6_route_output(sk, fl);
+
+@@ -773,7 +776,6 @@ int ip6_dst_lookup(struct sock *sk, stru
+
+ if (ipv6_addr_any(&fl->fl6_src)) {
+ err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
+-
+ if (err)
+ goto out_err_release;
+ }
+@@ -786,8 +788,48 @@ out_err_release:
+ return err;
+ }
+
++/**
++ * ip6_dst_lookup - perform route lookup on flow
++ * @sk: socket which provides route info
++ * @dst: pointer to dst_entry * for result
++ * @fl: flow to lookup
++ *
++ * This function performs a route lookup on the given flow.
++ *
++ * It returns zero on success, or a standard errno code on error.
++ */
++int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
++{
++ *dst = NULL;
++ return ip6_dst_lookup_tail(sk, dst, fl);
++}
+ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
+
++/**
++ * ip6_sk_dst_lookup - perform socket cached route lookup on flow
++ * @sk: socket which provides the dst cache and route info
++ * @dst: pointer to dst_entry * for result
++ * @fl: flow to lookup
++ *
++ * This function performs a route lookup on the given flow with the
++ * possibility of using the cached route in the socket if it is valid.
++ * It will take the socket dst lock when operating on the dst cache.
++ * As a result, this function can only be used in process context.
++ *
++ * It returns zero on success, or a standard errno code on error.
++ */
++int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
++{
++ *dst = NULL;
++ if (sk) {
++ *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
++ *dst = ip6_sk_dst_check(sk, *dst, fl);
++ }
++
++ return ip6_dst_lookup_tail(sk, dst, fl);
++}
++EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup);
++
+ static inline int ip6_ufo_append_data(struct sock *sk,
+ int getfrag(void *from, char *to, int offset, int len,
+ int odd, struct sk_buff *skb),
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 923989d..b76fd7f 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *s
+ inet->rcv_saddr = LOOPBACK4_IPV6;
+
+ sk->sk_gso_type = SKB_GSO_TCPV6;
+- ip6_dst_store(sk, dst, NULL);
++ __ip6_dst_store(sk, dst, NULL);
+
+ icsk->icsk_ext_hdr_len = 0;
+ if (np->opt)
+@@ -947,7 +947,7 @@ static struct sock * tcp_v6_syn_recv_soc
+ */
+
+ sk->sk_gso_type = SKB_GSO_TCPV6;
+- ip6_dst_store(newsk, dst, NULL);
++ __ip6_dst_store(newsk, dst, NULL);
+
+ newtcp6sk = (struct tcp6_sock *)newsk;
+ inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index ccc57f4..3d54f24 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -782,7 +782,7 @@ do_udp_sendmsg:
+ connected = 0;
+ }
+
+- err = ip6_dst_lookup(sk, &dst, fl);
++ err = ip6_sk_dst_lookup(sk, &dst, fl);
+ if (err)
+ goto out;
+ if (final_p)
+-
+To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
+the body of a message to majordomo vger kernel org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+Please read the FAQ at http://www.tux.org/lkml/
+
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]