From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Eric Dumazet <dada1@cosmosbay.com>
Cc: David Miller <davem@davemloft.net>,
Corey Minyard <minyard@acm.org>,
Stephen Hemminger <shemminger@vyatta.com>,
benny+usenet@amorsen.dk,
Linux Netdev List <netdev@vger.kernel.org>,
Christoph Lameter <cl@linux-foundation.org>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Evgeniy Polyakov <zbr@ioremap.net>,
Christian Bell <christian@myri.com>
Subject: Re: [PATCH 2/3] udp: Use hlist_nulls in UDP RCU code
Date: Wed, 19 Nov 2008 09:29:10 -0800 [thread overview]
Message-ID: <20081119172910.GC6753@linux.vnet.ibm.com> (raw)
In-Reply-To: <491C2867.5030807@cosmosbay.com>
On Thu, Nov 13, 2008 at 02:15:19PM +0100, Eric Dumazet wrote:
> This is a straightforward patch, using hlist_nulls infrastructure.
>
> RCUification already done on UDP two weeks ago.
>
> Using hlist_nulls permits us to avoid some memory barriers, both
> at lookup time and delete time.
>
> Patch is large because it adds new macros to include/net/sock.h.
> These macros will be used by TCP & DCCP in next patch.
Looks good, one question below about the lockless searches. If the
answer is that the search must complete undisturbed by deletions and
additions, then:
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> ---
> include/linux/rculist.h | 17 -----------
> include/net/sock.h | 57 ++++++++++++++++++++++++++++++--------
> include/net/udp.h | 2 -
> net/ipv4/udp.c | 47 ++++++++++++++-----------------
> net/ipv6/udp.c | 26 +++++++++--------
> 5 files changed, 83 insertions(+), 66 deletions(-)
>
> diff --git a/include/linux/rculist.h b/include/linux/rculist.h
> index 3ba2998..e649bd3 100644
> --- a/include/linux/rculist.h
> +++ b/include/linux/rculist.h
> @@ -383,22 +383,5 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
> ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
> pos = rcu_dereference(pos->next))
>
> -/**
> - * hlist_for_each_entry_rcu_safenext - iterate over rcu list of given type
> - * @tpos: the type * to use as a loop cursor.
> - * @pos: the &struct hlist_node to use as a loop cursor.
> - * @head: the head for your list.
> - * @member: the name of the hlist_node within the struct.
> - * @next: the &struct hlist_node to use as a next cursor
> - *
> - * Special version of hlist_for_each_entry_rcu that make sure
> - * each next pointer is fetched before each iteration.
> - */
> -#define hlist_for_each_entry_rcu_safenext(tpos, pos, head, member, next) \
> - for (pos = rcu_dereference((head)->first); \
> - pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) && \
> - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
> - pos = rcu_dereference(next))
> -
Bonus points for getting rid of a list primitive!!! ;-)
> #endif /* __KERNEL__ */
> #endif
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 8b2b821..0a63894 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -42,6 +42,7 @@
>
> #include <linux/kernel.h>
> #include <linux/list.h>
> +#include <linux/list_nulls.h>
> #include <linux/timer.h>
> #include <linux/cache.h>
> #include <linux/module.h>
> @@ -52,6 +53,7 @@
> #include <linux/security.h>
>
> #include <linux/filter.h>
> +#include <linux/rculist_nulls.h>
>
> #include <asm/atomic.h>
> #include <net/dst.h>
> @@ -106,6 +108,7 @@ struct net;
> * @skc_reuse: %SO_REUSEADDR setting
> * @skc_bound_dev_if: bound device index if != 0
> * @skc_node: main hash linkage for various protocol lookup tables
> + * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol
> * @skc_bind_node: bind hash linkage for various protocol lookup tables
> * @skc_refcnt: reference count
> * @skc_hash: hash value used with various protocol lookup tables
> @@ -120,7 +123,10 @@ struct sock_common {
> volatile unsigned char skc_state;
> unsigned char skc_reuse;
> int skc_bound_dev_if;
> - struct hlist_node skc_node;
> + union {
> + struct hlist_node skc_node;
> + struct hlist_nulls_node skc_nulls_node;
> + };
> struct hlist_node skc_bind_node;
> atomic_t skc_refcnt;
> unsigned int skc_hash;
> @@ -206,6 +212,7 @@ struct sock {
> #define sk_reuse __sk_common.skc_reuse
> #define sk_bound_dev_if __sk_common.skc_bound_dev_if
> #define sk_node __sk_common.skc_node
> +#define sk_nulls_node __sk_common.skc_nulls_node
> #define sk_bind_node __sk_common.skc_bind_node
> #define sk_refcnt __sk_common.skc_refcnt
> #define sk_hash __sk_common.skc_hash
> @@ -300,12 +307,30 @@ static inline struct sock *sk_head(const struct hlist_head *head)
> return hlist_empty(head) ? NULL : __sk_head(head);
> }
>
> +static inline struct sock *__sk_nulls_head(const struct hlist_nulls_head *head)
> +{
> + return hlist_nulls_entry(head->first, struct sock, sk_nulls_node);
> +}
> +
> +static inline struct sock *sk_nulls_head(const struct hlist_nulls_head *head)
> +{
> + return hlist_nulls_empty(head) ? NULL : __sk_nulls_head(head);
> +}
> +
> 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_nulls_next(const struct sock *sk)
> +{
> + return (!is_a_nulls(sk->sk_nulls_node.next)) ?
> + hlist_nulls_entry(sk->sk_nulls_node.next,
> + struct sock, sk_nulls_node) :
> + NULL;
> +}
> +
> static inline int sk_unhashed(const struct sock *sk)
> {
> return hlist_unhashed(&sk->sk_node);
> @@ -321,6 +346,11 @@ static __inline__ void sk_node_init(struct hlist_node *node)
> node->pprev = NULL;
> }
>
> +static __inline__ void sk_nulls_node_init(struct hlist_nulls_node *node)
> +{
> + node->pprev = NULL;
> +}
> +
> static __inline__ void __sk_del_node(struct sock *sk)
> {
> __hlist_del(&sk->sk_node);
> @@ -367,18 +397,18 @@ static __inline__ int sk_del_node_init(struct sock *sk)
> return rc;
> }
>
> -static __inline__ int __sk_del_node_init_rcu(struct sock *sk)
> +static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk)
> {
> if (sk_hashed(sk)) {
> - hlist_del_init_rcu(&sk->sk_node);
> + hlist_nulls_del_init_rcu(&sk->sk_nulls_node);
> return 1;
> }
> return 0;
> }
>
> -static __inline__ int sk_del_node_init_rcu(struct sock *sk)
> +static __inline__ int sk_nulls_del_node_init_rcu(struct sock *sk)
> {
> - int rc = __sk_del_node_init_rcu(sk);
> + int rc = __sk_nulls_del_node_init_rcu(sk);
>
> if (rc) {
> /* paranoid for a while -acme */
> @@ -399,15 +429,15 @@ 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)
> +static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
> {
> - hlist_add_head_rcu(&sk->sk_node, list);
> + hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list);
> }
>
> -static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list)
> +static __inline__ void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
> {
> sock_hold(sk);
> - __sk_add_node_rcu(sk, list);
> + __sk_nulls_add_node_rcu(sk, list);
> }
>
> static __inline__ void __sk_del_bind_node(struct sock *sk)
> @@ -423,11 +453,16 @@ 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_safenext(__sk, node, list, next) \
> - hlist_for_each_entry_rcu_safenext(__sk, node, list, sk_node, next)
> +#define sk_nulls_for_each(__sk, node, list) \
> + hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
> +#define sk_nulls_for_each_rcu(__sk, node, list) \
> + hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_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_nulls_for_each_from(__sk, node) \
> + if (__sk && ({ node = &(__sk)->sk_nulls_node; 1; })) \
> + hlist_nulls_for_each_entry_from(__sk, node, sk_nulls_node)
> #define sk_for_each_continue(__sk, node) \
> if (__sk && ({ node = &(__sk)->sk_node; 1; })) \
> hlist_for_each_entry_continue(__sk, node, sk_node)
> diff --git a/include/net/udp.h b/include/net/udp.h
> index df2bfe5..90e6ce5 100644
> --- a/include/net/udp.h
> +++ b/include/net/udp.h
> @@ -51,7 +51,7 @@ struct udp_skb_cb {
> #define UDP_SKB_CB(__skb) ((struct udp_skb_cb *)((__skb)->cb))
>
> struct udp_hslot {
> - struct hlist_head head;
> + struct hlist_nulls_head head;
> spinlock_t lock;
> } __attribute__((aligned(2 * sizeof(long))));
> struct udp_table {
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index 54badc9..fea2d87 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -127,9 +127,9 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
> const struct sock *sk2))
> {
> struct sock *sk2;
> - struct hlist_node *node;
> + struct hlist_nulls_node *node;
>
> - sk_for_each(sk2, node, &hslot->head)
> + sk_nulls_for_each(sk2, node, &hslot->head)
> if (net_eq(sock_net(sk2), net) &&
> sk2 != sk &&
> sk2->sk_hash == num &&
> @@ -189,12 +189,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
> inet_sk(sk)->num = snum;
> sk->sk_hash = snum;
> if (sk_unhashed(sk)) {
> - /*
> - * We need that previous write to sk->sk_hash committed
> - * before write to sk->next done in following add_node() variant
> - */
> - smp_wmb();
> - sk_add_node_rcu(sk, &hslot->head);
> + sk_nulls_add_node_rcu(sk, &hslot->head);
> sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
> }
> error = 0;
> @@ -261,7 +256,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
> int dif, struct udp_table *udptable)
> {
> struct sock *sk, *result;
> - struct hlist_node *node, *next;
> + struct hlist_nulls_node *node;
> unsigned short hnum = ntohs(dport);
> unsigned int hash = udp_hashfn(net, hnum);
> struct udp_hslot *hslot = &udptable->hash[hash];
> @@ -271,13 +266,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
> begin:
> result = NULL;
> badness = -1;
> - sk_for_each_rcu_safenext(sk, node, &hslot->head, next) {
> - /*
> - * lockless reader, and SLAB_DESTROY_BY_RCU items:
> - * We must check this item was not moved to another chain
> - */
> - if (udp_hashfn(net, sk->sk_hash) != hash)
> - goto begin;
> + sk_nulls_for_each_rcu(sk, node, &hslot->head) {
> score = compute_score(sk, net, saddr, hnum, sport,
> daddr, dport, dif);
> if (score > badness) {
> @@ -285,6 +274,14 @@ begin:
> badness = score;
> }
> }
> + /*
> + * if the nulls value we got at the end of this lookup is
> + * not the expected one, we must restart lookup.
> + * We probably met an item that was moved to another chain.
> + */
> + if (get_nulls_value(node) != hash)
> + goto begin;
> +
Shouldn't this check go -after- the check for "result"? Or is this a
case where the readers absolutely must have traversed a chain without
modification to be guaranteed of finding the correct result?
> if (result) {
> if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
> result = NULL;
> @@ -325,11 +322,11 @@ static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
> __be16 rmt_port, __be32 rmt_addr,
> int dif)
> {
> - struct hlist_node *node;
> + struct hlist_nulls_node *node;
> struct sock *s = sk;
> unsigned short hnum = ntohs(loc_port);
>
> - sk_for_each_from(s, node) {
> + sk_nulls_for_each_from(s, node) {
> struct inet_sock *inet = inet_sk(s);
>
> if (!net_eq(sock_net(s), net) ||
> @@ -977,7 +974,7 @@ void udp_lib_unhash(struct sock *sk)
> struct udp_hslot *hslot = &udptable->hash[hash];
>
> spin_lock_bh(&hslot->lock);
> - if (sk_del_node_init_rcu(sk)) {
> + if (sk_nulls_del_node_init_rcu(sk)) {
> inet_sk(sk)->num = 0;
> sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
> }
> @@ -1130,7 +1127,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
> int dif;
>
> spin_lock(&hslot->lock);
> - sk = sk_head(&hslot->head);
> + sk = sk_nulls_head(&hslot->head);
> dif = skb->dev->ifindex;
> sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
> if (sk) {
> @@ -1139,7 +1136,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
> do {
> struct sk_buff *skb1 = skb;
>
> - sknext = udp_v4_mcast_next(net, sk_next(sk), uh->dest,
> + sknext = udp_v4_mcast_next(net, sk_nulls_next(sk), uh->dest,
> daddr, uh->source, saddr,
> dif);
> if (sknext)
> @@ -1560,10 +1557,10 @@ static struct sock *udp_get_first(struct seq_file *seq, int start)
> struct net *net = seq_file_net(seq);
>
> for (state->bucket = start; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
> - struct hlist_node *node;
> + struct hlist_nulls_node *node;
> struct udp_hslot *hslot = &state->udp_table->hash[state->bucket];
> spin_lock_bh(&hslot->lock);
> - sk_for_each(sk, node, &hslot->head) {
> + sk_nulls_for_each(sk, node, &hslot->head) {
> if (!net_eq(sock_net(sk), net))
> continue;
> if (sk->sk_family == state->family)
> @@ -1582,7 +1579,7 @@ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
> struct net *net = seq_file_net(seq);
>
> do {
> - sk = sk_next(sk);
> + sk = sk_nulls_next(sk);
> } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
>
> if (!sk) {
> @@ -1753,7 +1750,7 @@ void __init udp_table_init(struct udp_table *table)
> int i;
>
> for (i = 0; i < UDP_HTABLE_SIZE; i++) {
> - INIT_HLIST_HEAD(&table->hash[i].head);
> + INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i);
> spin_lock_init(&table->hash[i].lock);
> }
> }
> diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
> index 8dafa36..fd2d9ad 100644
> --- a/net/ipv6/udp.c
> +++ b/net/ipv6/udp.c
> @@ -98,7 +98,7 @@ static struct sock *__udp6_lib_lookup(struct net *net,
> int dif, struct udp_table *udptable)
> {
> struct sock *sk, *result;
> - struct hlist_node *node, *next;
> + struct hlist_nulls_node *node;
> unsigned short hnum = ntohs(dport);
> unsigned int hash = udp_hashfn(net, hnum);
> struct udp_hslot *hslot = &udptable->hash[hash];
> @@ -108,19 +108,21 @@ static struct sock *__udp6_lib_lookup(struct net *net,
> begin:
> result = NULL;
> badness = -1;
> - sk_for_each_rcu_safenext(sk, node, &hslot->head, next) {
> - /*
> - * lockless reader, and SLAB_DESTROY_BY_RCU items:
> - * We must check this item was not moved to another chain
> - */
> - if (udp_hashfn(net, sk->sk_hash) != hash)
> - goto begin;
> + sk_nulls_for_each_rcu(sk, node, &hslot->head) {
> score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif);
> if (score > badness) {
> result = sk;
> badness = score;
> }
> }
> + /*
> + * if the nulls value we got at the end of this lookup is
> + * not the expected one, we must restart lookup.
> + * We probably met an item that was moved to another chain.
> + */
> + if (get_nulls_value(node) != hash)
> + goto begin;
> +
Same question as before...
> if (result) {
> if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
> result = NULL;
> @@ -374,11 +376,11 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
> __be16 rmt_port, struct in6_addr *rmt_addr,
> int dif)
> {
> - struct hlist_node *node;
> + struct hlist_nulls_node *node;
> struct sock *s = sk;
> unsigned short num = ntohs(loc_port);
>
> - sk_for_each_from(s, node) {
> + sk_nulls_for_each_from(s, node) {
> struct inet_sock *inet = inet_sk(s);
>
> if (!net_eq(sock_net(s), net))
> @@ -423,7 +425,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
> int dif;
>
> spin_lock(&hslot->lock);
> - sk = sk_head(&hslot->head);
> + sk = sk_nulls_head(&hslot->head);
> dif = inet6_iif(skb);
> sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
> if (!sk) {
> @@ -432,7 +434,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
> }
>
> sk2 = sk;
> - while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr,
> + while ((sk2 = udp_v6_mcast_next(net, sk_nulls_next(sk2), uh->dest, daddr,
> uh->source, saddr, dif))) {
> struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
> if (buff) {
next prev parent reply other threads:[~2008-11-19 17:29 UTC|newest]
Thread overview: 134+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-06 18:50 [PATCH 3/3] Convert the UDP hash lock to RCU Corey Minyard
2008-10-06 21:22 ` Eric Dumazet
2008-10-06 21:40 ` David Miller
2008-10-06 23:08 ` Corey Minyard
2008-10-07 8:37 ` Evgeniy Polyakov
2008-10-07 14:16 ` Christoph Lameter
2008-10-07 14:29 ` Evgeniy Polyakov
2008-10-07 14:38 ` Christoph Lameter
2008-10-07 14:33 ` Paul E. McKenney
2008-10-07 14:45 ` Christoph Lameter
2008-10-07 15:07 ` Eric Dumazet
2008-10-07 15:07 ` Paul E. McKenney
2008-10-07 5:24 ` Eric Dumazet
2008-10-07 8:54 ` Benny Amorsen
2008-10-07 12:59 ` Eric Dumazet
2008-10-07 14:07 ` Stephen Hemminger
2008-10-07 20:55 ` David Miller
2008-10-07 21:20 ` Stephen Hemminger
2008-10-08 13:55 ` Eric Dumazet
2008-10-08 18:45 ` David Miller
2008-10-28 20:37 ` [PATCH 1/2] udp: introduce struct udp_table and multiple rwlocks Eric Dumazet
2008-10-28 21:23 ` Christian Bell
2008-10-28 21:31 ` Evgeniy Polyakov
2008-10-28 21:48 ` Eric Dumazet
2008-10-28 21:28 ` Evgeniy Polyakov
2008-10-28 20:42 ` [PATCH 2/2] udp: RCU handling for Unicast packets Eric Dumazet
2008-10-28 22:45 ` Eric Dumazet
2008-10-29 5:05 ` David Miller
2008-10-29 8:23 ` Eric Dumazet
2008-10-29 8:56 ` David Miller
2008-10-29 10:19 ` Eric Dumazet
2008-10-29 18:19 ` David Miller
2008-10-29 9:04 ` Eric Dumazet
2008-10-29 9:17 ` David Miller
2008-10-29 13:17 ` Corey Minyard
2008-10-29 14:36 ` Eric Dumazet
2008-10-29 15:34 ` Corey Minyard
2008-10-29 16:09 ` Eric Dumazet
2008-10-29 16:37 ` Paul E. McKenney
2008-10-29 17:22 ` Corey Minyard
2008-10-29 17:45 ` Eric Dumazet
2008-10-29 18:28 ` Corey Minyard
2008-10-29 18:52 ` Paul E. McKenney
2008-10-29 20:00 ` Eric Dumazet
2008-10-29 20:17 ` Paul E. McKenney
2008-10-29 21:29 ` Corey Minyard
2008-10-29 21:57 ` Eric Dumazet
2008-10-29 21:58 ` Paul E. McKenney
2008-10-29 22:08 ` Eric Dumazet
2008-10-30 3:22 ` Corey Minyard
2008-10-30 5:50 ` Eric Dumazet
2008-11-02 4:19 ` David Miller
2008-10-30 5:40 ` David Miller
2008-10-30 5:51 ` Eric Dumazet
2008-10-30 7:04 ` Eric Dumazet
2008-10-30 7:05 ` David Miller
2008-10-30 15:40 ` [PATCH] udp: Introduce special NULL pointers for hlist termination Eric Dumazet
2008-10-30 15:51 ` Stephen Hemminger
2008-10-30 16:28 ` Corey Minyard
2008-10-31 14:37 ` Eric Dumazet
2008-10-31 14:55 ` Pavel Emelyanov
2008-11-02 4:22 ` David Miller
2008-10-30 17:12 ` Eric Dumazet
2008-10-31 7:51 ` David Miller
2008-10-30 16:01 ` Peter Zijlstra
2008-10-31 0:14 ` Keith Owens
2008-11-13 13:13 ` [PATCH 0/3] net: RCU lookups for UDP, DCCP and TCP protocol Eric Dumazet
2008-11-13 17:20 ` Andi Kleen
2008-11-17 3:41 ` David Miller
2008-11-19 19:52 ` Christoph Lameter
2008-11-13 13:14 ` [PATCH 1/3] rcu: Introduce hlist_nulls variant of hlist Eric Dumazet
2008-11-13 13:29 ` Peter Zijlstra
2008-11-13 13:44 ` Eric Dumazet
2008-11-13 16:02 ` [PATCH 4/3] rcu: documents rculist_nulls Eric Dumazet
2008-11-14 15:16 ` Peter Zijlstra
2008-11-17 3:36 ` David Miller
2008-11-19 17:07 ` Paul E. McKenney
2008-11-14 15:16 ` [PATCH 1/3] rcu: Introduce hlist_nulls variant of hlist Peter Zijlstra
2008-11-19 17:01 ` Paul E. McKenney
2008-11-19 17:53 ` Eric Dumazet
2008-11-19 18:46 ` Paul E. McKenney
2008-11-19 18:53 ` Arnaldo Carvalho de Melo
2008-11-19 21:17 ` Paul E. McKenney
2008-11-19 20:39 ` Eric Dumazet
2008-11-19 21:21 ` Paul E. McKenney
2008-11-13 13:15 ` [PATCH 2/3] udp: Use hlist_nulls in UDP RCU code Eric Dumazet
2008-11-19 17:29 ` Paul E. McKenney [this message]
2008-11-19 17:53 ` Eric Dumazet
2008-11-13 13:15 ` [PATCH 3/3] net: Convert TCP & DCCP hash tables to use RCU / hlist_nulls Eric Dumazet
2008-11-13 13:34 ` Peter Zijlstra
2008-11-13 13:51 ` Eric Dumazet
2008-11-13 14:08 ` Christoph Lameter
2008-11-13 14:22 ` Peter Zijlstra
2008-11-13 14:27 ` Christoph Lameter
2008-11-19 17:53 ` Paul E. McKenney
2008-11-23 9:33 ` [PATCH] net: Convert TCP/DCCP listening hash tables to use RCU Eric Dumazet
2008-11-23 15:59 ` Paul E. McKenney
2008-11-23 18:42 ` Eric Dumazet
2008-11-23 19:17 ` Paul E. McKenney
2008-11-23 20:18 ` Eric Dumazet
2008-11-23 22:33 ` Paul E. McKenney
2008-11-24 1:23 ` David Miller
2008-10-30 11:04 ` [PATCH 2/2] udp: RCU handling for Unicast packets Peter Zijlstra
2008-10-30 11:30 ` Eric Dumazet
2008-10-30 18:25 ` Paul E. McKenney
2008-10-31 16:40 ` Eric Dumazet
2008-11-01 3:10 ` Paul E. McKenney
2008-10-29 17:32 ` Eric Dumazet
2008-10-29 18:11 ` Paul E. McKenney
2008-10-29 18:29 ` David Miller
2008-10-29 18:38 ` Paul E. McKenney
2008-10-29 18:36 ` Eric Dumazet
2008-10-29 18:20 ` David Miller
2008-10-30 11:12 ` Peter Zijlstra
2008-10-30 11:29 ` Eric Dumazet
2008-10-28 20:37 ` [PATCH 0/2] udp: Convert the UDP hash lock to RCU Eric Dumazet
2008-10-28 21:28 ` Stephen Hemminger
2008-10-28 21:50 ` Eric Dumazet
2008-10-07 16:43 ` [PATCH 3/3] " Corey Minyard
2008-10-07 18:26 ` David Miller
2008-10-08 8:35 ` Eric Dumazet
2008-10-08 16:38 ` David Miller
2008-10-07 8:31 ` Peter Zijlstra
2008-10-07 14:36 ` Paul E. McKenney
2008-10-07 18:29 ` David Miller
2008-10-06 22:07 ` Corey Minyard
2008-10-07 8:17 ` Peter Zijlstra
2008-10-07 9:24 ` Eric Dumazet
2008-10-07 14:15 ` Christoph Lameter
2008-10-07 14:38 ` Paul E. McKenney
2008-10-07 14:50 ` Eric Dumazet
2008-10-07 15:05 ` Paul E. McKenney
2008-10-07 15:09 ` Peter Zijlstra
2008-10-07 15:23 ` Christoph Lameter
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=20081119172910.GC6753@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=a.p.zijlstra@chello.nl \
--cc=benny+usenet@amorsen.dk \
--cc=christian@myri.com \
--cc=cl@linux-foundation.org \
--cc=dada1@cosmosbay.com \
--cc=davem@davemloft.net \
--cc=minyard@acm.org \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
--cc=zbr@ioremap.net \
/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.