[PATCH v3 14/17] net,rds: use new hashtable implementation
Switch rds to use the new hashtable implementation. This reduces the amount of generic unrelated code in rds. Signed-off-by: Sasha Levin --- net/rds/bind.c | 28 +- net/rds/connection.c | 102 ++ 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/net/rds/bind.c b/net/rds/bind.c index 637bde5..79d65ce 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -36,16 +36,16 @@ #include #include #include +#include #include "rds.h" -#define BIND_HASH_SIZE 1024 -static struct hlist_head bind_hash_table[BIND_HASH_SIZE]; +#define BIND_HASH_BITS 10 +static DEFINE_HASHTABLE(bind_hash_table, BIND_HASH_BITS); static DEFINE_SPINLOCK(rds_bind_lock); -static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port) +static u32 rds_hash(__be32 addr, __be16 port) { - return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) & - (BIND_HASH_SIZE - 1)); + return jhash_2words((u32)addr, (u32)port, 0); } static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, @@ -53,12 +53,12 @@ static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, { struct rds_sock *rs; struct hlist_node *node; - struct hlist_head *head = hash_to_bucket(addr, port); + u32 key = rds_hash(addr, port); u64 cmp; u64 needle = ((u64)be32_to_cpu(addr) << 32) | be16_to_cpu(port); rcu_read_lock(); - hlist_for_each_entry_rcu(rs, node, head, rs_bound_node) { + hash_for_each_possible_rcu(bind_hash_table, rs, node, rs_bound_node, key) { cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) | be16_to_cpu(rs->rs_bound_port); @@ -74,13 +74,13 @@ static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, * make sure our addr and port are set before * we are added to the list, other people * in rcu will find us as soon as the -* hlist_add_head_rcu is done +* hash_add_rcu is done */ insert->rs_bound_addr = addr; insert->rs_bound_port = port; rds_sock_addref(insert); - hlist_add_head_rcu(>rs_bound_node, head); + hash_add_rcu(bind_hash_table, >rs_bound_node, key); } return NULL; } @@ -152,7 +152,7 @@ void rds_remove_bound(struct rds_sock *rs) rs, >rs_bound_addr, ntohs(rs->rs_bound_port)); - hlist_del_init_rcu(>rs_bound_node); + hash_del_rcu(>rs_bound_node); rds_sock_put(rs); rs->rs_bound_addr = 0; } @@ -202,3 +202,11 @@ out: synchronize_rcu(); return ret; } + +static int __init rds_init(void) +{ + hash_init(bind_hash_table); + return 0; +} + +module_init(rds_init); diff --git a/net/rds/connection.c b/net/rds/connection.c index 9e07c75..5b09ee1 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -34,28 +34,24 @@ #include #include #include +#include #include #include "rds.h" #include "loop.h" #define RDS_CONNECTION_HASH_BITS 12 -#define RDS_CONNECTION_HASH_ENTRIES (1 << RDS_CONNECTION_HASH_BITS) -#define RDS_CONNECTION_HASH_MASK (RDS_CONNECTION_HASH_ENTRIES - 1) /* converting this to RCU is a chore for another day.. */ static DEFINE_SPINLOCK(rds_conn_lock); static unsigned long rds_conn_count; -static struct hlist_head rds_conn_hash[RDS_CONNECTION_HASH_ENTRIES]; +static DEFINE_HASHTABLE(rds_conn_hash, RDS_CONNECTION_HASH_BITS); static struct kmem_cache *rds_conn_slab; -static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) +static unsigned long rds_conn_hashfn(__be32 laddr, __be32 faddr) { /* Pass NULL, don't need struct net for hash */ - unsigned long hash = inet_ehashfn(NULL, - be32_to_cpu(laddr), 0, - be32_to_cpu(faddr), 0); - return _conn_hash[hash & RDS_CONNECTION_HASH_MASK]; + return inet_ehashfn(NULL, be32_to_cpu(laddr), 0, be32_to_cpu(faddr), 0); } #define rds_conn_info_set(var, test, suffix) do { \ @@ -64,14 +60,14 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) } while (0) /* rcu read lock must be held or the connection spinlock */ -static struct rds_connection *rds_conn_lookup(struct hlist_head *head, - __be32 laddr, __be32 faddr, +static struct rds_connection *rds_conn_lookup(__be32 laddr, __be32 faddr, struct rds_transport *trans) { struct rds_connection *conn, *ret = NULL; struct hlist_node *pos; + unsigned long key = rds_conn_hashfn(laddr, faddr); - hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { +
[PATCH v3 14/17] net,rds: use new hashtable implementation
Switch rds to use the new hashtable implementation. This reduces the amount of generic unrelated code in rds. Signed-off-by: Sasha Levin levinsasha...@gmail.com --- net/rds/bind.c | 28 +- net/rds/connection.c | 102 ++ 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/net/rds/bind.c b/net/rds/bind.c index 637bde5..79d65ce 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -36,16 +36,16 @@ #include linux/if_arp.h #include linux/jhash.h #include linux/ratelimit.h +#include linux/hashtable.h #include rds.h -#define BIND_HASH_SIZE 1024 -static struct hlist_head bind_hash_table[BIND_HASH_SIZE]; +#define BIND_HASH_BITS 10 +static DEFINE_HASHTABLE(bind_hash_table, BIND_HASH_BITS); static DEFINE_SPINLOCK(rds_bind_lock); -static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port) +static u32 rds_hash(__be32 addr, __be16 port) { - return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) - (BIND_HASH_SIZE - 1)); + return jhash_2words((u32)addr, (u32)port, 0); } static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, @@ -53,12 +53,12 @@ static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, { struct rds_sock *rs; struct hlist_node *node; - struct hlist_head *head = hash_to_bucket(addr, port); + u32 key = rds_hash(addr, port); u64 cmp; u64 needle = ((u64)be32_to_cpu(addr) 32) | be16_to_cpu(port); rcu_read_lock(); - hlist_for_each_entry_rcu(rs, node, head, rs_bound_node) { + hash_for_each_possible_rcu(bind_hash_table, rs, node, rs_bound_node, key) { cmp = ((u64)be32_to_cpu(rs-rs_bound_addr) 32) | be16_to_cpu(rs-rs_bound_port); @@ -74,13 +74,13 @@ static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, * make sure our addr and port are set before * we are added to the list, other people * in rcu will find us as soon as the -* hlist_add_head_rcu is done +* hash_add_rcu is done */ insert-rs_bound_addr = addr; insert-rs_bound_port = port; rds_sock_addref(insert); - hlist_add_head_rcu(insert-rs_bound_node, head); + hash_add_rcu(bind_hash_table, insert-rs_bound_node, key); } return NULL; } @@ -152,7 +152,7 @@ void rds_remove_bound(struct rds_sock *rs) rs, rs-rs_bound_addr, ntohs(rs-rs_bound_port)); - hlist_del_init_rcu(rs-rs_bound_node); + hash_del_rcu(rs-rs_bound_node); rds_sock_put(rs); rs-rs_bound_addr = 0; } @@ -202,3 +202,11 @@ out: synchronize_rcu(); return ret; } + +static int __init rds_init(void) +{ + hash_init(bind_hash_table); + return 0; +} + +module_init(rds_init); diff --git a/net/rds/connection.c b/net/rds/connection.c index 9e07c75..5b09ee1 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -34,28 +34,24 @@ #include linux/list.h #include linux/slab.h #include linux/export.h +#include linux/hashtable.h #include net/inet_hashtables.h #include rds.h #include loop.h #define RDS_CONNECTION_HASH_BITS 12 -#define RDS_CONNECTION_HASH_ENTRIES (1 RDS_CONNECTION_HASH_BITS) -#define RDS_CONNECTION_HASH_MASK (RDS_CONNECTION_HASH_ENTRIES - 1) /* converting this to RCU is a chore for another day.. */ static DEFINE_SPINLOCK(rds_conn_lock); static unsigned long rds_conn_count; -static struct hlist_head rds_conn_hash[RDS_CONNECTION_HASH_ENTRIES]; +static DEFINE_HASHTABLE(rds_conn_hash, RDS_CONNECTION_HASH_BITS); static struct kmem_cache *rds_conn_slab; -static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) +static unsigned long rds_conn_hashfn(__be32 laddr, __be32 faddr) { /* Pass NULL, don't need struct net for hash */ - unsigned long hash = inet_ehashfn(NULL, - be32_to_cpu(laddr), 0, - be32_to_cpu(faddr), 0); - return rds_conn_hash[hash RDS_CONNECTION_HASH_MASK]; + return inet_ehashfn(NULL, be32_to_cpu(laddr), 0, be32_to_cpu(faddr), 0); } #define rds_conn_info_set(var, test, suffix) do { \ @@ -64,14 +60,14 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) } while (0) /* rcu read lock must be held or the connection spinlock */ -static struct rds_connection *rds_conn_lookup(struct hlist_head *head, - __be32 laddr, __be32 faddr, +static struct rds_connection *rds_conn_lookup(__be32 laddr, __be32 faddr, struct rds_transport *trans) { struct rds_connection *conn, *ret = NULL; struct hlist_node