From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tom Herbert Subject: Re: [PATCH RFC v2] rhashtable: implement rhashtable_walk_peek() using rhashtable_walk_last_seen() Date: Thu, 14 Jun 2018 10:41:05 -0700 Message-ID: References: <152782754287.30340.4395718227884933670.stgit@noble> <152782824964.30340.6329146982899668633.stgit@noble> <20180602154851.pfy4wryezuhxp76v@gondor.apana.org.au> <87y3fvpf40.fsf@notabene.neil.brown.name> <87sh63pakb.fsf@notabene.neil.brown.name> <87r2lmnj2c.fsf@notabene.neil.brown.name> <87in6wo636.fsf@notabene.neil.brown.name> <871sdjnwkr.fsf@notabene.neil.brown.name> <87y3frmhyx.fsf@notabene.neil.brown.name> <871sdck9ds.fsf@notabene.neil.brown.name> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Cc: Herbert Xu , Thomas Graf , Linux Kernel Network Developers , LKML , Tom Herbert To: NeilBrown Return-path: In-Reply-To: <871sdck9ds.fsf@notabene.neil.brown.name> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org On Mon, Jun 11, 2018 at 7:48 PM, NeilBrown wrote: > > rhashtable_walk_last_seen() does most of the work that > rhashtable_walk_peek() needs done, so use it and put > it in a "static inline". > Also update the documentation for rhashtable_walk_peek() to clarify > the expected use case. > > Signed-off-by: NeilBrown Acked-by: Tom Herbert > --- > > v2 as static-inline - suggested by Tom. > > Thanks, > NeilBrown > > include/linux/rhashtable.h | 29 ++++++++++++++++++++++++++++- > lib/rhashtable.c | 34 ---------------------------------- > 2 files changed, 28 insertions(+), 35 deletions(-) > > diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h > index d63b472e9d50..96ebc2690027 100644 > --- a/include/linux/rhashtable.h > +++ b/include/linux/rhashtable.h > @@ -247,10 +247,37 @@ static inline void rhashtable_walk_start(struct rhashtable_iter *iter) > } > > void *rhashtable_walk_next(struct rhashtable_iter *iter); > -void *rhashtable_walk_peek(struct rhashtable_iter *iter); > void *rhashtable_walk_last_seen(struct rhashtable_iter *iter); > void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU); > > +/** > + * rhashtable_walk_peek - Return the next object to use in an interrupted walk > + * @iter: Hash table iterator > + * > + * Returns the "current" object or NULL when the end of the table is reached. > + * When an rhashtable_walk is interrupted with rhashtable_walk_stop(), > + * it is often because an object was found that could not be processed > + * immediately, possible because there is no more space to encode details > + * of the object (e.g. when producing a seq_file from the table). > + * When the walk is restarted, the same object needs to be processed again, > + * if possible. The object might have been removed from the table while > + * the walk was paused, so it might not be available. In that case, the > + * normal "next" object should be treated as "current". > + * > + * To support this common case, rhashtable_walk_peek() returns the > + * appropriate object to process after an interrupted walk, either the > + * one that was most recently returned, or if that doesn't exist - the > + * next one. > + * > + * Returns -EAGAIN if resize event occurred. In that case the iterator > + * will rewind back to the beginning and you may continue to use it. > + */ > +static inline void *rhashtable_walk_peek(struct rhashtable_iter *iter) > +{ > + return rhashtable_walk_last_seen(iter) ?: > + rhashtable_walk_next(iter); > +} > + > void rhashtable_free_and_destroy(struct rhashtable *ht, > void (*free_fn)(void *ptr, void *arg), > void *arg); > diff --git a/lib/rhashtable.c b/lib/rhashtable.c > index 45f2554399a5..354275037df3 100644 > --- a/lib/rhashtable.c > +++ b/lib/rhashtable.c > @@ -915,40 +915,6 @@ void *rhashtable_walk_next(struct rhashtable_iter *iter) > } > EXPORT_SYMBOL_GPL(rhashtable_walk_next); > > -/** > - * rhashtable_walk_peek - Return the next object but don't advance the iterator > - * @iter: Hash table iterator > - * > - * Returns the next object or NULL when the end of the table is reached. > - * > - * Returns -EAGAIN if resize event occurred. Note that the iterator > - * will rewind back to the beginning and you may continue to use it. > - */ > -void *rhashtable_walk_peek(struct rhashtable_iter *iter) > -{ > - struct rhlist_head *list = iter->list; > - struct rhashtable *ht = iter->ht; > - struct rhash_head *p = iter->p; > - > - if (p) > - return rht_obj(ht, ht->rhlist ? &list->rhead : p); > - > - /* No object found in current iter, find next one in the table. */ > - > - if (iter->skip) { > - /* A nonzero skip value points to the next entry in the table > - * beyond that last one that was found. Decrement skip so > - * we find the current value. __rhashtable_walk_find_next > - * will restore the original value of skip assuming that > - * the table hasn't changed. > - */ > - iter->skip--; > - } > - > - return __rhashtable_walk_find_next(iter); > -} > -EXPORT_SYMBOL_GPL(rhashtable_walk_peek); > - > /** > * rhashtable_walk_last_seen - Return the previously returned object, if available > * @iter: Hash table iterator > -- > 2.14.0.rc0.dirty >