From patchwork Mon Oct 6 18:50:08 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 2975 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 90B5EDDFBA for ; Tue, 7 Oct 2008 06:50:27 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753559AbYJFTuW (ORCPT ); Mon, 6 Oct 2008 15:50:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753030AbYJFTuW (ORCPT ); Mon, 6 Oct 2008 15:50:22 -0400 Received: from vms172067pub.verizon.net ([206.46.172.67]:54165 "EHLO vms172067pub.verizon.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752863AbYJFTuV (ORCPT ); Mon, 6 Oct 2008 15:50:21 -0400 X-Greylist: delayed 3601 seconds by postgrey-1.27 at vger.kernel.org; Mon, 06 Oct 2008 15:50:21 EDT Received: from wf-rch.minyard.local ([96.226.138.225]) by vms172067.mailsrvcs.net (Sun Java System Messaging Server 6.2-6.01 (built Apr 3 2006)) with ESMTPA id <0K8B007TUYZLEUD0@vms172067.mailsrvcs.net>; Mon, 06 Oct 2008 13:50:09 -0500 (CDT) Received: from i2 (i2.minyard.local [192.168.27.126]) by wf-rch.minyard.local (Postfix) with ESMTP id C7B911F834; Mon, 06 Oct 2008 13:50:08 -0500 (CDT) Date: Mon, 06 Oct 2008 13:50:08 -0500 From: Corey Minyard Subject: [PATCH 2/3] Add RCU versions of socket hlist handling To: Linux Kernel , netdev@vger.kernel.org Cc: shemminger@vyatta.com, paulmck@linux.vnet.ibm.com Reply-to: minyard@acm.org Message-id: <20081006185008.GA10366@minyard.local> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add RCU version of some of the socket hlist handlers, getting ready for changing the UDP hash lock to RCU. Signed-off-by: Corey Minyard --- include/net/sock.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 06c5259..6cd39e5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -294,12 +295,24 @@ static inline struct sock *sk_head(const struct hlist_head *head) return hlist_empty(head) ? NULL : __sk_head(head); } +static inline struct sock *sk_head_rcu(const struct hlist_head *head) +{ + struct hlist_node *first = rcu_dereference(head->first); + return first ? hlist_entry(first, struct sock, sk_node) : NULL; +} + static inline struct sock *sk_next(const struct sock *sk) { return sk->sk_node.next ? hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL; } +static inline struct sock *sk_next_rcu(const struct sock *sk) +{ + struct hlist_node *next = rcu_dereference(sk->sk_node.next); + return next ? hlist_entry(next, struct sock, sk_node) : NULL; +} + static inline int sk_unhashed(const struct sock *sk) { return hlist_unhashed(&sk->sk_node); @@ -361,6 +374,27 @@ static __inline__ int sk_del_node_init(struct sock *sk) return rc; } +static inline int __sk_del_node_init_rcu(struct sock *sk) +{ + if (sk_hashed(sk)) { + hlist_del_init_rcu(&sk->sk_node); + return 1; + } + return 0; +} + +static inline int sk_del_node_init_rcu(struct sock *sk) +{ + int rc = __sk_del_node_init_rcu(sk); + + if (rc) { + /* paranoid for a while -acme */ + WARN_ON(atomic_read(&sk->sk_refcnt) == 1); + __sock_put(sk); + } + return rc; +} + static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_node, list); @@ -372,6 +406,17 @@ static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) __sk_add_node(sk, list); } +static inline void __sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +{ + hlist_add_head_rcu(&sk->sk_node, list); +} + +static inline void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +{ + sock_hold(sk); + __sk_add_node_rcu(sk, list); +} + static __inline__ void __sk_del_bind_node(struct sock *sk) { __hlist_del(&sk->sk_bind_node); @@ -385,9 +430,14 @@ static __inline__ void sk_add_bind_node(struct sock *sk, #define sk_for_each(__sk, node, list) \ hlist_for_each_entry(__sk, node, list, sk_node) +#define sk_for_each_rcu(__sk, node, list) \ + hlist_for_each_entry_rcu(__sk, node, list, sk_node) #define sk_for_each_from(__sk, node) \ if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ hlist_for_each_entry_from(__sk, node, sk_node) +#define sk_for_each_from_rcu(__sk, node) \ + if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ + hlist_for_each_entry_from_rcu(__sk, node, sk_node) #define sk_for_each_continue(__sk, node) \ if (__sk && ({ node = &(__sk)->sk_node; 1; })) \ hlist_for_each_entry_continue(__sk, node, sk_node)