All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Gospodarek <gospo@cumulusnetworks.com>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: David Miller <davem@davemloft.net>, netdev@vger.kernel.org
Subject: Re: [PATCH net-next 1/2] neigh: Factor out ___neigh_lookup_noref
Date: Wed, 4 Mar 2015 09:53:31 -0500	[thread overview]
Message-ID: <20150304145331.GA1551@gospo> (raw)
In-Reply-To: <87bnk9y8wb.fsf_-_@x220.int.ebiederm.org>

On Tue, Mar 03, 2015 at 05:10:44PM -0600, Eric W. Biederman wrote:
> 
> While looking at the mpls code I found myself writing yet another
> version of neigh_lookup_noref.  We currently have __ipv4_lookup_noref
> and __ipv6_lookup_noref.
> 
> So to make my work a little easier and to make it a smidge easier to
> verify/maintain the mpls code in the future I stopped and wrote
> ___neigh_lookup_noref.  Then I rewote __ipv4_lookup_noref and
> __ipv6_lookup_noref in terms of this new function.  I tested my new
> version by verifying that the same code is generated in
> ip_finish_output2 and ip6_finish_output2 where these functions are
> inlined.
> 
> To get to ___neigh_lookup_noref I added a new neighbour cache table
> function key_eq.  So that the static size of the key would be
> available.
> 
> I also added __neigh_lookup_noref for people who want to to lookup
> a neighbour table entry quickly but don't know which neibhgour table
> they are going to look up.

While I understand your intent here, you do really need to know which
neighbour table being used in order to do the look-up with your new
function, so this changelog isn't quite accurate.  I know Dave has
already accepted this patch, but it did not appear in the tree I just
updated, so hopefully there is time to fix this if you agree with me.

I realize patch 2/2 allows one to not specify a table as look-up is done
for you in neigh_xmit, but ___neigh_lookup_noref will clearly panic if
no valid table is passed.

Otherwise the patch-set looks good to me.

Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>

> 
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  include/net/arp.h       | 19 ++++--------------
>  include/net/ndisc.h     | 19 +-----------------
>  include/net/neighbour.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
>  net/core/neighbour.c    | 20 +++++--------------
>  net/decnet/dn_neigh.c   |  6 ++++++
>  net/ipv4/arp.c          |  9 ++++++++-
>  net/ipv6/ndisc.c        |  7 +++++++
>  7 files changed, 83 insertions(+), 49 deletions(-)
> 
> diff --git a/include/net/arp.h b/include/net/arp.h
> index 21ee1860abbc..5e0f891d476c 100644
> --- a/include/net/arp.h
> +++ b/include/net/arp.h
> @@ -9,28 +9,17 @@
>  
>  extern struct neigh_table arp_tbl;
>  
> -static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd)
> +static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd)
>  {
> +	u32 key = *(const u32 *)pkey;
>  	u32 val = key ^ hash32_ptr(dev);
>  
> -	return val * hash_rnd;
> +	return val * hash_rnd[0];
>  }
>  
>  static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
>  {
> -	struct neigh_hash_table *nht = rcu_dereference_bh(arp_tbl.nht);
> -	struct neighbour *n;
> -	u32 hash_val;
> -
> -	hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift);
> -	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
> -	     n != NULL;
> -	     n = rcu_dereference_bh(n->next)) {
> -		if (n->dev == dev && *(u32 *)n->primary_key == key)
> -			return n;
> -	}
> -
> -	return NULL;
> +	return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev);
>  }
>  
>  static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key)
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 6bbda34d5e59..b3a7751251b4 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -156,24 +156,7 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
>  
>  static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
>  {
> -	struct neigh_hash_table *nht;
> -	const u32 *p32 = pkey;
> -	struct neighbour *n;
> -	u32 hash_val;
> -
> -	nht = rcu_dereference_bh(nd_tbl.nht);
> -	hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
> -	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
> -	     n != NULL;
> -	     n = rcu_dereference_bh(n->next)) {
> -		u32 *n32 = (u32 *) n->primary_key;
> -		if (n->dev == dev &&
> -		    ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
> -		     (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0)
> -			return n;
> -	}
> -
> -	return NULL;
> +	return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
>  }
>  
>  static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
> diff --git a/include/net/neighbour.h b/include/net/neighbour.h
> index 9f912e4d4232..14e3f017966b 100644
> --- a/include/net/neighbour.h
> +++ b/include/net/neighbour.h
> @@ -197,6 +197,7 @@ struct neigh_table {
>  	__u32			(*hash)(const void *pkey,
>  					const struct net_device *dev,
>  					__u32 *hash_rnd);
> +	bool			(*key_eq)(const struct neighbour *, const void *pkey);
>  	int			(*constructor)(struct neighbour *);
>  	int			(*pconstructor)(struct pneigh_entry *);
>  	void			(*pdestructor)(struct pneigh_entry *);
> @@ -247,6 +248,57 @@ static inline void *neighbour_priv(const struct neighbour *n)
>  #define NEIGH_UPDATE_F_ISROUTER			0x40000000
>  #define NEIGH_UPDATE_F_ADMIN			0x80000000
>  
> +
> +static inline bool neigh_key_eq16(const struct neighbour *n, const void *pkey)
> +{
> +	return *(const u16 *)n->primary_key == *(const u16 *)pkey;
> +}
> +
> +static inline bool neigh_key_eq32(const struct neighbour *n, const void *pkey)
> +{
> +	return *(const u32 *)n->primary_key == *(const u32 *)pkey;
> +}
> +
> +static inline bool neigh_key_eq128(const struct neighbour *n, const void *pkey)
> +{
> +	const u32 *n32 = (const u32 *)n->primary_key;
> +	const u32 *p32 = pkey;
> +
> +	return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
> +		(n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0;
> +}
> +
> +static inline struct neighbour *___neigh_lookup_noref(
> +	struct neigh_table *tbl,
> +	bool (*key_eq)(const struct neighbour *n, const void *pkey),
> +	__u32 (*hash)(const void *pkey,
> +		      const struct net_device *dev,
> +		      __u32 *hash_rnd),
> +	const void *pkey,
> +	struct net_device *dev)
> +{
> +	struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht);
> +	struct neighbour *n;
> +	u32 hash_val;
> +
> +	hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
> +	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
> +	     n != NULL;
> +	     n = rcu_dereference_bh(n->next)) {
> +		if (n->dev == dev && key_eq(n, pkey))
> +			return n;
> +	}
> +
> +	return NULL;
> +}
> +
> +static inline struct neighbour *__neigh_lookup_noref(struct neigh_table *tbl,
> +						     const void *pkey,
> +						     struct net_device *dev)
> +{
> +	return ___neigh_lookup_noref(tbl, tbl->key_eq, tbl->hash, pkey, dev);
> +}
> +
>  void neigh_table_init(int index, struct neigh_table *tbl);
>  int neigh_table_clear(int index, struct neigh_table *tbl);
>  struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 0f48ea3affed..fe3c6eac5805 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -397,25 +397,15 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
>  			       struct net_device *dev)
>  {
>  	struct neighbour *n;
> -	int key_len = tbl->key_len;
> -	u32 hash_val;
> -	struct neigh_hash_table *nht;
>  
>  	NEIGH_CACHE_STAT_INC(tbl, lookups);
>  
>  	rcu_read_lock_bh();
> -	nht = rcu_dereference_bh(tbl->nht);
> -	hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
> -
> -	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
> -	     n != NULL;
> -	     n = rcu_dereference_bh(n->next)) {
> -		if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
> -			if (!atomic_inc_not_zero(&n->refcnt))
> -				n = NULL;
> -			NEIGH_CACHE_STAT_INC(tbl, hits);
> -			break;
> -		}
> +	n = __neigh_lookup_noref(tbl, pkey, dev);
> +	if (n) {
> +		if (!atomic_inc_not_zero(&n->refcnt))
> +			n = NULL;
> +		NEIGH_CACHE_STAT_INC(tbl, hits);
>  	}
>  
>  	rcu_read_unlock_bh();
> diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
> index f123c6c6748c..ee7d1cef0027 100644
> --- a/net/decnet/dn_neigh.c
> +++ b/net/decnet/dn_neigh.c
> @@ -93,12 +93,18 @@ static u32 dn_neigh_hash(const void *pkey,
>  	return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]);
>  }
>  
> +static bool dn_key_eq(const struct neighbour *neigh, const void *pkey)
> +{
> +	return neigh_key_eq16(neigh, pkey);
> +}
> +
>  struct neigh_table dn_neigh_table = {
>  	.family =			PF_DECnet,
>  	.entry_size =			NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)),
>  	.key_len =			sizeof(__le16),
>  	.protocol =			cpu_to_be16(ETH_P_DNA_RT),
>  	.hash =				dn_neigh_hash,
> +	.key_eq =			dn_key_eq,
>  	.constructor =			dn_neigh_construct,
>  	.id =				"dn_neigh_cache",
>  	.parms ={
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index 6b8aad6a0d7d..5f5c674e130a 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -122,6 +122,7 @@
>   *	Interface to generic neighbour cache.
>   */
>  static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 *hash_rnd);
> +static bool arp_key_eq(const struct neighbour *n, const void *pkey);
>  static int arp_constructor(struct neighbour *neigh);
>  static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
>  static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
> @@ -154,6 +155,7 @@ struct neigh_table arp_tbl = {
>  	.key_len	= 4,
>  	.protocol	= cpu_to_be16(ETH_P_IP),
>  	.hash		= arp_hash,
> +	.key_eq		= arp_key_eq,
>  	.constructor	= arp_constructor,
>  	.proxy_redo	= parp_redo,
>  	.id		= "arp_cache",
> @@ -209,7 +211,12 @@ static u32 arp_hash(const void *pkey,
>  		    const struct net_device *dev,
>  		    __u32 *hash_rnd)
>  {
> -	return arp_hashfn(*(u32 *)pkey, dev, *hash_rnd);
> +	return arp_hashfn(pkey, dev, hash_rnd);
> +}
> +
> +static bool arp_key_eq(const struct neighbour *neigh, const void *pkey)
> +{
> +	return neigh_key_eq32(neigh, pkey);
>  }
>  
>  static int arp_constructor(struct neighbour *neigh)
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index e363bbc2420d..247ad7c298f7 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -84,6 +84,7 @@ do {								\
>  static u32 ndisc_hash(const void *pkey,
>  		      const struct net_device *dev,
>  		      __u32 *hash_rnd);
> +static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey);
>  static int ndisc_constructor(struct neighbour *neigh);
>  static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
>  static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
> @@ -119,6 +120,7 @@ struct neigh_table nd_tbl = {
>  	.key_len =	sizeof(struct in6_addr),
>  	.protocol =	cpu_to_be16(ETH_P_IPV6),
>  	.hash =		ndisc_hash,
> +	.key_eq =	ndisc_key_eq,
>  	.constructor =	ndisc_constructor,
>  	.pconstructor =	pndisc_constructor,
>  	.pdestructor =	pndisc_destructor,
> @@ -295,6 +297,11 @@ static u32 ndisc_hash(const void *pkey,
>  	return ndisc_hashfn(pkey, dev, hash_rnd);
>  }
>  
> +static bool ndisc_key_eq(const struct neighbour *n, const void *pkey)
> +{
> +	return neigh_key_eq128(n, pkey);
> +}
> +
>  static int ndisc_constructor(struct neighbour *neigh)
>  {
>  	struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;
> -- 
> 2.2.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2015-03-04 14:53 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-25 17:09 [PATCH net-next 0/8] Basic MPLS support Eric W. Biederman
2015-02-25 17:13 ` [PATCH net-next 1/8] mpls: Refactor how the mpls module is built Eric W. Biederman
2015-02-26  2:05   ` Simon Horman
2015-02-26  2:15     ` Eric W. Biederman
2015-02-26  2:28       ` Simon Horman
2015-02-25 17:14 ` [PATCH net-next 2/8] mpls: Basic routing support Eric W. Biederman
2015-02-25 17:15 ` [PATCH net-next 3/8] mpls: Add a sysctl to control the size of the mpls label table Eric W. Biederman
2015-02-25 17:16 ` [PATCH net-next 4/8] mpls: Basic support for adding and removing routes Eric W. Biederman
2015-02-25 17:16 ` [PATCH net-next 5/8] mpls: Functions for reading and wrinting mpls labels over netlink Eric W. Biederman
2015-02-25 17:17 ` [PATCH net-next 6/8] mpls: Netlink commands to add, remove, and dump routes Eric W. Biederman
2015-02-25 17:18 ` [PATCH net-next 8/8] ipmpls: Basic device for injecting packets into an mpls tunnel Eric W. Biederman
2015-03-05  9:17   ` Vivek Venkatraman
2015-03-05 14:00     ` Eric W. Biederman
2015-03-05 16:25       ` Vivek Venkatraman
2015-03-05 19:52         ` Eric W. Biederman
2015-03-06  6:05           ` Vivek Venkatraman
2015-03-07 10:36           ` Robert Shearman
2015-03-07 21:12             ` Eric W. Biederman
2015-02-25 17:19 ` [PATCH net-next 7/8] mpls: Multicast route table change notifications Eric W. Biederman
2015-02-26  7:21   ` roopa
2015-02-26 14:03     ` Eric W. Biederman
2015-02-26 15:12       ` roopa
2015-03-05  1:56         ` Andy Gospodarek
2015-02-25 17:37 ` [PATCH iproute2] mpls: Add basic mpls support to iproute Eric W. Biederman
2015-02-26  6:58 ` [PATCH net-next 0/8] Basic MPLS support roopa
2015-02-27 21:21 ` David Miller
2015-02-28  0:58   ` Eric W. Biederman
2015-03-02  0:05     ` Shrijeet Mukherjee
2015-03-02  4:03     ` David Miller
2015-03-02  5:10       ` Eric W. Biederman
2015-03-02  5:53         ` David Miller
2015-03-02  5:59         ` [PATCH net-next 0/15] Neighbour table and ax25 cleanups Eric W. Biederman
2015-03-02  5:59           ` [PATCH net-next 01/15] ax25: In ax25_rebuild_header add missing kfree_skb Eric W. Biederman
2015-03-02  6:01           ` [PATCH net-next 02/15] rose: Set the destination address in rose_header Eric W. Biederman
2015-03-02  6:02           ` [PATCH net-next 03/15] rose: Transmit packets in rose_xmit not rose_rebuild_header Eric W. Biederman
2015-03-02  6:03           ` [PATCH net-next 04/15] ax25/kiss: Replace ax_header_ops with ax25_header_ops Eric W. Biederman
2015-03-02  6:03           ` [PATCH net-next 05/15] ax25/6pack: Replace sp_header_ops " Eric W. Biederman
2015-03-02  6:04           ` [PATCH net-next 06/15] ax25: Make ax25_header and ax25_rebuild_header static Eric W. Biederman
2015-03-02  6:05           ` [PATCH net-next 07/15] ax25: Refactor to use private neighbour operations Eric W. Biederman
2015-03-02  6:06           ` [PATCH net-next 08/15] arp: Remove special case to give AX25 it's open arp operations Eric W. Biederman
2015-03-02  6:07           ` [PATCH net-next 09/15] neigh: Move neigh_compat_output into ax25_ip.c Eric W. Biederman
2015-03-02  6:08           ` [PATCH net-next 10/15] ax25: Stop calling/abusing dev_rebuild_header Eric W. Biederman
2015-03-02  6:09           ` [PATCH net-next 11/15] ax25: Stop depending on arp_find Eric W. Biederman
2015-03-02  6:11           ` [PATCH net-next 12/15] net: Kill dev_rebuild_header Eric W. Biederman
2015-03-02  6:12           ` [PATCH net-next 13/15] arp: Kill arp_find Eric W. Biederman
2015-03-02  6:13           ` [PATCH net-next 14/15] neigh: Don't require dst in neigh_hh_init Eric W. Biederman
2015-03-02  6:14           ` [PATCH net-next 15/15] neigh: Don't require a dst in neigh_resolve_output Eric W. Biederman
2015-03-02 21:44           ` [PATCH net-next 0/15] Neighbour table and ax25 cleanups David Miller
2015-03-03 15:41             ` [PATCH net-next] ax25: Stop using magic neighbour cache operations Eric W. Biederman
2015-03-03 19:45               ` David Miller
2015-03-03 20:22                 ` Eric W. Biederman
2015-03-03 20:33                   ` David Miller
2015-03-03 23:09                     ` [PATCH net-next 0/2] Neighbour table prep for MPLS Eric W. Biederman
2015-03-03 23:10                       ` [PATCH net-next 1/2] neigh: Factor out ___neigh_lookup_noref Eric W. Biederman
2015-03-04 14:53                         ` Andy Gospodarek [this message]
2015-03-04 15:58                           ` Eric W. Biederman
2015-03-04 16:30                             ` Andy Gospodarek
2015-03-03 23:11                       ` [PATCH net-next 2/2] neigh: Add helper function neigh_xmit Eric W. Biederman
2015-03-04  1:06                       ` [PATCH net-next 0/7] Basic MPLS support take 2 Eric W. Biederman
2015-03-04  1:10                         ` [PATCH net-next 1/7] mpls: Refactor how the mpls module is built Eric W. Biederman
2015-03-04  1:10                         ` [PATCH net-next 2/7] mpls: Basic routing support Eric W. Biederman
2015-03-05 16:36                           ` Vivek Venkatraman
2015-03-05 18:42                             ` Eric W. Biederman
2015-03-04  1:11                         ` [PATCH net-next 3/7] mpls: Add a sysctl to control the size of the mpls label table Eric W. Biederman
2015-03-05  9:45                           ` Vivek Venkatraman
2015-03-05 13:22                             ` Eric W. Biederman
2015-03-05 14:38                               ` Eric W. Biederman
2015-03-05 16:49                                 ` Vivek Venkatraman
2015-03-04  1:12                         ` [PATCH net-next 4/7] mpls: Basic support for adding and removing routes Eric W. Biederman
2015-03-04  8:13                           ` roopa
2015-03-04 20:36                             ` Eric W. Biederman
2015-03-05  0:30                               ` roopa
2015-03-05  2:50                               ` Bill Fink
2015-03-05 11:54                                 ` Eric W. Biederman
2015-03-05 19:10                                   ` Bill Fink
2015-03-04  1:13                         ` [PATCH net-next 5/7] mpls: Functions for reading and wrinting mpls labels over netlink Eric W. Biederman
2015-03-04  1:13                         ` [PATCH net-next 6/7] mpls: Netlink commands to add, remove, and dump routes Eric W. Biederman
2015-03-04  1:14                         ` [PATCH net-next 7/7] mpls: Multicast route table change notifications Eric W. Biederman
2015-03-04  5:27                         ` [PATCH net-next 0/7] Basic MPLS support take 2 David Miller
2015-03-04  6:13                           ` Eric W. Biederman
2015-03-04  5:25                       ` [PATCH net-next 0/2] Neighbour table prep for MPLS David Miller
2015-03-04  5:53                         ` Eric W. Biederman
2015-03-04 14:56                           ` Andy Gospodarek
2015-03-04 21:04                           ` David Miller
2015-03-05 12:35                             ` Eric W. Biederman
2015-03-05 10:14                   ` [PATCH net-next] ax25: Stop using magic neighbour cache operations Steven Whitehouse
2015-03-06 20:44                     ` Eric W. Biederman
2015-03-14  0:33                       ` Steven Whitehouse

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=20150304145331.GA1551@gospo \
    --to=gospo@cumulusnetworks.com \
    --cc=davem@davemloft.net \
    --cc=ebiederm@xmission.com \
    --cc=netdev@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.