aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-01-02 17:00:16 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-03 14:32:56 -0500
commit88d6ed15acff1cb44b1d1f3c0a393b7f7744957a (patch)
treeee25a48f8ab11d06c062480c89ba1e96c8113e57 /net/netlink
parenta4b18cda4c2676a4b4b59622b2e0394dc153e00b (diff)
rhashtable: Convert bucket iterators to take table and index
This patch is in preparation to introduce per bucket spinlocks. It extends all iterator macros to take the bucket table and bucket index. It also introduces a new rht_dereference_bucket() to handle protected accesses to buckets. It introduces a barrier() to the RCU iterators to the prevent the compiler from caching the first element. The lockdep verifier is introduced as stub which always succeeds and properly implement in the next patch when the locks are introduced. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c12
-rw-r--r--net/netlink/diag.c4
2 files changed, 11 insertions, 5 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index a5d7ed627563..57449b6089c2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2898,7 +2898,9 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
2898 const struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht); 2898 const struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
2899 2899
2900 for (j = 0; j < tbl->size; j++) { 2900 for (j = 0; j < tbl->size; j++) {
2901 rht_for_each_entry_rcu(nlk, tbl->buckets[j], node) { 2901 struct rhash_head *node;
2902
2903 rht_for_each_entry_rcu(nlk, node, tbl, j, node) {
2902 s = (struct sock *)nlk; 2904 s = (struct sock *)nlk;
2903 2905
2904 if (sock_net(s) != seq_file_net(seq)) 2906 if (sock_net(s) != seq_file_net(seq))
@@ -2926,6 +2928,8 @@ static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
2926static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2928static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2927{ 2929{
2928 struct rhashtable *ht; 2930 struct rhashtable *ht;
2931 const struct bucket_table *tbl;
2932 struct rhash_head *node;
2929 struct netlink_sock *nlk; 2933 struct netlink_sock *nlk;
2930 struct nl_seq_iter *iter; 2934 struct nl_seq_iter *iter;
2931 struct net *net; 2935 struct net *net;
@@ -2942,17 +2946,17 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2942 2946
2943 i = iter->link; 2947 i = iter->link;
2944 ht = &nl_table[i].hash; 2948 ht = &nl_table[i].hash;
2945 rht_for_each_entry(nlk, nlk->node.next, ht, node) 2949 tbl = rht_dereference_rcu(ht->tbl, ht);
2950 rht_for_each_entry_rcu_continue(nlk, node, nlk->node.next, tbl, iter->hash_idx, node)
2946 if (net_eq(sock_net((struct sock *)nlk), net)) 2951 if (net_eq(sock_net((struct sock *)nlk), net))
2947 return nlk; 2952 return nlk;
2948 2953
2949 j = iter->hash_idx + 1; 2954 j = iter->hash_idx + 1;
2950 2955
2951 do { 2956 do {
2952 const struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
2953 2957
2954 for (; j < tbl->size; j++) { 2958 for (; j < tbl->size; j++) {
2955 rht_for_each_entry(nlk, tbl->buckets[j], ht, node) { 2959 rht_for_each_entry_rcu(nlk, node, tbl, j, node) {
2956 if (net_eq(sock_net((struct sock *)nlk), net)) { 2960 if (net_eq(sock_net((struct sock *)nlk), net)) {
2957 iter->link = i; 2961 iter->link = i;
2958 iter->hash_idx = j; 2962 iter->hash_idx = j;
diff --git a/net/netlink/diag.c b/net/netlink/diag.c
index de8c74a3c061..fcca36d81a62 100644
--- a/net/netlink/diag.c
+++ b/net/netlink/diag.c
@@ -113,7 +113,9 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
113 req = nlmsg_data(cb->nlh); 113 req = nlmsg_data(cb->nlh);
114 114
115 for (i = 0; i < htbl->size; i++) { 115 for (i = 0; i < htbl->size; i++) {
116 rht_for_each_entry(nlsk, htbl->buckets[i], ht, node) { 116 struct rhash_head *pos;
117
118 rht_for_each_entry(nlsk, pos, htbl, i, node) {
117 sk = (struct sock *)nlsk; 119 sk = (struct sock *)nlsk;
118 120
119 if (!net_eq(sock_net(sk), net)) 121 if (!net_eq(sock_net(sk), net))