linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Omar Sandoval <osandov@osandov.com>
To: Ming Lei <ming.lei@redhat.com>
Cc: Jens Axboe <axboe@fb.com>,
	linux-block@vger.kernel.org,
	Christoph Hellwig <hch@infradead.org>,
	Bart Van Assche <bart.vanassche@sandisk.com>,
	Laurence Oberman <loberman@redhat.com>,
	Paolo Valente <paolo.valente@linaro.org>,
	Mel Gorman <mgorman@techsingularity.net>,
	Omar Sandoval <osandov@fb.com>
Subject: Re: [PATCH V4 02/14] sbitmap: introduce __sbitmap_for_each_set()
Date: Sun, 10 Sep 2017 10:20:27 -0700	[thread overview]
Message-ID: <20170910172027.GA2579@vader> (raw)
In-Reply-To: <20170909093812.GE26081@ming.t460p>

On Sat, Sep 09, 2017 at 05:38:13PM +0800, Ming Lei wrote:
> On Fri, Sep 08, 2017 at 01:43:41PM -0700, Omar Sandoval wrote:
> > On Sat, Sep 02, 2017 at 11:17:17PM +0800, Ming Lei wrote:
> > > We need to iterate ctx starting from any ctx in round robin
> > > way, so introduce this helper.
> > > 
> > > Cc: Omar Sandoval <osandov@fb.com>
> > 
> > A couple of comments below, once you address those you can add
> > 
> > Reviewed-by: Omar Sandoval <osandov@fb.com>
> > 
> > > Signed-off-by: Ming Lei <ming.lei@redhat.com>
> > > ---
> > >  include/linux/sbitmap.h | 54 ++++++++++++++++++++++++++++++++++++-------------
> > >  1 file changed, 40 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
> > > index a1904aadbc45..2329b9e1a0e2 100644
> > > --- a/include/linux/sbitmap.h
> > > +++ b/include/linux/sbitmap.h
> > > @@ -211,10 +211,14 @@ bool sbitmap_any_bit_set(const struct sbitmap *sb);
> > >   */
> > >  bool sbitmap_any_bit_clear(const struct sbitmap *sb);
> > >  
> > > +#define SB_NR_TO_INDEX(sb, bitnr) ((bitnr) >> (sb)->shift)
> > > +#define SB_NR_TO_BIT(sb, bitnr) ((bitnr) & ((1U << (sb)->shift) - 1U))
> > > +
> > >  typedef bool (*sb_for_each_fn)(struct sbitmap *, unsigned int, void *);
> > >  
> > >  /**
> > >   * sbitmap_for_each_set() - Iterate over each set bit in a &struct sbitmap.
> > > + * @off: Where to start the iteration
> > >   * @sb: Bitmap to iterate over.
> > >   * @fn: Callback. Should return true to continue or false to break early.
> > >   * @data: Pointer to pass to callback.
> > > @@ -222,35 +226,57 @@ typedef bool (*sb_for_each_fn)(struct sbitmap *, unsigned int, void *);
> > >   * This is inline even though it's non-trivial so that the function calls to the
> > >   * callback will hopefully get optimized away.
> > >   */
> > > -static inline void sbitmap_for_each_set(struct sbitmap *sb, sb_for_each_fn fn,
> > > -					void *data)
> > > +static inline void __sbitmap_for_each_set(struct sbitmap *sb,
> > > +					  unsigned int off,
> > > +					  sb_for_each_fn fn, void *data)
> > >  {
> > > -	unsigned int i;
> > > +	unsigned int index = SB_NR_TO_INDEX(sb, off);
> > > +	unsigned int nr = SB_NR_TO_BIT(sb, off);
> > > +	unsigned int scanned = 0;
> > >  
> > > -	for (i = 0; i < sb->map_nr; i++) {
> > > -		struct sbitmap_word *word = &sb->map[i];
> > > -		unsigned int off, nr;
> > > +	while (1) {
> > > +		struct sbitmap_word *word = &sb->map[index];
> > > +		unsigned int depth = min_t(unsigned int, word->depth - nr,
> > > +					   sb->depth - scanned);
> > >  
> > > +		scanned += depth;
> > >  		if (!word->word)
> > > -			continue;
> > > +			goto next;
> > >  
> > > -		nr = 0;
> > > -		off = i << sb->shift;
> > > +		depth += nr;
> > 
> > I had to think hard to convince myself this was right. If above we set
> > depth to (sb->depth - scanned), then we must have already looped at
> 
> It should be so only in the last loop, in which the 1st half of
> the word is to be checked because we start from the 2nd half of
> the same word.
> 
> > least once, so nr must be 0, therefore this is okay. Am I following this
> > correctly? I think reassigning like so would be more clear:
> 
> Yes, you are right, nr can be non-zero only in the 1st loop.
> 
> > 
> > 		depth = min_t(unsigned int, word->depth, sb->depth - scanned);
> 
> If nr isn't zero, the depth to be scanned should be 'word->depth - nr'
> in the 1st loop, so the above way can't cover this case.

What I mean is that you keep the same initialization above, but instead of
		depth += nr
you do
		depth = min_t(unsigned int, word->depth, sb->depth - scanned);
because like I said, the reasoning about why `+= nr` is okay in the
`sb->depth - scanned` case is subtle.

And maybe even replace the
		scanned += depth;
with
		scanned += min_t(unsigned int, word->depth - nr,
	   			 sb->depth - scanned);
I.e., don't reuse the depth local variable for two different things. I'm
nitpicking here but this code is tricky enough as it is.

For completeness, I mean this exactly:

	while (1) {
		struct sbitmap_word *word = &sb->map[index];
		unsigned int depth;

		scanned += min_t(unsigned int, word->depth - nr,
				 sb->depth - scanned);
		if (!word->word)
			goto next;

		depth = min_t(unsigned int, word->depth, sb->depth - scanned);
		off = index << sb->shift;
		while (1) {
			nr = find_next_bit(&word->word, depth, nr);
			if (nr >= depth)
				break;

			if (!fn(sb, off + nr, data))
				return;

			nr++;
		}
next:
		if (scanned >= sb->depth)
			break;
		nr = 0;
		if (++index >= sb->map_nr)
			index = 0;
	}

  reply	other threads:[~2017-09-10 17:20 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-02 15:17 [PATCH V4 00/14] blk-mq-sched: improve SCSI-MQ performance Ming Lei
2017-09-02 15:17 ` [PATCH V4 01/14] blk-mq-sched: fix scheduler bad performance Ming Lei
2017-09-08 20:48   ` Omar Sandoval
2017-09-08 20:54     ` Omar Sandoval
2017-09-08 20:56       ` Omar Sandoval
2017-09-09  7:43         ` Ming Lei
2017-09-09  7:33       ` Ming Lei
2017-09-02 15:17 ` [PATCH V4 02/14] sbitmap: introduce __sbitmap_for_each_set() Ming Lei
2017-09-08 20:43   ` Omar Sandoval
2017-09-09  9:38     ` Ming Lei
2017-09-10 17:20       ` Omar Sandoval [this message]
2017-09-11  4:08         ` Ming Lei
2017-09-13 18:37           ` Omar Sandoval
2017-09-14  1:56             ` Ming Lei
2017-09-14 14:59               ` Omar Sandoval
2017-09-14 15:18                 ` Omar Sandoval
2017-09-15  1:57                 ` Ming Lei
2017-09-02 15:17 ` [PATCH V4 03/14] blk-mq: introduce blk_mq_dispatch_rq_from_ctx() Ming Lei
2017-09-15  0:04   ` Omar Sandoval
2017-09-15  1:50     ` Ming Lei
2017-09-02 15:17 ` [PATCH V4 04/14] blk-mq-sched: move actual dispatching into one helper Ming Lei
2017-09-19 19:21   ` Omar Sandoval
2017-09-02 15:17 ` [PATCH V4 05/14] blk-mq-sched: improve dispatching from sw queue Ming Lei
2017-09-08 23:54   ` Omar Sandoval
2017-09-10  4:45     ` Ming Lei
2017-09-10 17:38       ` Omar Sandoval
2017-09-11  4:13         ` Ming Lei
2017-09-13 17:32           ` Omar Sandoval
2017-09-19 20:37   ` Jens Axboe
2017-09-20  2:37     ` Ming Lei
2017-09-20 12:20     ` Ming Lei
2017-09-22  2:15       ` Ming Lei
2017-09-02 15:17 ` [PATCH V4 06/14] blk-mq-sched: don't dequeue request until all in ->dispatch are flushed Ming Lei
2017-09-19 19:11   ` Omar Sandoval
2017-09-20  2:55     ` Ming Lei
2017-09-02 15:17 ` [PATCH V4 07/14] blk-mq-sched: introduce blk_mq_sched_queue_depth() Ming Lei
2017-09-02 15:17 ` [PATCH V4 08/14] blk-mq-sched: use q->queue_depth as hint for q->nr_requests Ming Lei
2017-09-02 15:17 ` [PATCH V4 09/14] block: introduce rqhash helpers Ming Lei
2017-09-02 15:17 ` [PATCH V4 10/14] block: move actual bio merge code into __elv_merge Ming Lei
2017-09-02 15:17 ` [PATCH V4 11/14] block: add check on elevator for supporting bio merge via hashtable from blk-mq sw queue Ming Lei
2017-09-02 15:17 ` [PATCH V4 12/14] block: introduce .last_merge and .hash to blk_mq_ctx Ming Lei
2017-09-02 15:17 ` [PATCH V4 13/14] blk-mq-sched: refactor blk_mq_sched_try_merge() Ming Lei
2017-09-02 15:17 ` [PATCH V4 14/14] blk-mq: improve bio merge from blk-mq sw queue Ming Lei
2017-09-04  9:12 ` [PATCH V4 00/14] blk-mq-sched: improve SCSI-MQ performance Paolo Valente
2017-09-05  1:39   ` Ming Lei
2017-09-06 15:27     ` Ming Lei
2017-09-19 19:25 ` Omar Sandoval
2017-09-20  3:18   ` Ming Lei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170910172027.GA2579@vader \
    --to=osandov@osandov.com \
    --cc=axboe@fb.com \
    --cc=bart.vanassche@sandisk.com \
    --cc=hch@infradead.org \
    --cc=linux-block@vger.kernel.org \
    --cc=loberman@redhat.com \
    --cc=mgorman@techsingularity.net \
    --cc=ming.lei@redhat.com \
    --cc=osandov@fb.com \
    --cc=paolo.valente@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).