From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Cc: aik@au1.ibm.com, anton@au1.ibm.com, paulus@samba.org,
sparclinux@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
davem@davemloft.net
Subject: Re: [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock
Date: Sun, 05 Apr 2015 00:33:31 +1100 [thread overview]
Message-ID: <1428154411.20500.312.camel@kernel.crashing.org> (raw)
In-Reply-To: <20150404112714.GA2117@oracle.com>
On Sat, 2015-04-04 at 07:27 -0400, Sowmini Varadhan wrote:
> One last question before I spin out v9.. the dma_mask code
> is a bit confusing to me, so I want to make sure... the code is
>
> > if (limit + tbl->it_offset > mask) {
> > limit = mask - tbl->it_offset + 1;
> > /* If we're constrained on address range, first try
> > * at the masked hint to avoid O(n) search complexity,
> > * but on second pass, start at 0 in pool 0.
> > */
> > if ((start & mask) >= limit || pass > 0) {
> > spin_unlock(&(pool->lock));
> > pool = &(tbl->pools[0]);
> > spin_lock(&(pool->lock));
> > start = pool->start;
>
> So here I would need to mark need_flush to true, right?
Well, no but ...
So you aren't changing any pool hint, so you don't have to mark any pool
for flushing. The "n < hint" check will do the flush later on if needed
(the one I told you to add).
You only need to force a flush if you modify the hint.
*However*, you do an unlock, which means that if you have modified any
*other* pool's hint (ie, need_flush is true), you need to actually
perform a flush.
I think that business with flushing on unlock is becoming too ugly, I
would suggest you simplify things by moving need_flush to be part of the
pool structure (maybe a flag).
IE, when you modify a pool's hint, your mark it for flushing.
When you allocate from a pool, you flush it at the end, just before you
return success, if either it was marked for flushing or n < hint (and
clear the mark of course).
That should cleanly factor all cases in a simpler & more readable code
path. The flush is done only when needed (an actual allocation happen on
a pool), you just "mark them dirty" when you change their hints, you
don't have to worry about the lock dropped case & pool hop'ing anymore.
Basically the logic looks like that:
.../...
n = iommu_area_alloc(...)
if (n == -1) {
if (pass == 0) {
change pool hint
pool->need_flush = true;
pass++;
goto again;
} else if (!largealloc && .... ) {
unlock/pool hop/lock
// no need to flush anything here
pool->hint = pool->start;
pool->need_flush = true;
etc...
} else {
n = DMA_ERROR_CODE;
goto fail;
}
}
end = n + pages;
if (n < pool->hint || pool->need_flush) {
pool->need_flush = false;
iommu->lazy_flush(...);
}
pool->hint = end;
.../...
Now this can be further simplified imho. For example that logic:
+ if (pass == 0 && handle && *handle &&
+ (*handle >= pool->start) && (*handle < pool->end))
+ start = *handle;
+ else
+ start = pool->hint;
Can move above the again: label. that way, you remove the pass test
and you no longer have to adjust pool->hint in the "if (likely(pass ==
0))" failure case. Just adjust "start" and try again, which means you
also no longer need to set need_flush.
Additionally, when pool hop'ing, now you only need to adjust "start" as
well. By not resetting it, you also remove the need for marking it "need
flush". I would add to that, why not set "start" to the new pool's hint
instead of the new pool's start ? That will save some flushes, no ?
Anton, do you remember why you reset the hint when changing pool ? I
don't see that gaining us anything and it does make lazy flushing more
complex.
At that point, you have removed all setters of need_flush, that logic
can be entirely removed, or am I just too tired (it's past midnight) and
missing something entirely here ?
We only need the if (n < pool->hint) check to do the lazy flush at the
end, that's it.
Cheers,
Ben.
WARNING: multiple messages have this Message-ID (diff)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Cc: aik@au1.ibm.com, anton@au1.ibm.com, paulus@samba.org,
sparclinux@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
davem@davemloft.net
Subject: Re: [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l
Date: Sat, 04 Apr 2015 13:33:31 +0000 [thread overview]
Message-ID: <1428154411.20500.312.camel@kernel.crashing.org> (raw)
In-Reply-To: <20150404112714.GA2117@oracle.com>
On Sat, 2015-04-04 at 07:27 -0400, Sowmini Varadhan wrote:
> One last question before I spin out v9.. the dma_mask code
> is a bit confusing to me, so I want to make sure... the code is
>
> > if (limit + tbl->it_offset > mask) {
> > limit = mask - tbl->it_offset + 1;
> > /* If we're constrained on address range, first try
> > * at the masked hint to avoid O(n) search complexity,
> > * but on second pass, start at 0 in pool 0.
> > */
> > if ((start & mask) >= limit || pass > 0) {
> > spin_unlock(&(pool->lock));
> > pool = &(tbl->pools[0]);
> > spin_lock(&(pool->lock));
> > start = pool->start;
>
> So here I would need to mark need_flush to true, right?
Well, no but ...
So you aren't changing any pool hint, so you don't have to mark any pool
for flushing. The "n < hint" check will do the flush later on if needed
(the one I told you to add).
You only need to force a flush if you modify the hint.
*However*, you do an unlock, which means that if you have modified any
*other* pool's hint (ie, need_flush is true), you need to actually
perform a flush.
I think that business with flushing on unlock is becoming too ugly, I
would suggest you simplify things by moving need_flush to be part of the
pool structure (maybe a flag).
IE, when you modify a pool's hint, your mark it for flushing.
When you allocate from a pool, you flush it at the end, just before you
return success, if either it was marked for flushing or n < hint (and
clear the mark of course).
That should cleanly factor all cases in a simpler & more readable code
path. The flush is done only when needed (an actual allocation happen on
a pool), you just "mark them dirty" when you change their hints, you
don't have to worry about the lock dropped case & pool hop'ing anymore.
Basically the logic looks like that:
.../...
n = iommu_area_alloc(...)
if (n = -1) {
if (pass = 0) {
change pool hint
pool->need_flush = true;
pass++;
goto again;
} else if (!largealloc && .... ) {
unlock/pool hop/lock
// no need to flush anything here
pool->hint = pool->start;
pool->need_flush = true;
etc...
} else {
n = DMA_ERROR_CODE;
goto fail;
}
}
end = n + pages;
if (n < pool->hint || pool->need_flush) {
pool->need_flush = false;
iommu->lazy_flush(...);
}
pool->hint = end;
.../...
Now this can be further simplified imho. For example that logic:
+ if (pass = 0 && handle && *handle &&
+ (*handle >= pool->start) && (*handle < pool->end))
+ start = *handle;
+ else
+ start = pool->hint;
Can move above the again: label. that way, you remove the pass test
and you no longer have to adjust pool->hint in the "if (likely(pass =
0))" failure case. Just adjust "start" and try again, which means you
also no longer need to set need_flush.
Additionally, when pool hop'ing, now you only need to adjust "start" as
well. By not resetting it, you also remove the need for marking it "need
flush". I would add to that, why not set "start" to the new pool's hint
instead of the new pool's start ? That will save some flushes, no ?
Anton, do you remember why you reset the hint when changing pool ? I
don't see that gaining us anything and it does make lazy flushing more
complex.
At that point, you have removed all setters of need_flush, that logic
can be entirely removed, or am I just too tired (it's past midnight) and
missing something entirely here ?
We only need the if (n < pool->hint) check to do the lazy flush at the
end, that's it.
Cheers,
Ben.
next prev parent reply other threads:[~2015-04-04 13:33 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-31 14:40 [PATCH v8 RFC 0/3] Generic IOMMU pooled allocator Sowmini Varadhan
2015-03-31 14:40 ` Sowmini Varadhan
2015-03-31 14:40 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-03-31 14:40 ` Sowmini Varadhan
2015-03-31 15:15 ` David Laight
2015-03-31 15:15 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l David Laight
2015-03-31 15:25 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-03-31 15:25 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-02 20:54 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 20:54 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-02 21:43 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-02 21:43 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-02 21:57 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 21:57 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-02 22:01 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 22:01 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-02 22:02 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 22:02 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-02 22:15 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-02 22:15 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-02 22:19 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 22:19 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-02 21:54 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-02 21:54 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-02 22:08 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-02 22:08 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-03 0:42 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock David Miller
2015-04-03 0:42 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l David Miller
2015-04-03 18:28 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-03 18:28 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-03 21:06 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Benjamin Herrenschmidt
2015-04-03 21:06 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Benjamin Herrenschmidt
2015-04-03 21:51 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-03 21:51 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-04 11:27 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and lock Sowmini Varadhan
2015-04-04 11:27 ` [PATCH v8 RFC 1/3] sparc: Break up monolithic iommu table/lock into finer graularity pools and l Sowmini Varadhan
2015-04-04 13:33 ` Benjamin Herrenschmidt [this message]
2015-04-04 13:33 ` Benjamin Herrenschmidt
2015-03-31 14:40 ` [PATCH v8 RFC 2/3] sparc: Make sparc64 use scalable lib/iommu-common.c functions Sowmini Varadhan
2015-03-31 14:40 ` Sowmini Varadhan
2015-03-31 14:40 ` [PATCH v8 RFC 3/3] sparc: Make LDC use common iommu poll management functions Sowmini Varadhan
2015-03-31 14:40 ` Sowmini Varadhan
2015-03-31 18:06 ` [PATCH v8 RFC 0/3] Generic IOMMU pooled allocator Sowmini Varadhan
2015-03-31 18:06 ` Sowmini Varadhan
2015-03-31 18:08 ` David Miller
2015-03-31 18:08 ` David Miller
2015-04-01 1:01 ` Benjamin Herrenschmidt
2015-04-01 1:01 ` Benjamin Herrenschmidt
2015-04-01 1:08 ` Sowmini Varadhan
2015-04-01 1:08 ` Sowmini Varadhan
2015-04-01 3:12 ` David Miller
2015-04-01 3:12 ` David Miller
2015-04-02 12:51 ` Sowmini Varadhan
2015-04-02 12:51 ` Sowmini Varadhan
2015-04-02 16:21 ` David Miller
2015-04-02 16:21 ` David Miller
2015-04-02 20:22 ` Benjamin Herrenschmidt
2015-04-02 20:22 ` Benjamin Herrenschmidt
2015-04-02 20:52 ` Benjamin Herrenschmidt
2015-04-02 20:52 ` Benjamin Herrenschmidt
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=1428154411.20500.312.camel@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=aik@au1.ibm.com \
--cc=anton@au1.ibm.com \
--cc=davem@davemloft.net \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=paulus@samba.org \
--cc=sowmini.varadhan@oracle.com \
--cc=sparclinux@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.