* [rfc] powerpc/npu: Cleanup MMIO ATSD flushing
@ 2017-10-30 12:38 Balbir Singh
2017-10-30 16:03 ` Aneesh Kumar K.V
0 siblings, 1 reply; 3+ messages in thread
From: Balbir Singh @ 2017-10-30 12:38 UTC (permalink / raw)
To: alistair, mpe; +Cc: linuxppc-dev, arbab, Balbir Singh
While reviewing the code I found that the flush assumes all
pages are of mmu_linear_psize, which is not correct. The patch
uses find_linux_pte to find the right page size and uses that
for launching the ATSD invalidation. A new helper is added
to abstract the invalidation from the various notifiers.
The patch also cleans up a bit by removing AP size from PID
flushes.
Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
arch/powerpc/platforms/powernv/npu-dma.c | 55 ++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index 2cb6cbea4b3b..0d58f127b32d 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -27,6 +27,7 @@
#include <asm/pnv-pci.h>
#include <asm/msi_bitmap.h>
#include <asm/opal.h>
+#include <asm/pte-walk.h>
#include "powernv.h"
#include "pci.h"
@@ -459,9 +460,6 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid, bool flush)
/* PRS set to process-scoped */
launch |= PPC_BIT(13);
- /* AP */
- launch |= (u64) mmu_get_ap(mmu_virtual_psize) << PPC_BITLSHIFT(17);
-
/* PID */
launch |= pid << PPC_BITLSHIFT(38);
@@ -473,7 +471,8 @@ static int mmio_invalidate_pid(struct npu *npu, unsigned long pid, bool flush)
}
static int mmio_invalidate_va(struct npu *npu, unsigned long va,
- unsigned long pid, bool flush)
+ unsigned long pid, bool flush,
+ unsigned int shift)
{
unsigned long launch;
@@ -484,9 +483,8 @@ static int mmio_invalidate_va(struct npu *npu, unsigned long va,
launch |= PPC_BIT(13);
/* AP */
- launch |= (u64) mmu_get_ap(mmu_virtual_psize) << PPC_BITLSHIFT(17);
+ launch |= (u64) mmu_get_ap(shift) << PPC_BITLSHIFT(17);
- /* PID */
launch |= pid << PPC_BITLSHIFT(38);
/* No flush */
@@ -503,7 +501,8 @@ struct mmio_atsd_reg {
};
static void mmio_invalidate_wait(
- struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], bool flush)
+ struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], bool flush,
+ unsigned int shift)
{
struct npu *npu;
int i, reg;
@@ -536,7 +535,8 @@ static void mmio_invalidate_wait(
* the value of va.
*/
static void mmio_invalidate(struct npu_context *npu_context, int va,
- unsigned long address, bool flush)
+ unsigned long address, bool flush,
+ unsigned int shift)
{
int i, j;
struct npu *npu;
@@ -569,7 +569,7 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
if (va)
mmio_atsd_reg[i].reg =
mmio_invalidate_va(npu, address, pid,
- flush);
+ flush, shift);
else
mmio_atsd_reg[i].reg =
mmio_invalidate_pid(npu, pid, flush);
@@ -582,10 +582,33 @@ static void mmio_invalidate(struct npu_context *npu_context, int va,
}
}
- mmio_invalidate_wait(mmio_atsd_reg, flush);
+ mmio_invalidate_wait(mmio_atsd_reg, flush, shift);
if (flush)
/* Wait for the flush to complete */
- mmio_invalidate_wait(mmio_atsd_reg, false);
+ mmio_invalidate_wait(mmio_atsd_reg, false, shift);
+}
+
+static void pnv_npu2_invalidate_helper(struct npu_context *npu_context,
+ struct mm_struct *mm, unsigned long start,
+ unsigned long end, bool flush)
+{
+ unsigned long address;
+ bool is_thp;
+ unsigned int hshift, shift;
+
+ address = start;
+ do {
+ local_irq_disable();
+ find_linux_pte(mm->pgd, address, &is_thp, &hshift);
+ if (!is_thp)
+ shift = PAGE_SHIFT;
+ else
+ shift = hshift;
+ mmio_invalidate(npu_context, address > 0, address, flush,
+ shift);
+ local_irq_enable();
+ address += (1ull << shift);
+ } while (address < end);
}
static void pnv_npu2_mn_release(struct mmu_notifier *mn,
@@ -601,7 +624,7 @@ static void pnv_npu2_mn_release(struct mmu_notifier *mn,
* There should be no more translation requests for this PID, but we
* need to ensure any entries for it are removed from the TLB.
*/
- mmio_invalidate(npu_context, 0, 0, true);
+ pnv_npu2_invalidate_helper(npu_context, mm, 0, PAGE_SIZE, true);
}
static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
@@ -611,7 +634,7 @@ static void pnv_npu2_mn_change_pte(struct mmu_notifier *mn,
{
struct npu_context *npu_context = mn_to_npu_context(mn);
- mmio_invalidate(npu_context, 1, address, true);
+ pnv_npu2_invalidate_helper(npu_context, mm, address, address, true);
}
static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
@@ -619,13 +642,11 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
unsigned long start, unsigned long end)
{
struct npu_context *npu_context = mn_to_npu_context(mn);
- unsigned long address;
- for (address = start; address < end; address += PAGE_SIZE)
- mmio_invalidate(npu_context, 1, address, false);
+ pnv_npu2_invalidate_helper(npu_context, mm, start, end, false);
/* Do the flush only on the final addess == end */
- mmio_invalidate(npu_context, 1, address, true);
+ pnv_npu2_invalidate_helper(npu_context, mm, end, end, true);
}
static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
--
2.13.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [rfc] powerpc/npu: Cleanup MMIO ATSD flushing
2017-10-30 12:38 [rfc] powerpc/npu: Cleanup MMIO ATSD flushing Balbir Singh
@ 2017-10-30 16:03 ` Aneesh Kumar K.V
2017-10-30 23:28 ` Balbir Singh
0 siblings, 1 reply; 3+ messages in thread
From: Aneesh Kumar K.V @ 2017-10-30 16:03 UTC (permalink / raw)
To: Balbir Singh, alistair, mpe; +Cc: linuxppc-dev, arbab
On 10/30/2017 06:08 PM, Balbir Singh wrote:
> +
> +static void pnv_npu2_invalidate_helper(struct npu_context *npu_context,
> + struct mm_struct *mm, unsigned long start,
> + unsigned long end, bool flush)
> +{
> + unsigned long address;
> + bool is_thp;
> + unsigned int hshift, shift;
> +
> + address = start;
> + do {
> + local_irq_disable();
> + find_linux_pte(mm->pgd, address, &is_thp, &hshift);
> + if (!is_thp)
> + shift = PAGE_SHIFT;
> + else
> + shift = hshift;
Is that correct? if is_thp is 0 can we derive shift from hshift? IIUC we
set hshift only
if it is a hugepage.
> + mmio_invalidate(npu_context, address > 0, address, flush,
> + shift);
> + local_irq_enable();
> + address += (1ull << shift);
> + } while (address < end);
> }
>
>
-aneesh
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [rfc] powerpc/npu: Cleanup MMIO ATSD flushing
2017-10-30 16:03 ` Aneesh Kumar K.V
@ 2017-10-30 23:28 ` Balbir Singh
0 siblings, 0 replies; 3+ messages in thread
From: Balbir Singh @ 2017-10-30 23:28 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: Alistair Popple, Michael Ellerman,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT),
Reza Arbab
On Tue, Oct 31, 2017 at 3:03 AM, Aneesh Kumar K.V
<aneeshkumar.opensource@gmail.com> wrote:
>
>
> On 10/30/2017 06:08 PM, Balbir Singh wrote:
>>
>> +
>> +static void pnv_npu2_invalidate_helper(struct npu_context *npu_context,
>> + struct mm_struct *mm, unsigned long start,
>> + unsigned long end, bool flush)
>> +{
>> + unsigned long address;
>> + bool is_thp;
>> + unsigned int hshift, shift;
>> +
>> + address = start;
>> + do {
>> + local_irq_disable();
>> + find_linux_pte(mm->pgd, address, &is_thp, &hshift);
>> + if (!is_thp)
>> + shift = PAGE_SHIFT;
>> + else
>> + shift = hshift;
>
>
> Is that correct? if is_thp is 0 can we derive shift from hshift? IIUC we set
> hshift only
> if it is a hugepage.
OK.. I assumed that it'll be set. So I've got to check for
if (is_thp)
shift = mmu_psize_defs[MMU_PAGE_2M].shift
else if (hshift)
shift = hshift
else
shift = PAGE_SHIFT
>
>
>> + mmio_invalidate(npu_context, address > 0, address, flush,
>> + shift);
>> + local_irq_enable();
>> + address += (1ull << shift);
>> + } while (address < end);
>> }
>>
Thanks for the review!
Balbir Singh.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-10-30 23:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-30 12:38 [rfc] powerpc/npu: Cleanup MMIO ATSD flushing Balbir Singh
2017-10-30 16:03 ` Aneesh Kumar K.V
2017-10-30 23:28 ` Balbir Singh
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.