All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Pankratov <ap@swapped.cc>
To: acme@conectiva.com.br, ak@suse.de
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] [2.6] [1/2] hlist: replace explicit checks of hlist fields w/ func calls
Date: Tue, 10 Feb 2004 22:28:11 -0800	[thread overview]
Message-ID: <4029CB7B.3090409@swapped.cc> (raw)

Arnaldo, Andi,

I have a set of two patches that removes if() branching from
hlist_xxx() functions.

First patch replaces explicit manipulation and checks of hlist_head
and hlist_node fields with hlist_xxx() function calls. The goal
here is to hide the details of how the hlist is terminated from
the external code.

Second patch removes if's from hlist_xxx() functions. The idea
is to terminate the list not with 0, but with a pointer at a
special 'null' item. Luckily a single 'null' can be shared
between all hlists _without_ any synchronization, because its
'next' and 'pprev' fields are never read. In fact, 'next' is
not accessed at all, and 'pprev' is used only for writing.

--------------

diff -uprX dontdiff linux-2.6.2/include/linux/list.h 
linux-2.6.2.hlist/include/linux/list.h
--- linux-2.6.2/include/linux/list.h	2004-02-03 19:43:56.000000000 -0800
+++ linux-2.6.2.hlist/include/linux/list.h	2004-02-10 12:35:57.000000000 
-0800
@@ -439,6 +439,16 @@ struct hlist_node {
  #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
  #define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)

+static __inline__ void hlist_node_init(struct hlist_node *h)
+{
+	h->pprev = NULL;
+}
+
+static __inline__ int hlist_last(const struct hlist_node *h)
+{
+	return !h->next;
+}
+
  static __inline__ int hlist_unhashed(const struct hlist_node *h)
  {
  	return !h->pprev;
@@ -531,6 +541,8 @@ static __inline__ void hlist_add_after(s
  }

  #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+#define hlist_entry_safe(ptr, type, member) \
+	((ptr) == 0 ? NULL : container_of(ptr,type,member))

  /* Cannot easily do prefetch unfortunately */
  #define hlist_for_each(pos, head) \
diff -uprX dontdiff linux-2.6.2/include/net/sock.h 
linux-2.6.2.hlist/include/net/sock.h
--- linux-2.6.2/include/net/sock.h	2004-02-03 19:44:05.000000000 -0800
+++ linux-2.6.2.hlist/include/net/sock.h	2004-02-10 12:38:24.000000000 -0800
@@ -266,13 +266,12 @@ static inline struct sock *__sk_head(str

  static inline struct sock *sk_head(struct hlist_head *head)
  {
-	return hlist_empty(head) ? NULL : __sk_head(head);
+	return hlist_entry_safe(head->first, struct sock, sk_node);
  }

  static inline struct sock *sk_next(struct sock *sk)
  {
-	return sk->sk_node.next ?
-		hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL;
+	return hlist_entry_safe(sk->sk_node.next, struct sock, sk_node);
  }

  static inline int sk_unhashed(struct sock *sk)
@@ -282,12 +281,12 @@ static inline int sk_unhashed(struct soc

  static inline int sk_hashed(struct sock *sk)
  {
-	return sk->sk_node.pprev != NULL;
+	return ! hlist_unhashed(&sk->sk_node);
  }

  static __inline__ void sk_node_init(struct hlist_node *node)
  {
-	node->pprev = NULL;
+	hlist_node_init(node);
  }

  static __inline__ void __sk_del_node(struct sock *sk)
diff -uprX dontdiff linux-2.6.2/include/net/tcp.h 
linux-2.6.2.hlist/include/net/tcp.h
--- linux-2.6.2/include/net/tcp.h	2004-02-03 19:43:11.000000000 -0800
+++ linux-2.6.2.hlist/include/net/tcp.h	2004-02-10 12:47:32.000000000 -0800
@@ -102,7 +102,8 @@ static inline struct tcp_bind_bucket *__

  static inline struct tcp_bind_bucket *tb_head(struct 
tcp_bind_hashbucket *head)
  {
-	return hlist_empty(&head->chain) ? NULL : __tb_head(head);
+	return hlist_entry_safe(head->chain.first,
+				struct tcp_bind_bucket, node);
  }

  extern struct tcp_hashinfo {
@@ -237,12 +238,12 @@ static __inline__ void tw_add_bind_node(

  static inline int tw_dead_hashed(struct tcp_tw_bucket *tw)
  {
-	return tw->tw_death_node.pprev != NULL;
+	return ! hlist_unhashed(&tw->tw_death_node);
  }

  static __inline__ void tw_dead_node_init(struct tcp_tw_bucket *tw)
  {
-	tw->tw_death_node.pprev = NULL;
+	hlist_node_init(&tw->tw_death_node);
  }

  static __inline__ void __tw_del_dead_node(struct tcp_tw_bucket *tw)
diff -uprX dontdiff linux-2.6.2/net/ax25/af_ax25.c 
linux-2.6.2.hlist/net/ax25/af_ax25.c
--- linux-2.6.2/net/ax25/af_ax25.c	2004-02-03 19:44:39.000000000 -0800
+++ linux-2.6.2.hlist/net/ax25/af_ax25.c	2004-02-10 12:48:28.000000000 -0800
@@ -1860,8 +1860,8 @@ static void *ax25_info_next(struct seq_f
  {
  	++*pos;

-	return hlist_entry( ((struct ax25_cb *)v)->ax25_node.next,
-			    struct ax25_cb, ax25_node);
+	return hlist_entry_safe(((struct ax25_cb *)v)->ax25_node.next,
+				struct ax25_cb, ax25_node);
  }
  	
  static void ax25_info_stop(struct seq_file *seq, void *v)
diff -uprX dontdiff linux-2.6.2/net/ipv4/tcp_ipv4.c 
linux-2.6.2.hlist/net/ipv4/tcp_ipv4.c
--- linux-2.6.2/net/ipv4/tcp_ipv4.c	2004-02-03 19:43:41.000000000 -0800
+++ linux-2.6.2.hlist/net/ipv4/tcp_ipv4.c	2004-02-10 12:50:27.000000000 
-0800
@@ -459,7 +459,7 @@ inline struct sock *tcp_v4_lookup_listen
  	if (!hlist_empty(head)) {
  		struct inet_opt *inet = inet_sk((sk = __sk_head(head)));

-		if (inet->num == hnum && !sk->sk_node.next &&
+		if (inet->num == hnum && hlist_last(&sk->sk_node) &&
  		    (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
  		    (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
  		    !sk->sk_bound_dev_if)
@@ -736,7 +736,7 @@ ok:
   	head  = &tcp_bhash[tcp_bhashfn(snum)];
   	tb  = tcp_sk(sk)->bind_hash;
  	spin_lock_bh(&head->lock);
-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+	if (sk_head(&tb->owners) == sk && hlist_last(&sk->sk_bind_node)) {
  		__tcp_v4_hash(sk, 0);
  		spin_unlock_bh(&head->lock);
  		return 0;
@@ -2124,14 +2124,12 @@ static int tcp_v4_destroy_sock(struct so

  static inline struct tcp_tw_bucket *tw_head(struct hlist_head *head)
  {
-	return hlist_empty(head) ? NULL :
-		list_entry(head->first, struct tcp_tw_bucket, tw_node);
+	return hlist_entry_safe(head->first, struct tcp_tw_bucket, tw_node);
  }

  static inline struct tcp_tw_bucket *tw_next(struct tcp_tw_bucket *tw)
  {
-	return tw->tw_node.next ?
-		hlist_entry(tw->tw_node.next, typeof(*tw), tw_node) : NULL;
+	return hlist_entry_safe(tw->tw_node.next, typeof(*tw), tw_node);
  }

  static void *listening_get_first(struct seq_file *seq)
diff -uprX dontdiff linux-2.6.2/net/ipv6/tcp_ipv6.c 
linux-2.6.2.hlist/net/ipv6/tcp_ipv6.c
--- linux-2.6.2/net/ipv6/tcp_ipv6.c	2004-02-03 19:43:56.000000000 -0800
+++ linux-2.6.2.hlist/net/ipv6/tcp_ipv6.c	2004-02-09 21:27:23.000000000 
-0800
@@ -524,7 +524,7 @@ static int tcp_v6_hash_connect(struct so

  	spin_lock_bh(&head->lock);

-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+	if (sk_head(&tb->owners) == sk && hlist_last(&sk->sk_bind_node)) {
  		__tcp_v6_hash(sk);
  		spin_unlock_bh(&head->lock);
  		return 0;
diff -uprX dontdiff linux-2.6.2/net/netrom/nr_route.c 
linux-2.6.2.hlist/net/netrom/nr_route.c
--- linux-2.6.2/net/netrom/nr_route.c	2004-02-03 19:45:02.000000000 -0800
+++ linux-2.6.2.hlist/net/netrom/nr_route.c	2004-02-10 
12:53:10.000000000 -0800
@@ -870,7 +870,7 @@ static void *nr_node_next(struct seq_fil
  		? nr_node_list.first
  		: ((struct nr_node *)v)->node_node.next;

-	return hlist_entry(node, struct nr_node, node_node);
+	return hlist_entry_safe(node, struct nr_node, node_node);
  }

  static void nr_node_stop(struct seq_file *seq, void *v)
@@ -953,7 +953,7 @@ static void *nr_neigh_next(struct seq_fi
  		? nr_neigh_list.first
  		: ((struct nr_neigh *)v)->neigh_node.next;

-	return hlist_entry(node, struct nr_neigh, neigh_node);
+	return hlist_entry_safe(node, struct nr_neigh, neigh_node);
  }

  static void nr_neigh_stop(struct seq_file *seq, void *v)




             reply	other threads:[~2004-02-11  6:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-11  6:28 Alex Pankratov [this message]
2004-02-13 22:14 ` [PATCH] [2.6] [1/2] hlist: replace explicit checks of hlist fields w/ func calls Andi Kleen
2004-02-11  6:57   ` Alex Pankratov
2004-02-11 12:10     ` Arnaldo Carvalho de Melo
2004-02-14  0:28     ` Andi Kleen
2004-02-11 16:37       ` Alex Pankratov
2004-02-12  4:52       ` Alex Pankratov
2004-02-12  8:43         ` Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4029CB7B.3090409@swapped.cc \
    --to=ap@swapped.cc \
    --cc=acme@conectiva.com.br \
    --cc=ak@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.