Remove the code that resets the walker table. The walker table should
only be initialized in the walk init function or when a future table is
encountered. If the walker table is NULL this is the indication that
the walk has completed and this information can be used to break a
multi-call walk in the table (e.g. successive calls to nelink_dump
that are dumping elements of an rhashtable).

This also allows us to change rhashtable_walk_start to return void
since the only error it was returning was -EAGAIN for a table change.
This patch changes all the callers of rhashtable_walk_start to expect
void which eliminates logic needed to check the return value for a
rare condition. Note that -EAGAIN will be returned in a call
to rhashtable_walk_next which seems to always follow the start
of the walk so there should be no behavioral change in doing this.

Signed-off-by: Tom Herbert <t...@quantonium.net>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c       |  6 +---
 .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c   |  7 ++---
 fs/gfs2/glock.c                                    |  8 ++---
 include/linux/rhashtable.h                         |  2 +-
 include/net/sctp/sctp.h                            |  2 +-
 lib/rhashtable.c                                   | 18 ++----------
 lib/test_rhashtable.c                              |  6 +---
 net/ipv6/ila/ila_xlat.c                            |  4 +--
 net/ipv6/seg6.c                                    |  4 +--
 net/mac80211/mesh_pathtbl.c                        | 34 +++++++---------------
 net/netfilter/nft_set_hash.c                       | 10 ++-----
 net/netlink/af_netlink.c                           |  5 ++--
 net/netlink/diag.c                                 |  8 ++---
 net/sctp/proc.c                                    |  6 +---
 net/sctp/socket.c                                  | 19 +++---------
 net/tipc/socket.c                                  |  6 ++--
 16 files changed, 37 insertions(+), 108 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c 
b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index d5031f436f83..df6a57087848 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -1416,11 +1416,7 @@ bnxt_tc_flow_stats_batch_prep(struct bnxt *bp,
        void *flow_node;
        int rc, i;
 
-       rc = rhashtable_walk_start(iter);
-       if (rc && rc != -EAGAIN) {
-               i = 0;
-               goto done;
-       }
+       rhashtable_walk_start(iter);
 
        rc = 0;
        for (i = 0; i < BNXT_FLOW_STATS_BATCH_MAX; i++) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index d4a548a6a55c..6d7a10d0c45e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -765,9 +765,7 @@ static void ch_flower_stats_handler(struct work_struct 
*work)
 
        rhashtable_walk_enter(&adap->flower_tbl, &iter);
        do {
-               flower_entry = ERR_PTR(rhashtable_walk_start(&iter));
-               if (IS_ERR(flower_entry))
-                       goto walk_stop;
+               rhashtable_walk_start(&iter);
 
                while ((flower_entry = rhashtable_walk_next(&iter)) &&
                       !IS_ERR(flower_entry)) {
@@ -786,8 +784,9 @@ static void ch_flower_stats_handler(struct work_struct 
*work)
                                spin_unlock(&flower_entry->lock);
                        }
                }
-walk_stop:
+
                rhashtable_walk_stop(&iter);
+
        } while (flower_entry == ERR_PTR(-EAGAIN));
        rhashtable_walk_exit(&iter);
        mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 11066d8647d2..20d1b6e2d829 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1549,16 +1549,13 @@ static void glock_hash_walk(glock_examiner examiner, 
const struct gfs2_sbd *sdp)
        rhashtable_walk_enter(&gl_hash_table, &iter);
 
        do {
-               gl = ERR_PTR(rhashtable_walk_start(&iter));
-               if (IS_ERR(gl))
-                       goto walk_stop;
+               rhashtable_walk_start(&iter);
 
                while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl))
                        if (gl->gl_name.ln_sbd == sdp &&
                            lockref_get_not_dead(&gl->gl_lockref))
                                examiner(gl);
 
-walk_stop:
                rhashtable_walk_stop(&iter);
        } while (cond_resched(), gl == ERR_PTR(-EAGAIN));
 
@@ -1947,8 +1944,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, 
loff_t *pos)
        loff_t n = *pos;
 
        rhashtable_walk_enter(&gl_hash_table, &gi->hti);
-       if (rhashtable_walk_start(&gi->hti) != 0)
-               return NULL;
+       rhashtable_walk_start(&gi->hti);
 
        do {
                gfs2_glock_iter_next(gi);
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 361c08e35dbc..4c976bf320a8 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -378,7 +378,7 @@ void *rhashtable_insert_slow(struct rhashtable *ht, const 
void *key,
 void rhashtable_walk_enter(struct rhashtable *ht,
                           struct rhashtable_iter *iter);
 void rhashtable_walk_exit(struct rhashtable_iter *iter);
-int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);
+void rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);
 void *rhashtable_walk_next(struct rhashtable_iter *iter);
 void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);
 
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 906a9c0efa71..6f79415f6634 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -116,7 +116,7 @@ extern struct percpu_counter sctp_sockets_allocated;
 int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
 struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
 
-int sctp_transport_walk_start(struct rhashtable_iter *iter);
+void sctp_transport_walk_start(struct rhashtable_iter *iter);
 void sctp_transport_walk_stop(struct rhashtable_iter *iter);
 struct sctp_transport *sctp_transport_get_next(struct net *net,
                        struct rhashtable_iter *iter);
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index ddd7dde87c3c..eeddfb3199cd 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -736,16 +736,9 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_exit);
  * @iter:      Hash table iterator
  *
  * Start a hash table walk at the current iterator position.  Note that we take
- * the RCU lock in all cases including when we return an error.  So you must
- * always call rhashtable_walk_stop to clean up.
- *
- * Returns zero if successful.
- *
- * Returns -EAGAIN if resize event occured.  Note that the iterator
- * will rewind back to the beginning and you may use it immediately
- * by calling rhashtable_walk_next.
+ * the RCU lock so you must always call rhashtable_walk_stop to clean up.
  */
-int rhashtable_walk_start(struct rhashtable_iter *iter)
+void rhashtable_walk_start(struct rhashtable_iter *iter)
        __acquires(RCU)
 {
        struct rhashtable *ht = iter->ht;
@@ -756,13 +749,6 @@ int rhashtable_walk_start(struct rhashtable_iter *iter)
        if (iter->walker.tbl)
                list_del(&iter->walker.list);
        spin_unlock(&ht->lock);
-
-       if (!iter->walker.tbl) {
-               iter->walker.tbl = rht_dereference_rcu(ht->tbl, ht);
-               return -EAGAIN;
-       }
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(rhashtable_walk_start);
 
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index 8e83cbdc049c..76d3667fdea2 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -162,11 +162,7 @@ static void test_bucket_stats(struct rhashtable *ht, 
unsigned int entries)
                return;
        }
 
-       err = rhashtable_walk_start(&hti);
-       if (err && err != -EAGAIN) {
-               pr_warn("Test failed: iterator failed: %d\n", err);
-               return;
-       }
+       rhashtable_walk_start(&hti);
 
        while ((pos = rhashtable_walk_next(&hti))) {
                if (PTR_ERR(pos) == -EAGAIN) {
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 6eb5e68f112a..44c39c5f0638 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -512,9 +512,7 @@ static int ila_nl_dump(struct sk_buff *skb, struct 
netlink_callback *cb)
        struct ila_map *ila;
        int ret;
 
-       ret = rhashtable_walk_start(rhiter);
-       if (ret && ret != -EAGAIN)
-               goto done;
+       rhashtable_walk_start(rhiter);
 
        for (;;) {
                ila = rhashtable_walk_next(rhiter);
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index c81407770956..7f5621d09571 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -306,9 +306,7 @@ static int seg6_genl_dumphmac(struct sk_buff *skb, struct 
netlink_callback *cb)
        struct seg6_hmac_info *hinfo;
        int ret;
 
-       ret = rhashtable_walk_start(iter);
-       if (ret && ret != -EAGAIN)
-               goto done;
+       rhashtable_walk_start(iter);
 
        for (;;) {
                hinfo = rhashtable_walk_next(iter);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 86c8dfef56a4..a5125624a76d 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -257,9 +257,7 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
        if (ret)
                return NULL;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto err;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -269,7 +267,6 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
                if (i++ == idx)
                        break;
        }
-err:
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 
@@ -513,9 +510,7 @@ void mesh_plink_broken(struct sta_info *sta)
        if (ret)
                return;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -535,7 +530,6 @@ void mesh_plink_broken(struct sta_info *sta)
                                WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast);
                }
        }
-out:
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 }
@@ -584,9 +578,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
        if (ret)
                return;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -597,7 +589,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
                if (rcu_access_pointer(mpath->next_hop) == sta)
                        __mesh_path_del(tbl, mpath);
        }
-out:
+
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 }
@@ -614,9 +606,7 @@ static void mpp_flush_by_proxy(struct ieee80211_sub_if_data 
*sdata,
        if (ret)
                return;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -627,7 +617,7 @@ static void mpp_flush_by_proxy(struct ieee80211_sub_if_data 
*sdata,
                if (ether_addr_equal(mpath->mpp, proxy))
                        __mesh_path_del(tbl, mpath);
        }
-out:
+
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 }
@@ -642,9 +632,7 @@ static void table_flush_by_iface(struct mesh_table *tbl)
        if (ret)
                return;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -653,7 +641,7 @@ static void table_flush_by_iface(struct mesh_table *tbl)
                        break;
                __mesh_path_del(tbl, mpath);
        }
-out:
+
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 }
@@ -873,9 +861,7 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data 
*sdata,
        if (ret)
                return;
 
-       ret = rhashtable_walk_start(&iter);
-       if (ret && ret != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&iter);
 
        while ((mpath = rhashtable_walk_next(&iter))) {
                if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@@ -887,7 +873,7 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data 
*sdata,
                     time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
                        __mesh_path_del(tbl, mpath);
        }
-out:
+
        rhashtable_walk_stop(&iter);
        rhashtable_walk_exit(&iter);
 }
diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
index f8166c1d5430..3f1624ee056f 100644
--- a/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -251,11 +251,7 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, 
struct nft_set *set,
        if (err)
                return;
 
-       err = rhashtable_walk_start(&hti);
-       if (err && err != -EAGAIN) {
-               iter->err = err;
-               goto out;
-       }
+       rhashtable_walk_start(&hti);
 
        while ((he = rhashtable_walk_next(&hti))) {
                if (IS_ERR(he)) {
@@ -306,9 +302,7 @@ static void nft_rhash_gc(struct work_struct *work)
        if (err)
                goto schedule;
 
-       err = rhashtable_walk_start(&hti);
-       if (err && err != -EAGAIN)
-               goto out;
+       rhashtable_walk_start(&hti);
 
        while ((he = rhashtable_walk_next(&hti))) {
                if (IS_ERR(he)) {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b9e0ee4e22f5..ab325d4d6fef 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2478,8 +2478,9 @@ static int netlink_walk_start(struct nl_seq_iter *iter)
                return err;
        }
 
-       err = rhashtable_walk_start(&iter->hti);
-       return err == -EAGAIN ? 0 : err;
+       rhashtable_walk_start(&iter->hti);
+
+       return 0;
 }
 
 static void netlink_walk_stop(struct nl_seq_iter *iter)
diff --git a/net/netlink/diag.c b/net/netlink/diag.c
index 8faa20b4d457..7dda33b9b784 100644
--- a/net/netlink/diag.c
+++ b/net/netlink/diag.c
@@ -115,11 +115,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct 
netlink_callback *cb,
        if (!s_num)
                rhashtable_walk_enter(&tbl->hash, hti);
 
-       ret = rhashtable_walk_start(hti);
-       if (ret == -EAGAIN)
-               ret = 0;
-       if (ret)
-               goto stop;
+       rhashtable_walk_start(hti);
 
        while ((nlsk = rhashtable_walk_next(hti))) {
                if (IS_ERR(nlsk)) {
@@ -146,8 +142,8 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct 
netlink_callback *cb,
                }
        }
 
-stop:
        rhashtable_walk_stop(hti);
+
        if (ret)
                goto done;
 
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 26b4be6b4172..4545bc2aff84 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -288,12 +288,8 @@ struct sctp_ht_iter {
 static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos)
 {
        struct sctp_ht_iter *iter = seq->private;
-       int err = sctp_transport_walk_start(&iter->hti);
 
-       if (err) {
-               iter->start_fail = 1;
-               return ERR_PTR(err);
-       }
+       sctp_transport_walk_start(&iter->hti);
 
        iter->start_fail = 0;
        return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 014847e25648..1dae4742cac4 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4676,20 +4676,11 @@ int sctp_get_sctp_info(struct sock *sk, struct 
sctp_association *asoc,
 EXPORT_SYMBOL_GPL(sctp_get_sctp_info);
 
 /* use callback to avoid exporting the core structure */
-int sctp_transport_walk_start(struct rhashtable_iter *iter)
+void sctp_transport_walk_start(struct rhashtable_iter *iter)
 {
-       int err;
-
        rhltable_walk_enter(&sctp_transport_hashtable, iter);
 
-       err = rhashtable_walk_start(iter);
-       if (err && err != -EAGAIN) {
-               rhashtable_walk_stop(iter);
-               rhashtable_walk_exit(iter);
-               return err;
-       }
-
-       return 0;
+       rhashtable_walk_start(iter);
 }
 
 void sctp_transport_walk_stop(struct rhashtable_iter *iter)
@@ -4780,12 +4771,10 @@ int sctp_for_each_transport(int (*cb)(struct 
sctp_transport *, void *),
                            struct net *net, int *pos, void *p) {
        struct rhashtable_iter hti;
        struct sctp_transport *tsp;
-       int ret;
+       int ret = 0;
 
 again:
-       ret = sctp_transport_walk_start(&hti);
-       if (ret)
-               return ret;
+       sctp_transport_walk_start(&hti);
 
        tsp = sctp_transport_get_idx(net, &hti, *pos + 1);
        for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) {
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 5d18c0caa92b..22c4fd8a9dfe 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2640,9 +2640,7 @@ void tipc_sk_reinit(struct net *net)
        rhashtable_walk_enter(&tn->sk_rht, &iter);
 
        do {
-               tsk = ERR_PTR(rhashtable_walk_start(&iter));
-               if (IS_ERR(tsk))
-                       goto walk_stop;
+               rhashtable_walk_start(&iter);
 
                while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) {
                        spin_lock_bh(&tsk->sk.sk_lock.slock);
@@ -2651,7 +2649,7 @@ void tipc_sk_reinit(struct net *net)
                        msg_set_orignode(msg, tn->own_addr);
                        spin_unlock_bh(&tsk->sk.sk_lock.slock);
                }
-walk_stop:
+
                rhashtable_walk_stop(&iter);
        } while (tsk == ERR_PTR(-EAGAIN));
 }
-- 
2.11.0

Reply via email to