rhashtable: Change rhashtable_walk_start to return void

Most callers of rhashtable_walk_start don't care about a resize event
which is indicated by a return value of -EAGAIN. So calls to
rhashtable_walk_start are wrapped wih code to ignore -EAGAIN. Something
like this is common:

       ret = rhashtable_walk_start(rhiter);
       if (ret && ret != -EAGAIN)
               goto out;

Since zero and -EAGAIN are the only possible return values from the
function this check is pointless. The condition never evaluates to true.

This patch changes rhashtable_walk_start to return void. This simplifies
code for the callers that ignore -EAGAIN. For the few cases where the
caller cares about the resize event, particularly where the table can be
walked in mulitple parts for netlink or seq file dump, the function
rhashtable_walk_start_check has been added that returns -EAGAIN on a
resize event.

Signed-off-by: Tom Herbert <tom@quantonium.net>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Tom Herbert 2017-12-04 10:31:41 -08:00 коммит произвёл David S. Miller
Родитель a0b586fa75
Коммит 97a6ec4ac0
16 изменённых файлов: 48 добавлений и 94 удалений

Просмотреть файл

@ -1412,11 +1412,7 @@ bnxt_tc_flow_stats_batch_prep(struct bnxt *bp,
void *flow_node; void *flow_node;
int rc, i; int rc, i;
rc = rhashtable_walk_start(iter); rhashtable_walk_start(iter);
if (rc && rc != -EAGAIN) {
i = 0;
goto done;
}
rc = 0; rc = 0;
for (i = 0; i < BNXT_FLOW_STATS_BATCH_MAX; i++) { for (i = 0; i < BNXT_FLOW_STATS_BATCH_MAX; i++) {

Просмотреть файл

@ -763,9 +763,7 @@ static void ch_flower_stats_handler(struct work_struct *work)
rhashtable_walk_enter(&adap->flower_tbl, &iter); rhashtable_walk_enter(&adap->flower_tbl, &iter);
do { do {
flower_entry = ERR_PTR(rhashtable_walk_start(&iter)); rhashtable_walk_start(&iter);
if (IS_ERR(flower_entry))
goto walk_stop;
while ((flower_entry = rhashtable_walk_next(&iter)) && while ((flower_entry = rhashtable_walk_next(&iter)) &&
!IS_ERR(flower_entry)) { !IS_ERR(flower_entry)) {
@ -784,8 +782,9 @@ static void ch_flower_stats_handler(struct work_struct *work)
spin_unlock(&flower_entry->lock); spin_unlock(&flower_entry->lock);
} }
} }
walk_stop:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
} while (flower_entry == ERR_PTR(-EAGAIN)); } while (flower_entry == ERR_PTR(-EAGAIN));
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD); mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);

Просмотреть файл

@ -1549,16 +1549,13 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
rhashtable_walk_enter(&gl_hash_table, &iter); rhashtable_walk_enter(&gl_hash_table, &iter);
do { do {
gl = ERR_PTR(rhashtable_walk_start(&iter)); rhashtable_walk_start(&iter);
if (IS_ERR(gl))
goto walk_stop;
while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl))
if (gl->gl_name.ln_sbd == sdp && if (gl->gl_name.ln_sbd == sdp &&
lockref_get_not_dead(&gl->gl_lockref)) lockref_get_not_dead(&gl->gl_lockref))
examiner(gl); examiner(gl);
walk_stop:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
} while (cond_resched(), gl == ERR_PTR(-EAGAIN)); } while (cond_resched(), gl == ERR_PTR(-EAGAIN));
@ -1947,7 +1944,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos)
loff_t n = *pos; loff_t n = *pos;
rhashtable_walk_enter(&gl_hash_table, &gi->hti); rhashtable_walk_enter(&gl_hash_table, &gi->hti);
if (rhashtable_walk_start(&gi->hti) != 0) if (rhashtable_walk_start_check(&gi->hti) != 0)
return NULL; return NULL;
do { do {

Просмотреть файл

@ -378,7 +378,13 @@ void *rhashtable_insert_slow(struct rhashtable *ht, const void *key,
void rhashtable_walk_enter(struct rhashtable *ht, void rhashtable_walk_enter(struct rhashtable *ht,
struct rhashtable_iter *iter); struct rhashtable_iter *iter);
void rhashtable_walk_exit(struct rhashtable_iter *iter); void rhashtable_walk_exit(struct rhashtable_iter *iter);
int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU); int rhashtable_walk_start_check(struct rhashtable_iter *iter) __acquires(RCU);
static inline void rhashtable_walk_start(struct rhashtable_iter *iter)
{
(void)rhashtable_walk_start_check(iter);
}
void *rhashtable_walk_next(struct rhashtable_iter *iter); void *rhashtable_walk_next(struct rhashtable_iter *iter);
void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU); void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);

Просмотреть файл

@ -116,7 +116,7 @@ extern struct percpu_counter sctp_sockets_allocated;
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *); 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); void sctp_transport_walk_stop(struct rhashtable_iter *iter);
struct sctp_transport *sctp_transport_get_next(struct net *net, struct sctp_transport *sctp_transport_get_next(struct net *net,
struct rhashtable_iter *iter); struct rhashtable_iter *iter);

Просмотреть файл

@ -732,7 +732,7 @@ void rhashtable_walk_exit(struct rhashtable_iter *iter)
EXPORT_SYMBOL_GPL(rhashtable_walk_exit); EXPORT_SYMBOL_GPL(rhashtable_walk_exit);
/** /**
* rhashtable_walk_start - Start a hash table walk * rhashtable_walk_start_check - Start a hash table walk
* @iter: Hash table iterator * @iter: Hash table iterator
* *
* Start a hash table walk at the current iterator position. Note that we take * Start a hash table walk at the current iterator position. Note that we take
@ -744,8 +744,12 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_exit);
* Returns -EAGAIN if resize event occured. Note that the iterator * Returns -EAGAIN if resize event occured. Note that the iterator
* will rewind back to the beginning and you may use it immediately * will rewind back to the beginning and you may use it immediately
* by calling rhashtable_walk_next. * by calling rhashtable_walk_next.
*
* rhashtable_walk_start is defined as an inline variant that returns
* void. This is preferred in cases where the caller would ignore
* resize events and always continue.
*/ */
int rhashtable_walk_start(struct rhashtable_iter *iter) int rhashtable_walk_start_check(struct rhashtable_iter *iter)
__acquires(RCU) __acquires(RCU)
{ {
struct rhashtable *ht = iter->ht; struct rhashtable *ht = iter->ht;
@ -764,7 +768,7 @@ int rhashtable_walk_start(struct rhashtable_iter *iter)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(rhashtable_walk_start); EXPORT_SYMBOL_GPL(rhashtable_walk_start_check);
/** /**
* rhashtable_walk_next - Return the next object and advance the iterator * rhashtable_walk_next - Return the next object and advance the iterator

Просмотреть файл

@ -162,11 +162,7 @@ static void test_bucket_stats(struct rhashtable *ht, unsigned int entries)
return; return;
} }
err = rhashtable_walk_start(&hti); rhashtable_walk_start(&hti);
if (err && err != -EAGAIN) {
pr_warn("Test failed: iterator failed: %d\n", err);
return;
}
while ((pos = rhashtable_walk_next(&hti))) { while ((pos = rhashtable_walk_next(&hti))) {
if (PTR_ERR(pos) == -EAGAIN) { if (PTR_ERR(pos) == -EAGAIN) {

Просмотреть файл

@ -512,9 +512,7 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
struct ila_map *ila; struct ila_map *ila;
int ret; int ret;
ret = rhashtable_walk_start(rhiter); rhashtable_walk_start(rhiter);
if (ret && ret != -EAGAIN)
goto done;
for (;;) { for (;;) {
ila = rhashtable_walk_next(rhiter); ila = rhashtable_walk_next(rhiter);

Просмотреть файл

@ -306,9 +306,7 @@ static int seg6_genl_dumphmac(struct sk_buff *skb, struct netlink_callback *cb)
struct seg6_hmac_info *hinfo; struct seg6_hmac_info *hinfo;
int ret; int ret;
ret = rhashtable_walk_start(iter); rhashtable_walk_start(iter);
if (ret && ret != -EAGAIN)
goto done;
for (;;) { for (;;) {
hinfo = rhashtable_walk_next(iter); hinfo = rhashtable_walk_next(iter);

Просмотреть файл

@ -257,9 +257,7 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
if (ret) if (ret)
return NULL; return NULL;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto err;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) 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) if (i++ == idx)
break; break;
} }
err:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
@ -513,9 +510,7 @@ void mesh_plink_broken(struct sta_info *sta)
if (ret) if (ret)
return; return;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto out;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) 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); WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast);
} }
} }
out:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
} }
@ -584,9 +578,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
if (ret) if (ret)
return; return;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto out;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) 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) if (rcu_access_pointer(mpath->next_hop) == sta)
__mesh_path_del(tbl, mpath); __mesh_path_del(tbl, mpath);
} }
out:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
} }
@ -614,9 +606,7 @@ static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata,
if (ret) if (ret)
return; return;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto out;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) 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)) if (ether_addr_equal(mpath->mpp, proxy))
__mesh_path_del(tbl, mpath); __mesh_path_del(tbl, mpath);
} }
out:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
} }
@ -642,9 +632,7 @@ static void table_flush_by_iface(struct mesh_table *tbl)
if (ret) if (ret)
return; return;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto out;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN)
@ -653,7 +641,7 @@ static void table_flush_by_iface(struct mesh_table *tbl)
break; break;
__mesh_path_del(tbl, mpath); __mesh_path_del(tbl, mpath);
} }
out:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
} }
@ -873,9 +861,7 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata,
if (ret) if (ret)
return; return;
ret = rhashtable_walk_start(&iter); rhashtable_walk_start(&iter);
if (ret && ret != -EAGAIN)
goto out;
while ((mpath = rhashtable_walk_next(&iter))) { while ((mpath = rhashtable_walk_next(&iter))) {
if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) 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)) time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
__mesh_path_del(tbl, mpath); __mesh_path_del(tbl, mpath);
} }
out:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
rhashtable_walk_exit(&iter); rhashtable_walk_exit(&iter);
} }

Просмотреть файл

@ -251,11 +251,7 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
if (err) if (err)
return; return;
err = rhashtable_walk_start(&hti); rhashtable_walk_start(&hti);
if (err && err != -EAGAIN) {
iter->err = err;
goto out;
}
while ((he = rhashtable_walk_next(&hti))) { while ((he = rhashtable_walk_next(&hti))) {
if (IS_ERR(he)) { if (IS_ERR(he)) {
@ -306,9 +302,7 @@ static void nft_rhash_gc(struct work_struct *work)
if (err) if (err)
goto schedule; goto schedule;
err = rhashtable_walk_start(&hti); rhashtable_walk_start(&hti);
if (err && err != -EAGAIN)
goto out;
while ((he = rhashtable_walk_next(&hti))) { while ((he = rhashtable_walk_next(&hti))) {
if (IS_ERR(he)) { if (IS_ERR(he)) {

Просмотреть файл

@ -2478,8 +2478,9 @@ static int netlink_walk_start(struct nl_seq_iter *iter)
return err; return err;
} }
err = rhashtable_walk_start(&iter->hti); rhashtable_walk_start(&iter->hti);
return err == -EAGAIN ? 0 : err;
return 0;
} }
static void netlink_walk_stop(struct nl_seq_iter *iter) static void netlink_walk_stop(struct nl_seq_iter *iter)

Просмотреть файл

@ -115,11 +115,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
if (!s_num) if (!s_num)
rhashtable_walk_enter(&tbl->hash, hti); rhashtable_walk_enter(&tbl->hash, hti);
ret = rhashtable_walk_start(hti); rhashtable_walk_start(hti);
if (ret == -EAGAIN)
ret = 0;
if (ret)
goto stop;
while ((nlsk = rhashtable_walk_next(hti))) { while ((nlsk = rhashtable_walk_next(hti))) {
if (IS_ERR(nlsk)) { 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); rhashtable_walk_stop(hti);
if (ret) if (ret)
goto done; goto done;

Просмотреть файл

@ -288,12 +288,8 @@ struct sctp_ht_iter {
static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos) static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct sctp_ht_iter *iter = seq->private; struct sctp_ht_iter *iter = seq->private;
int err = sctp_transport_walk_start(&iter->hti);
if (err) { sctp_transport_walk_start(&iter->hti);
iter->start_fail = 1;
return ERR_PTR(err);
}
iter->start_fail = 0; iter->start_fail = 0;
return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos); return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);

Просмотреть файл

@ -4676,20 +4676,11 @@ int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
EXPORT_SYMBOL_GPL(sctp_get_sctp_info); EXPORT_SYMBOL_GPL(sctp_get_sctp_info);
/* use callback to avoid exporting the core structure */ /* 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); rhltable_walk_enter(&sctp_transport_hashtable, iter);
err = rhashtable_walk_start(iter); rhashtable_walk_start(iter);
if (err && err != -EAGAIN) {
rhashtable_walk_stop(iter);
rhashtable_walk_exit(iter);
return err;
}
return 0;
} }
void sctp_transport_walk_stop(struct rhashtable_iter *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 net *net, int *pos, void *p) {
struct rhashtable_iter hti; struct rhashtable_iter hti;
struct sctp_transport *tsp; struct sctp_transport *tsp;
int ret; int ret = 0;
again: again:
ret = sctp_transport_walk_start(&hti); sctp_transport_walk_start(&hti);
if (ret)
return ret;
tsp = sctp_transport_get_idx(net, &hti, *pos + 1); tsp = sctp_transport_get_idx(net, &hti, *pos + 1);
for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) { for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) {

Просмотреть файл

@ -2640,9 +2640,7 @@ void tipc_sk_reinit(struct net *net)
rhashtable_walk_enter(&tn->sk_rht, &iter); rhashtable_walk_enter(&tn->sk_rht, &iter);
do { do {
tsk = ERR_PTR(rhashtable_walk_start(&iter)); rhashtable_walk_start(&iter);
if (IS_ERR(tsk))
goto walk_stop;
while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) {
spin_lock_bh(&tsk->sk.sk_lock.slock); 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); msg_set_orignode(msg, tn->own_addr);
spin_unlock_bh(&tsk->sk.sk_lock.slock); spin_unlock_bh(&tsk->sk.sk_lock.slock);
} }
walk_stop:
rhashtable_walk_stop(&iter); rhashtable_walk_stop(&iter);
} while (tsk == ERR_PTR(-EAGAIN)); } while (tsk == ERR_PTR(-EAGAIN));
} }