From: Bill Mills <hidden> Date: 2016-06-06 03:21:21
This RFC series adds support for outer shared LPAE page table
attributes. This attribute is needed by at least keystone to achieve
dma coherency. The choice is done at early boot time and can co-exist
with other platforms that want only inner shared.
v2 addresses the concern about changing the memory attributes while the
MMU is on that was raised in v1. It also puts the primary
responsibility of choosing the right mode on the platform.
Instead of creating an "need outer shared flag" to the pv_fixup code, I
created a generic attribute modification mechanism. The idea was it
could be used to solve other problems where the assumptions of the
early boot tables need to be changed in a safe manner. Right now it is
LPAE only and tied 1:1 with pv_fixup but that could change. I did test
that applying a 0 pv_fixup seemed to do no harm.
There is a patch that adds an early param "defshared". This is a
separate patch as I am unsure if this is really desired. It is useful
for testing the series however. You can use it to force keystone to
use inner shared (and it will fallback to non-coherent dma-ops) or you
can use it to force another platform to use outer shared and see what
happens. If we keep the param, documentation will be added.
This series needs more testing and finishing but I wanted to get a read
on the direction. This does run on Keystone and for QEMU vexpress-A15.
QEMU vexpress runs with inner or outer shared :)
Multiple TODO points marked in-line. If the approach is accepted I
will complete the TODO items and TI will do more testing.
Series based on V4.7-rc2
v1 was here:
http://marc.info/?t=146044908600005&r=1&w=2
-- Bill
From: Bill Mills <hidden> Date: 2016-06-06 03:21:22
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
Signed-off-by: Bill Mills <redacted>
---
arch/arm/mach-keystone/keystone.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
@@ -52,21 +53,53 @@ static struct notifier_block platform_nb = {.notifier_call=keystone_platform_notifier,};+voidveto_dma_coherent(void)+{+structdevice_node*node,*start_node;+structproperty*prop;++for(start_node=NULL;+(node=of_find_node_with_property(start_node,"dma-coherent"));+start_node=node){+prop=of_find_property(node,"dma-coherent",NULL);+if(prop)+of_remove_property(node,prop);+}+}+staticvoid__initkeystone_init(void){+/* If we are running from the high physical addresses then adjust+*addresseswegivetothedevice'sDMA.Theywillbeseeingthis+*memorythroughtheMSMCaddresstranslationwhichmakesthefirst2GB+*ofhighmemoryappearinthelow4GBspace.+*(DMAmastersonkeystone2have32bitaddressbuses)+*/if(PHYS_OFFSET>=KEYSTONE_HIGH_PHYS_START){keystone_dma_pfn_offset=PFN_DOWN(KEYSTONE_HIGH_PHYS_START-KEYSTONE_LOW_PHYS_START);bus_register_notifier(&platform_bus_type,&platform_nb);}++/* if the kernel has not been configured to meet the keystone+*platformrequirementstoachieveDMAcoherency,thenignoreany+*devicetreeconfigurationforthis+*/+if(!keystone_dma_coherent)+veto_dma_coherent();+keystone_pm_runtime_init();of_platform_populate(NULL,of_default_bus_match_table,NULL,NULL);}staticlonglong__initkeystone_pv_fixup(void){+#ifdef CONFIG_ARM_LPAElonglongoffset;phys_addr_tmem_start,mem_end;+booldma_ok;++dma_ok=use_outer_shared();mem_start=memblock_start_of_DRAM();mem_end=memblock_end_of_DRAM();
@@ -84,11 +117,15 @@ static long long __init keystone_pv_fixup(void)}offset=KEYSTONE_HIGH_PHYS_START-KEYSTONE_LOW_PHYS_START;+keystone_dma_coherent=dma_ok;/* Populate the arch idmap hook */arch_phys_to_idmap_offset=-offset;returnoffset;+#else+return0;+#endif}staticconstchar*constkeystone_match[]__initconst={
From: Bill Mills <hidden> Date: 2016-06-06 03:21:26
Support early init selection of inner or outer shared page table
attributes.
In LPAE shared is 3 valued: non-shared, inner-shared, and outer-shared.
Provide a mask and both shared values. Shared value in use is stored in
variables. The old constants are eliminated to avoid accidental use.
Early page tables and variables are initialized to inner shared.
If a platform needs outer shared, it calls use_outer_shared()
during early_paging_init. The variables and early page table are
fixed up. The mem_types built during paging_init are fixed to match
the value in effect.
No functional change for non-LPAE. We only add a few extra aliases for
existing constants and use some extra vars at boot.
This patch is based in part on an earlier RFC patch by
Tero Kristo [off-list ref]
Signed-off-by: Bill Mills <redacted>
---
arch/arm/include/asm/pgtable-2level-hwdef.h | 6 +++
arch/arm/include/asm/pgtable-3level-hwdef.h | 14 ++++-
arch/arm/include/asm/pgtable-3level.h | 2 +-
arch/arm/include/asm/pgtable-hwdef.h | 1 +
arch/arm/include/asm/pgtable.h | 3 ++
arch/arm/mm/dump.c | 28 ++++++++++
arch/arm/mm/mmu.c | 80 +++++++++++++++++++++++------
arch/arm/mm/proc-v7-3level.S | 2 +-
8 files changed, 115 insertions(+), 21 deletions(-)
@@ -93,4 +93,10 @@#define PHYS_MASK (~0UL)+/* These are here to share more code between 2level & 3level */+#define L_PTE_EARLY_SHARED PTE_EXT_SHARED+#define PTE_EXT_SMASK PTE_EXT_SHARED+#define PMD_SECT_EARLY_S PMD_SECT_S+#define PMD_SECT_SMASK PMD_SECT_S+#endif
@@ -70,6 +70,13 @@ pgprot_t pgprot_hyp_device;pgprot_tpgprot_s2;pgprot_tpgprot_s2_device;+/* For LPAE hold the value of Inner or Outer Shared attribute selected at+*earlyinit,whichstartsoutasinnershared+*Fornon_LPAEthesearealwaysjustthesingleSBit+*/+pmdval_tpmd_sect_s=PMD_SECT_EARLY_S;+pteval_tl_pte_shared=L_PTE_EARLY_SHARED;+EXPORT_SYMBOL(pgprot_user);EXPORT_SYMBOL(pgprot_kernel);
@@ -449,14 +466,24 @@ static void __init build_mem_type_table(void)ecc_mask=0;}+#ifdef CONFIG_ARM_LPAE+if(pmd_sect_s!=PMD_SECT_EARLY_S)+/* we are using different sharable value than was set at+*compiletime,fixupthememtypes+*/+for(i=0;i<ARRAY_SIZE(mem_types);i++)+if(mem_types[i].prot_sect&PMD_SECT_SMASK)+fixup_mem_type_shared(&mem_types[i]);+#endif+if(is_smp()){if(cachepolicy!=CPOLICY_WRITEALLOC){pr_warn("Forcing write-allocate cache policy for SMP\n");cachepolicy=CPOLICY_WRITEALLOC;}-if(!(initial_pmd_value&PMD_SECT_S)){+if(!(initial_pmd_value&PMD_SECT_SMASK)){pr_warn("Forcing shared mappings for SMP\n");-initial_pmd_value|=PMD_SECT_S;+initial_pmd_value|=pmd_sect_s;}}
@@ -1510,6 +1537,25 @@ bool __init attr_mod_add(struct attr_mod_entry *pmod)returntrue;}+/* use outer shared wherever we would have used inner shared */+bool__inituse_outer_shared(void)+{+structattr_mod_entrymod={+.test_mask=PTE_EXT_SMASK,+.test_value=PTE_EXT_ISHARED,+.clear_mask=PTE_EXT_SMASK,+.set_mask=PTE_EXT_OSHARED+};++if(attr_mod_add(&mod)>=0){+l_pte_shared=PTE_EXT_OSHARED;+pmd_sect_s=PMD_SECT_OSHARED;+returntrue;+}++returnfalse;+}+/**early_paging_init()recreatesboottimepagetablesetup,allowingmachines*toswitchovertoahigh(>4G)addressspaceonLPAEsystems
From: Bill Mills <hidden> Date: 2016-06-06 03:22:38
Allow early-init to specify modifications to be made to the boot time page
table. Any modifications specified will be done with MMU off at the same
time that any Phy<->Virt fixup is done.
This ability is enabled with ARM_PV_FIXUP.
It is currently only implemented for LPAE mode.
Signed-off-by: Bill Mills <redacted>
---
arch/arm/include/asm/pgtable-hwdef.h | 21 +++++++++
arch/arm/mm/mmu.c | 36 ++++++++++++---
arch/arm/mm/pv-fixup-asm.S | 86 ++++++++++++++++++++++++++++++++++--
3 files changed, 135 insertions(+), 8 deletions(-)
@@ -1496,23 +1496,41 @@ extern unsigned long __atags_pointer;typedefvoidpgtables_remap(longlongoffset,unsignedlongpgd,void*bdata);pgtables_remaplpae_pgtables_remap_asm;+intnum_attr_mods;++/* add an entry to the early page table attribute modification list */+bool__initattr_mod_add(structattr_mod_entry*pmod)+{+if(num_attr_mods>=MAX_ATTR_MOD_ENTRIES){+pr_crit("Out of room for (or late use of) early page table attribute modifications.\n");+returnfalse;+}++attr_mod_table[num_attr_mods++]=*pmod;+returntrue;+}+/**early_paging_init()recreatesboottimepagetablesetup,allowingmachines*toswitchovertoahigh(>4G)addressspaceonLPAEsystems+*+*Thisfunctionalsoappliesanyattributemodificationsspecifiedin+*attr_mod_table.Thesemayhavebeenaddedbeforewegothere(early_param)+*orfromwithinmdesc->pv_fixupcalledbythisfunction*/void__initearly_paging_init(conststructmachine_desc*mdesc){pgtables_remap*lpae_pgtables_remap;unsignedlongpa_pgd;unsignedintcr,ttbcr;-longlongoffset;+longlongoffset=0;void*boot_data;+unsignedlongpmd;-if(!mdesc->pv_fixup)-return;+if(mdesc->pv_fixup)+offset=mdesc->pv_fixup();-offset=mdesc->pv_fixup();-if(offset==0)+if(offset==0&&num_attr_mods==0)return;/*
@@ -1564,6 +1582,14 @@ void __init early_paging_init(const struct machine_desc *mdesc)/* Re-enable the caches and cacheable TLB walks */asmvolatile("mcr p15, 0, %0, c2, c0, 2"::"r"(ttbcr));set_cr(cr);++/* disable any further use of attribute fixup */+num_attr_mods=MAX_ATTR_MOD_ENTRIES+1;++/* record the new "initial" pmd and cachepolicy */+pmd=pmd_val(*pmd_off_k((unsignedlong)_data));+pmd&=~PMD_MASK;+init_default_cache_policy(pmd);}#else
@@ -74,15 +111,58 @@ ENTRY(lpae_pgtables_remap_asm)dsb+/*Updateattributesofalllevel2entriesin1GBspace*/+/*TODO:fix/testBE8THUMB2kernel*/+adrlr3,attr_mod_table+addr7,r2,#0x1000+addr6,r7,#0x4000+bl3f@NOTCABI++/*Updateattributesofthe4level1entries*/+/*TODO:deletethisorallowmodentriestomatchonlyL1*/+movr7,r2+addr6,r7,#32+bl3f@NOTCABI+b7f++3:ldrdr4,[r7]+orrsr11,r4,r5+beq6f@skipunusedentries+movr10,r3+4:ldrdr8,[r10]+orrsr11,r8,r9+beq6f@endofmodtable?+andr0,r4,r8@no,loadtestmask+andr1,r5,r9+ldrdr8,[r10,#8] @ load test bits+cmpr0,r8+cmpeqr1,r9+bne5f@doesentrymatchdesc?+ldrdr8,[r10,#16] @ yes, load mod clear mask+bicr4,r4,r8+bicr5,r5,r9+ldrdr8,[r10,#24] @ load mod set mask+orrr4,r4,r8+orrr5,r5,r9+5:addr10,r10,#32 @ try next mod desc+b4b+6:strdr4,[r7],#1 << L2_ORDER+cmpr7,r6+bls3b+bxlr++7:movip,#0mcrp15,0,ip,c7,c5,0@I+BTBcacheinvalidatemcrp15,0,ip,c8,c7,0@local_flush_tlb_all()dsbisb-mcrp15,0,r8,c1,c0,0@re-enableMMU+mrcp15,0,r8,c1,c0,0@re-enableMMU+orrr8,r8,#CR_M+mcrp15,0,r8,c1,c0,0dsbisb-ldmfdsp!,{r4-r8,pc}+ldmfdsp!,{r4-r11,pc}ENDPROC(lpae_pgtables_remap_asm)
From: Bill Mills <hidden> Date: 2016-06-06 03:22:39
Adds defsharing=inner|outer as an early command line option.
Any such command line option will override a platform's choice.
Signed-off-by: Bill Mills <redacted>
---
arch/arm/include/asm/pgtable-hwdef.h | 1 +
arch/arm/mm/mmu.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
@@ -1524,6 +1524,7 @@ typedef void pgtables_remap(long long offset, unsigned long pgd, void *bdata);pgtables_remaplpae_pgtables_remap_asm;intnum_attr_mods;+staticconstchar*defshared_seen;/* add an entry to the early page table attribute modification list */bool__initattr_mod_add(structattr_mod_entry*pmod)
@@ -1547,15 +1548,50 @@ bool __init use_outer_shared(void).set_mask=PTE_EXT_OSHARED};+if(defshared_seen){+pr_err("Default Sharing already set to %s\n",defshared_seen);+returnfalse;+}+if(attr_mod_add(&mod)>=0){l_pte_shared=PTE_EXT_OSHARED;pmd_sect_s=PMD_SECT_OSHARED;+defshared_seen="outer";returntrue;}returnfalse;}+/* explicitly use inner shared */+bool__inituse_inner_shared(void)+{+if(defshared_seen){+pr_err("Default Sharing already set to %s\n",defshared_seen);+returnfalse;+}++defshared_seen="inner";+returntrue;+}++/*+*Allowsharingtypetobeset+*/+staticint__initearly_defshared(char*p)+{+if(strcmp(p,"outer")==0)+use_outer_shared();+elseif(strcmp(p,"inner")==0)+use_inner_shared();+else+pr_err("Unknown defshared mode %s\n",p);++return0;+}++early_param("defshared",early_defshared);+/**early_paging_init()recreatesboottimepagetablesetup,allowingmachines*toswitchovertoahigh(>4G)addressspaceonLPAEsystems
From: Mark Rutland <mark.rutland@arm.com> Date: 2016-06-06 08:56:57
[adding devicetree]
On Sun, Jun 05, 2016 at 11:20:29PM -0400, Bill Mills wrote:
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
I would prefer that we have a separate property (e.g.
"dma-outer-coherent") to describe when a device can be coherent with
Normal, Outer Shareable, Inner Write-Back, Outer Write-Back memory.
Then the kernel can figure out whether or not device can be used
coherently, depending on how it is configured.
Thanks,
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-April/421470.html
@@ -52,21 +53,53 @@ static struct notifier_block platform_nb = {.notifier_call=keystone_platform_notifier,};+voidveto_dma_coherent(void)+{+structdevice_node*node,*start_node;+structproperty*prop;++for(start_node=NULL;+(node=of_find_node_with_property(start_node,"dma-coherent"));+start_node=node){+prop=of_find_property(node,"dma-coherent",NULL);+if(prop)+of_remove_property(node,prop);+}+}+staticvoid__initkeystone_init(void){+/* If we are running from the high physical addresses then adjust+*addresseswegivetothedevice'sDMA.Theywillbeseeingthis+*memorythroughtheMSMCaddresstranslationwhichmakesthefirst2GB+*ofhighmemoryappearinthelow4GBspace.+*(DMAmastersonkeystone2have32bitaddressbuses)+*/if(PHYS_OFFSET>=KEYSTONE_HIGH_PHYS_START){keystone_dma_pfn_offset=PFN_DOWN(KEYSTONE_HIGH_PHYS_START-KEYSTONE_LOW_PHYS_START);bus_register_notifier(&platform_bus_type,&platform_nb);}++/* if the kernel has not been configured to meet the keystone+*platformrequirementstoachieveDMAcoherency,thenignoreany+*devicetreeconfigurationforthis+*/+if(!keystone_dma_coherent)+veto_dma_coherent();+keystone_pm_runtime_init();of_platform_populate(NULL,of_default_bus_match_table,NULL,NULL);}staticlonglong__initkeystone_pv_fixup(void){+#ifdef CONFIG_ARM_LPAElonglongoffset;phys_addr_tmem_start,mem_end;+booldma_ok;++dma_ok=use_outer_shared();mem_start=memblock_start_of_DRAM();mem_end=memblock_end_of_DRAM();
@@ -84,11 +117,15 @@ static long long __init keystone_pv_fixup(void)}offset=KEYSTONE_HIGH_PHYS_START-KEYSTONE_LOW_PHYS_START;+keystone_dma_coherent=dma_ok;/* Populate the arch idmap hook */arch_phys_to_idmap_offset=-offset;returnoffset;+#else+return0;+#endif}staticconstchar*constkeystone_match[]__initconst={
On Monday, June 6, 2016 9:56:27 AM CEST Mark Rutland wrote:
[adding devicetree]
On Sun, Jun 05, 2016 at 11:20:29PM -0400, Bill Mills wrote:
quoted
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
I would prefer that we have a separate property (e.g.
"dma-outer-coherent") to describe when a device can be coherent with
Normal, Outer Shareable, Inner Write-Back, Outer Write-Back memory.
Then the kernel can figure out whether or not device can be used
coherently, depending on how it is configured.
I share your concern, but I don't think the dma-outer-coherent attribute
would be a good solution either.
The problem really is that keystone is a platform that is sometimes
coherent, depending purely on what kernel we run, and not at all on
anything we can describe in devicetree, and I don't see any good way
to capture the behavior of the hardware in generic DT bindings.
So far, the assumption has been:
- when running a non-LPAE kernel, keystone is not coherent, and we
must ignore both the dma-coherent properties in devices and the
dma-ranges properties in bus nodes.
- when running an LPAE kernel, keystone is coherent, and we must
respect both of those.
My interpretation of Bill's description above is that we now have
an additional requirement that at least I was not aware of before,
regarding the outer-sharable attribute. I don't think there is
much value in making this a boot-time option, since everyone would
want to run this platform in a cache-coherent way if at all possible.
We already have special hacks to detect the case of keystone running
in LPAE mode, in order to do the special rewrite-all-page-tables
hack at boot time for relocating the physical address, and we could
use the same hack to change the page table attributes.
The question is how to communicate the requirement for outer-sharable
for a platform. If we think it's a safe assumption that there will
not be future 32-bit platforms with this requirement (or maybe one
or two more at most), we could leave it in the special keystone hack.
Alternatively, a DT property in an appropriate node could indicate
that a particular platform requires it.
Arnd
From: Mark Rutland <mark.rutland@arm.com> Date: 2016-06-06 11:43:18
On Mon, Jun 06, 2016 at 11:09:07AM +0200, Arnd Bergmann wrote:
On Monday, June 6, 2016 9:56:27 AM CEST Mark Rutland wrote:
quoted
[adding devicetree]
On Sun, Jun 05, 2016 at 11:20:29PM -0400, Bill Mills wrote:
quoted
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
I would prefer that we have a separate property (e.g.
"dma-outer-coherent") to describe when a device can be coherent with
Normal, Outer Shareable, Inner Write-Back, Outer Write-Back memory.
Then the kernel can figure out whether or not device can be used
coherently, depending on how it is configured.
I share your concern, but I don't think the dma-outer-coherent attribute
would be a good solution either.
The problem really is that keystone is a platform that is sometimes
coherent, depending purely on what kernel we run, and not at all on
anything we can describe in devicetree, and I don't see any good way
to capture the behavior of the hardware in generic DT bindings.
I think that above doesn't quite capture the situation:
Some DMA masters can be cache-coherent (only) with Outer Shareable
transactions. That is a property we could capture inthe DT (e.g.
dma-outer-coherent), and is independent of the kernel configuration.
Whether or not the devices are coherent with the kernel's chosen memory
attributes certainly depends on the kernel configuration, but that is
not what we capture in the DT.
So far, the assumption has been:
- when running a non-LPAE kernel, keystone is not coherent, and we
must ignore both the dma-coherent properties in devices and the
dma-ranges properties in bus nodes.
I wasn't able to spot if/where that was enforced. Is it possible to boot
Keystone UP, !LPAE?
- when running an LPAE kernel, keystone is coherent, and we must
respect both of those.
Similarly this has not been enforced either way. Currently I cannot see
how devices with dma-coherent could possibly work with Keystone.
I think we also need to be clear as to what we mean by "keystone is
coherent". With LPAE, CPUs can be coherent with each other, so long as
the appropriate physical addresses are used (with the magic to handle
that).
Devices being cache-coherent with CPUs is already something we manage
per-device.
My interpretation of Bill's description above is that we now have
an additional requirement that at least I was not aware of before,
regarding the outer-sharable attribute. I don't think there is
much value in making this a boot-time option, since everyone would
want to run this platform in a cache-coherent way if at all possible.
We already have special hacks to detect the case of keystone running
in LPAE mode, in order to do the special rewrite-all-page-tables
hack at boot time for relocating the physical address, and we could
use the same hack to change the page table attributes.
The question is how to communicate the requirement for outer-sharable
for a platform. If we think it's a safe assumption that there will
not be future 32-bit platforms with this requirement (or maybe one
or two more at most), we could leave it in the special keystone hack.
Alternatively, a DT property in an appropriate node could indicate
that a particular platform requires it.
As above, I think this must be specified per-device, following the usual
manner in which we describe Inner Shareable coherency using
dma-coherent.
Thanks,
Mark.
From: Russell King - ARM Linux <linux@armlinux.org.uk> Date: 2016-06-06 11:43:40
On Mon, Jun 06, 2016 at 09:56:27AM +0100, Mark Rutland wrote:
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
dma-coherent's semantics are not very well defined - just grep for it
in Documention/devicetree/ and you'll find several different wordings
for what this property means.
Anyway, my point here is that all of these merely say that the hardware
is coherent in _some regard_ - it doesn't specify under what conditions
DMA coherency is guaranteed by the hardware. It happens that on ARM,
most platforms give that guarantee when using inner shared mappings. If
we were to use some other sharing, or disable sharing altogether (eg, by
disabling SMP support) then all these platforms would immediately break.
In other words, DMA coherence today already depends on the kernel's setup
of the page tables corresponding to the requirements of the hardware.
Keystone II is just slightly different - and as I understand it, TI
followed one of the early specifications that ARM Ltd produced. That
specification may have contained errors, but unfortunately, we now have
a situation where there is hardware out there which followed in good
faith.
So, it seems to me to be entirely reasonable that Keystone II should
mark devices with the "dma-coherent" property - just the same way as
every other platform does. It also seems to be entirely appropriate for
a platform to remove this property if it determines that the conditions
for DMA coherency are not met - in order to save the users data from
corruption.
TI Keystone II is not the only platform with issues here: there are
Marvell Armada platforms out there which have DMA coherence, but are
uniprocessor, we don't set the shared bit (which they require for
DMA coherence) and so we omit the dma-coherent property from the
device tree at the moment. And they're inner-shared coherent. We
just don't set the page tables up so that they can work.
So, I think to require a whole new property is absurd. The existing
property means "if the rest of the system is appropriately configured,
this device can be dma-coherent". So, what I think we need is a way
to communicate whether the rest of the system has been appropriately
configured, so the property can be attached to devices which meet the
criteria, but the arch/platform level can signal whether the conditions
for device DMA coherence have been met. That's not a DT property,
that's a matter of how the kernel has setup the system.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
From: Mark Rutland <mark.rutland@arm.com> Date: 2016-06-06 11:59:40
On Mon, Jun 06, 2016 at 12:43:21PM +0100, Russell King - ARM Linux wrote:
On Mon, Jun 06, 2016 at 09:56:27AM +0100, Mark Rutland wrote:
quoted
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
dma-coherent's semantics are not very well defined - just grep for it
in Documention/devicetree/ and you'll find several different wordings
for what this property means.
Indeed. This is the tip of the iceberg w.r.t. under-specification of
memory attribute usage.
Anyway, my point here is that all of these merely say that the hardware
is coherent in _some regard_ - it doesn't specify under what conditions
DMA coherency is guaranteed by the hardware. It happens that on ARM,
most platforms give that guarantee when using inner shared mappings. If
we were to use some other sharing, or disable sharing altogether (eg, by
disabling SMP support) then all these platforms would immediately break.
In other words, DMA coherence today already depends on the kernel's setup
of the page tables corresponding to the requirements of the hardware.
I agree that whether or not devices are coherent in practice depends on
the kernel's configuration. The flip side, as you point out, is that
devices are coherent when a specific set of attributes are used.
i.e. that if you read dma-coherent as meaning "coherent iff Normal,
Inner Shareable, Inner WB Cacheable, Outer WB Cacheable", then
dma-coherent consistently describes the same thing, rather than
depending on the configuration of the OS.
DT is a datastructure provided to the kernel, potentially without deep
internal knowledge of that kernel configuration. Having a consistent
rule that is independent of the kernel configuration seems worth aiming
for.
A dma-outer-coherent property would allow us to accurately describe the
keystone case in the same way, independent of kernel configuration.
Keystone II is just slightly different - and as I understand it, TI
followed one of the early specifications that ARM Ltd produced. That
specification may have contained errors, but unfortunately, we now have
a situation where there is hardware out there which followed in good
faith.
To be clear, I am not arguing against supporting keystone. I just wish
to avoid muddying the waters further w.r.t. the semantics of
dma-coherent, which I believe can be salvaged and made consistent.
Clearly, those semantics are the point of contention here.
Thanks,
Mark.
From: Russell King - ARM Linux <linux@armlinux.org.uk> Date: 2016-06-06 12:18:27
On Sun, Jun 05, 2016 at 11:20:26PM -0400, Bill Mills wrote:
Allow early-init to specify modifications to be made to the boot time page
table. Any modifications specified will be done with MMU off at the same
time that any Phy<->Virt fixup is done.
I think this is rather over-engineered - do we need to support multiple
different fixups to the page tables like this?
Given how this has grown, I think it would be better to duplicate the
existing swapper_pg_dir, modify the new copy, and then have the
pv-fixup-asm code merely copy the new to the old with the MMU off.
That way, the only two things that the assembly code has to do is to
deal with the page table update, and updating the TTBR registers.
Most of the complexity can then be kept in the C code.
I think we also need to modify the TTBCR to match the sharability of
memory - currently, TTB walks will be inner sharable, but my
understanding is that if we switch memory to be outer sharable, we
also need to update the TTB walks to match.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
From: William Mills <hidden> Date: 2016-06-06 12:19:43
On 06/06/2016 07:59 AM, Mark Rutland wrote:
On Mon, Jun 06, 2016 at 12:43:21PM +0100, Russell King - ARM Linux wrote:
quoted
On Mon, Jun 06, 2016 at 09:56:27AM +0100, Mark Rutland wrote:
quoted
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
dma-coherent's semantics are not very well defined - just grep for it
in Documention/devicetree/ and you'll find several different wordings
for what this property means.
Indeed. This is the tip of the iceberg w.r.t. under-specification of
memory attribute usage.
quoted
Anyway, my point here is that all of these merely say that the hardware
is coherent in _some regard_ - it doesn't specify under what conditions
DMA coherency is guaranteed by the hardware. It happens that on ARM,
most platforms give that guarantee when using inner shared mappings. If
we were to use some other sharing, or disable sharing altogether (eg, by
disabling SMP support) then all these platforms would immediately break.
In other words, DMA coherence today already depends on the kernel's setup
of the page tables corresponding to the requirements of the hardware.
I agree that whether or not devices are coherent in practice depends on
the kernel's configuration. The flip side, as you point out, is that
devices are coherent when a specific set of attributes are used.
i.e. that if you read dma-coherent as meaning "coherent iff Normal,
Inner Shareable, Inner WB Cacheable, Outer WB Cacheable", then
dma-coherent consistently describes the same thing, rather than
depending on the configuration of the OS.
Even w/o inner / outer it seems to me it is under specified.
What about a system where main DDR memory is DMA coherent but an on chip
SRAM needs manual flush/invalidate? Right now dma coherency is all or
nothing. In the above case you would need to ensure that the device
never tried to use that SRAM for dma transactions even though the device
is perfectly capable with the right hand-holding. Alternatively you
could use the SRAM but penalize the normal case of DDR.
DT is a datastructure provided to the kernel, potentially without deep
internal knowledge of that kernel configuration. Having a consistent
rule that is independent of the kernel configuration seems worth aiming
for.
A dma-outer-coherent property would allow us to accurately describe the
keystone case in the same way, independent of kernel configuration.
quoted
Keystone II is just slightly different - and as I understand it, TI
followed one of the early specifications that ARM Ltd produced. That
specification may have contained errors, but unfortunately, we now have
a situation where there is hardware out there which followed in good
faith.
To be clear, I am not arguing against supporting keystone. I just wish
to avoid muddying the waters further w.r.t. the semantics of
dma-coherent, which I believe can be salvaged and made consistent.
Clearly, those semantics are the point of contention here.
To me this seems like a choice between embracing outer-shared or
treating it like a quirk of some early armv7 devices. With ARM's
current recommendations to use inner-shared for everything in many
contexts (like ARM servers etc), I was assuming you would want the latter.
Thanks for looking. This is not the patch that I expected to generate
the most discussion. :)
-- Bill
From: Russell King - ARM Linux <linux@armlinux.org.uk> Date: 2016-06-06 12:32:23
On Mon, Jun 06, 2016 at 12:59:18PM +0100, Mark Rutland wrote:
I agree that whether or not devices are coherent in practice depends on
the kernel's configuration. The flip side, as you point out, is that
devices are coherent when a specific set of attributes are used.
i.e. that if you read dma-coherent as meaning "coherent iff Normal,
Inner Shareable, Inner WB Cacheable, Outer WB Cacheable", then
dma-coherent consistently describes the same thing, rather than
depending on the configuration of the OS.
DT is a datastructure provided to the kernel, potentially without deep
internal knowledge of that kernel configuration. Having a consistent
rule that is independent of the kernel configuration seems worth aiming
for.
I think you've missed the point. dma-coherent is _already_ dependent on
the kernel configuration. "Having a consistent rule that is independent
of the kernel configuration" is already an impossibility, as I illustrated
in my previous message concerning Marvell Armada SoCs, and you also said
in your preceding paragraph!
For example, if you clear the shared bit in the page tables on non-LPAE
SoCs, devices are no longer coherent.
DMA coherence on ARM _is_ already tightly linked with the kernel
configuration. You already can't get away from that, so I think you
should give up trying to argue that point. :)
Whether devices are DMA coherent is a combination of two things:
* is the device connected to a coherent bus.
* is the system setup to allow coherency on that bus to work.
We capture the first through the dma-coherent property, which is clearly
a per-device property. We ignore the second because we assume everyone
is going to configure the CPU side correctly. That's untrue today, and
it's untrue not only because of Keystone II, but also because of other
SoCs as well which pre-date Keystone II. We currently miss out on
considering that, because if we ignore it, we get something that works
for most platforms.
I don't see that adding a dma-outer-coherent property helps this - it's
muddying the waters somewhat - and it's also forcing additional complexity
into places where we shouldn't have it. We would need to parse two
properties in the DMA API code, and then combine it with knowledge as
to how the system page tables have been setup. If they've been setup
as inner sharable, then dma-coherent identifies whether the device is
coherent. If they've been setup as outer sharable, then
dma-outer-coherent specifies that and dma-coherent is meaningless.
Sounds like a recipe for confusion.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
From: William Mills <hidden> Date: 2016-06-06 12:32:34
On 06/06/2016 08:18 AM, Russell King - ARM Linux wrote:
On Sun, Jun 05, 2016 at 11:20:26PM -0400, Bill Mills wrote:
quoted
Allow early-init to specify modifications to be made to the boot time page
table. Any modifications specified will be done with MMU off at the same
time that any Phy<->Virt fixup is done.
I think this is rather over-engineered - do we need to support multiple
different fixups to the page tables like this?
Yes I was expecting this comment but thought I would give you the choice. :)
Given how this has grown, I think it would be better to duplicate the
existing swapper_pg_dir, modify the new copy, and then have the
pv-fixup-asm code merely copy the new to the old with the MMU off.
That way, the only two things that the assembly code has to do is to
deal with the page table update, and updating the TTBR registers.
Most of the complexity can then be kept in the C code.
I really like this. I can just do the outer shared fixup and not worry
about a generalized mechanism. *If* someone needs to do another fixup
they can just code it in C.
The new patch #1 will just rework the PV_FIXUP for the new asm/C split.
You want the off-line table to copy over the early table in place w/ MMU
off, correct? (Not update the HW to point to a new spot.)
I think we also need to modify the TTBCR to match the sharability of
memory - currently, TTB walks will be inner sharable, but my
understanding is that if we switch memory to be outer sharable, we
also need to update the TTB walks to match.
Good point, Thanks. I don't think our internal hack has been doing that.
From: William Mills <hidden> Date: 2016-06-06 12:51:40
On 06/06/2016 07:42 AM, Mark Rutland wrote:
On Mon, Jun 06, 2016 at 11:09:07AM +0200, Arnd Bergmann wrote:
quoted
On Monday, June 6, 2016 9:56:27 AM CEST Mark Rutland wrote:
quoted
[adding devicetree]
On Sun, Jun 05, 2016 at 11:20:29PM -0400, Bill Mills wrote:
quoted
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
I would prefer that we have a separate property (e.g.
"dma-outer-coherent") to describe when a device can be coherent with
Normal, Outer Shareable, Inner Write-Back, Outer Write-Back memory.
Then the kernel can figure out whether or not device can be used
coherently, depending on how it is configured.
I share your concern, but I don't think the dma-outer-coherent attribute
would be a good solution either.
The problem really is that keystone is a platform that is sometimes
coherent, depending purely on what kernel we run, and not at all on
anything we can describe in devicetree, and I don't see any good way
to capture the behavior of the hardware in generic DT bindings.
I think that above doesn't quite capture the situation:
Some DMA masters can be cache-coherent (only) with Outer Shareable
transactions. That is a property we could capture inthe DT (e.g.
dma-outer-coherent), and is independent of the kernel configuration.
Whether or not the devices are coherent with the kernel's chosen memory
attributes certainly depends on the kernel configuration, but that is
not what we capture in the DT.
quoted
So far, the assumption has been:
- when running a non-LPAE kernel, keystone is not coherent, and we
must ignore both the dma-coherent properties in devices and the
dma-ranges properties in bus nodes.
I wasn't able to spot if/where that was enforced. Is it possible to boot
Keystone UP, !LPAE?
Yes ... with the right combination of DTB, u-boot, u-boot vars, and
kernel config. Mismatches either fail hard or use dma-coherent ops
without actually providing coherency. I am attempting to make this less
fragile.
Mis-configured coherency can be dead-wrong and still only fail 1
transaction in 1,000,000. I have seen customers run for weeks or months
w/o detecting the issue. Thats why I wanted the veto logic.
There are 3 cases to cover:
LPAE w/ high PA:
this is the normal mode for KS2. Uses coherent dma-ops.
!LPAE:
obviously uses low PA and must use non-coherent dma-ops.
LPAE w/ low PA:
This happens with an LPAE kernel but the user has passed a low
PA memory DTB and u-boot has not fixed it up.
This case must also use non-coherent dma-ops
Upstream DTS has keystone memory at the low PA. I agree with that.
U-boot and kernel opt-in to the use of high PA.
If you give high PA to a non-LPAE kernel I believe it will fail hard and
fast. I can check.
Thanks,
Bill
I saw only v2 but seems like it already generated
discussion(s)
On 06/06/2016 07:42 AM, Mark Rutland wrote:
quoted
On Mon, Jun 06, 2016 at 11:09:07AM +0200, Arnd Bergmann wrote:
quoted
On Monday, June 6, 2016 9:56:27 AM CEST Mark Rutland wrote:
quoted
[adding devicetree]
On Sun, Jun 05, 2016 at 11:20:29PM -0400, Bill Mills wrote:
quoted
Keystone2 can do DMA coherency but only if:
1) DDR3A DMA buffers are in high physical addresses (0x8_0000_0000)
(DDR3B does not have this constraint)
2) Memory is marked outer shared
3) DMA Master marks transactions as outer shared
(This is taken care of in bootloader)
Use outer shared instead of inner shared.
This choice is done at early init time and uses the attr_mod facility
If the kernel is not configured for LPAE and using high PA, or if the
switch to outer shared fails, then we fail to meet this criteria.
Under any of these conditions we veto any dma-coherent attributes in
the DTB.
I very much do not like this. As I previously mentioned [1],
dma-coherent has de-facto semantics today. This series deliberately
changes that, and inverts the relationship between DT and kernel (as the
describption in the DT would now depend on the configuration of the
kernel).
I would prefer that we have a separate property (e.g.
"dma-outer-coherent") to describe when a device can be coherent with
Normal, Outer Shareable, Inner Write-Back, Outer Write-Back memory.
Then the kernel can figure out whether or not device can be used
coherently, depending on how it is configured.
I share your concern, but I don't think the dma-outer-coherent attribute
would be a good solution either.
The problem really is that keystone is a platform that is sometimes
coherent, depending purely on what kernel we run, and not at all on
anything we can describe in devicetree, and I don't see any good way
to capture the behavior of the hardware in generic DT bindings.
I think that above doesn't quite capture the situation:
Some DMA masters can be cache-coherent (only) with Outer Shareable
transactions. That is a property we could capture inthe DT (e.g.
dma-outer-coherent), and is independent of the kernel configuration.
Whether or not the devices are coherent with the kernel's chosen memory
attributes certainly depends on the kernel configuration, but that is
not what we capture in the DT.
quoted
So far, the assumption has been:
- when running a non-LPAE kernel, keystone is not coherent, and we
must ignore both the dma-coherent properties in devices and the
dma-ranges properties in bus nodes.
Correct.
quoted
I wasn't able to spot if/where that was enforced. Is it possible to boot
Keystone UP, !LPAE?
Yes ... with the right combination of DTB, u-boot, u-boot vars, and
kernel config. Mismatches either fail hard or use dma-coherent ops
without actually providing coherency. I am attempting to make this less
fragile.
Mis-configured coherency can be dead-wrong and still only fail 1
transaction in 1,000,000. I have seen customers run for weeks or months
w/o detecting the issue. Thats why I wanted the veto logic.
There are 3 cases to cover:
LPAE w/ high PA:
this is the normal mode for KS2. Uses coherent dma-ops.
!LPAE:
obviously uses low PA and must use non-coherent dma-ops.
LPAE w/ low PA:
This happens with an LPAE kernel but the user has passed a low
PA memory DTB and u-boot has not fixed it up.
This case must also use non-coherent dma-ops
Upstream DTS has keystone memory at the low PA. I agree with that.
U-boot and kernel opt-in to the use of high PA.
If you give high PA to a non-LPAE kernel I believe it will fail hard and
fast. I can check.
UP will mostly boot from boot view the memory. The keystone_pv_fixup()
will bail out for higher PA. Let me know if you see otherwise.
Regards,
Santosh
(Joining discussion late since only this thread showed up in my
inbox)
On 6/6/2016 5:32 AM, Russell King - ARM Linux wrote:
On Mon, Jun 06, 2016 at 12:59:18PM +0100, Mark Rutland wrote:
quoted
I agree that whether or not devices are coherent in practice depends on
the kernel's configuration. The flip side, as you point out, is that
devices are coherent when a specific set of attributes are used.
i.e. that if you read dma-coherent as meaning "coherent iff Normal,
Inner Shareable, Inner WB Cacheable, Outer WB Cacheable", then
dma-coherent consistently describes the same thing, rather than
depending on the configuration of the OS.
I think there is a bit of miss-understanding with 'dma-coherent'
DT property and as RMK pointed out "dma-coherent-outer" isn't
right direction either.
quoted
DT is a datastructure provided to the kernel, potentially without deep
internal knowledge of that kernel configuration. Having a consistent
rule that is independent of the kernel configuration seems worth aiming
for.
I think you've missed the point. dma-coherent is _already_ dependent on
the kernel configuration. "Having a consistent rule that is independent
of the kernel configuration" is already an impossibility, as I illustrated
in my previous message concerning Marvell Armada SoCs, and you also said
in your preceding paragraph!
For example, if you clear the shared bit in the page tables on non-LPAE
SoCs, devices are no longer coherent.
DMA coherence on ARM _is_ already tightly linked with the kernel
configuration. You already can't get away from that, so I think you
should give up trying to argue that point. :)
Whether devices are DMA coherent is a combination of two things:
* is the device connected to a coherent bus.
* is the system setup to allow coherency on that bus to work.
We capture the first through the dma-coherent property, which is clearly
a per-device property. We ignore the second because we assume everyone
is going to configure the CPU side correctly. That's untrue today, and
it's untrue not only because of Keystone II, but also because of other
SoCs as well which pre-date Keystone II. We currently miss out on
considering that, because if we ignore it, we get something that works
for most platforms.
I agree with Russell. When I added "dma-coherent" per device DT
property, the intention was to distinguish certain devices which may
not be coherent sitting on coherent fabric for some hardware reasons.
I don't see that adding a dma-outer-coherent property helps this - it's
muddying the waters somewhat - and it's also forcing additional complexity
into places where we shouldn't have it. We would need to parse two
properties in the DMA API code, and then combine it with knowledge as
to how the system page tables have been setup. If they've been setup
as inner sharable, then dma-coherent identifies whether the device is
coherent. If they've been setup as outer sharable, then
dma-outer-coherent specifies that and dma-coherent is meaningless.
Sounds like a recipe for confusion.
Exactly. We should leave the "dma-coherent" property to mark coherent
vs non coherent device(s).
The inner vs outer is really page table ARCH setup issue and should
be handled exactly the way it was done first place to handle the
special memory view(outside 4 GB).
Keystone needs outer shared bit set while setting up MMU pages
which is best done in MMU off mode while recreating the new
page tables.
Regards,
Santosh
On Monday, June 6, 2016 12:42:56 PM CEST Mark Rutland wrote:
On Mon, Jun 06, 2016 at 11:09:07AM +0200, Arnd Bergmann wrote:
quoted
On Monday, June 6, 2016 9:56:27 AM CEST Mark Rutland wrote:
So far, the assumption has been:
- when running a non-LPAE kernel, keystone is not coherent, and we
must ignore both the dma-coherent properties in devices and the
dma-ranges properties in bus nodes.
I wasn't able to spot if/where that was enforced. Is it possible to boot
Keystone UP, !LPAE?
With !LPAE, no devices are coherent, so that should work with both
SMP and and UP. Not sure about LPAE with coherent devices on UP,
IIRC we had a bug in that configuration on Armada XP, as the memory
was not marked as sharable at all there, and ended up not being
coherent with DMA masters.
My first guess is that uniprocessor mode on keystone has not been
tested at all (TI's QA seems to test only a very limited number of
configurations), so it may or may not work.
Arnd
From: Mark Rutland <mark.rutland@arm.com> Date: 2016-06-07 10:02:10
On Mon, Jun 06, 2016 at 01:32:10PM +0100, Russell King - ARM Linux wrote:
On Mon, Jun 06, 2016 at 12:59:18PM +0100, Mark Rutland wrote:
quoted
I agree that whether or not devices are coherent in practice depends on
the kernel's configuration. The flip side, as you point out, is that
devices are coherent when a specific set of attributes are used.
i.e. that if you read dma-coherent as meaning "coherent iff Normal,
Inner Shareable, Inner WB Cacheable, Outer WB Cacheable", then
dma-coherent consistently describes the same thing, rather than
depending on the configuration of the OS.
DT is a datastructure provided to the kernel, potentially without deep
internal knowledge of that kernel configuration. Having a consistent
rule that is independent of the kernel configuration seems worth aiming
for.
I think you've missed the point. dma-coherent is _already_ dependent on
the kernel configuration.
I understood this point. Please, allow me to clarify below, as I've
evidently not done a good job so far.
"Having a consistent rule that is independent of the kernel
configuration" is already an impossibility, as I illustrated in my
previous message concerning Marvell Armada SoCs, and you also said in
your preceding paragraph!
That's not quite what I said. What I said was that whether or not you
end up with coherency depends on the kernel's configuration. That's why
I pointed out that in practice, the only cases that work with today's
mainline kernels are this for which the devices which are coherent with
the kernel's usual memory attributes in an SMP configuration.
If you grep for dma-coherent in arch/arm/boot/dts, you'll find that
appears in:
arch/arm/boot/dts/artpec6.dtsi
arch/arm/boot/dts/ecx-common.dtsi
arch/arm/boot/dts/ls1021a.dtsi
Which are all SMP Cortex-{A7,A9,A15} platforms, and:
arch/arm/boot/dts/k2e.dtsi
arch/arm/boot/dts/k2e-netcp.dtsi
arch/arm/boot/dts/k2hk-netcp.dtsi
arch/arm/boot/dts/k2l-netcp.dtsi
arch/arm/boot/dts/keystone.dtsi
For which, as far as I am aware, the dma-coherent property does not
yield coherency with a mainline kernel, due to the requirement of Outer
Shareable attributes.
So, if we codify the dma-coherent semantics as only matching the working
case today, then it becomes consistent and independent of kernel
configuration, and we can add properties to cater for the other cases,
independent of kernel configuration.
For example, if you clear the shared bit in the page tables on non-LPAE
SoCs, devices are no longer coherent.
Yes. This is a problem, but one that we already face. If we clarified
the semantics as above, we would know that the device is simply not
coherent.
DMA coherence on ARM _is_ already tightly linked with the kernel
configuration. You already can't get away from that, so I think you
should give up trying to argue that point. :)
I hope that I've clarified my position w.r.t. coherence vs specification
thereof. :)
Whether devices are DMA coherent is a combination of two things:
* is the device connected to a coherent bus.
* is the system setup to allow coherency on that bus to work.
We capture the first through the dma-coherent property, which is clearly
a per-device property. We ignore the second because we assume everyone
is going to configure the CPU side correctly. That's untrue today, and
it's untrue not only because of Keystone II, but also because of other
SoCs as well which pre-date Keystone II. We currently miss out on
considering that, because if we ignore it, we get something that works
for most platforms.
I don't see that adding a dma-outer-coherent property helps this - it's
muddying the waters somewhat - and it's also forcing additional complexity
into places where we shouldn't have it. We would need to parse two
properties in the DMA API code, and then combine it with knowledge as
to how the system page tables have been setup. If they've been setup
as inner sharable, then dma-coherent identifies whether the device is
coherent. If they've been setup as outer sharable, then
dma-outer-coherent specifies that and dma-coherent is meaningless.
I think that at minimum, the attributes devices require needs to be
describe to the kernel, rather than being something we hope just
happened to match.
Sounds like a recipe for confusion.
Unfortunately, I think everything in this area leads to confusion. :(
Thanks,
Mark.
From: Russell King - ARM Linux <linux@armlinux.org.uk> Date: 2016-06-07 12:33:08
On Tue, Jun 07, 2016 at 11:01:43AM +0100, Mark Rutland wrote:
So, if we codify the dma-coherent semantics as only matching the working
case today, then it becomes consistent and independent of kernel
configuration, and we can add properties to cater for the other cases,
independent of kernel configuration.
That's where our points of view differ. You claim that it becomes
independent of the kernel configuration. I'm saying that's total
rubbish, because it's dependent on the kernel setting the CPU page
tables up as it does today.
If we set them up differently, then it doesn't work so well. This
is evidenced by Marvell Armada uniprocessor platforms, where they
are DMA coherent provided that the S bit is set. However, because
they are uniprocessor platforms, the kernel sets the page tables up
with the S bit clear. That means that the kernel configures the
system in a way which results in it being non-coherent.
So here, we have an example of why your position is actually incorrect.
dma-coherent does *not* give a "consistent and independent of kernel
configuration" property - it's inherently tied to how the kernel has
setup the page tables.
So, dma-coherent is coherent _provided_ the kernel sets the page tables
up as we currently expect it to - the S bit set on non-LPAE systems, on
LPAE systems, inner-sharable. If we deviate from that, (eg by clearing
the S bit on non-LPAE systems) we end up with a non-coherent system,
even if dma-coherent is specified.
The Keystone II case is no different - Keystone II is coherent if the
correct conditions are met with the CPU page tables. The only difference
is that it's a slightly different set of conditions.
quoted
For example, if you clear the shared bit in the page tables on non-LPAE
SoCs, devices are no longer coherent.
Yes. This is a problem, but one that we already face. If we clarified
the semantics as above, we would know that the device is simply not
coherent.
How? We would need to introduce some flag which is passed from the
architecture code into the OF code to disable the effect of dma-coherent,
making of_dma_is_coherent() return false if the S bit is clear.
quoted
Whether devices are DMA coherent is a combination of two things:
* is the device connected to a coherent bus.
* is the system setup to allow coherency on that bus to work.
We capture the first through the dma-coherent property, which is clearly
a per-device property. We ignore the second because we assume everyone
is going to configure the CPU side correctly. That's untrue today, and
it's untrue not only because of Keystone II, but also because of other
SoCs as well which pre-date Keystone II. We currently miss out on
considering that, because if we ignore it, we get something that works
for most platforms.
I don't see that adding a dma-outer-coherent property helps this - it's
muddying the waters somewhat - and it's also forcing additional complexity
into places where we shouldn't have it. We would need to parse two
properties in the DMA API code, and then combine it with knowledge as
to how the system page tables have been setup. If they've been setup
as inner sharable, then dma-coherent identifies whether the device is
coherent. If they've been setup as outer sharable, then
dma-outer-coherent specifies that and dma-coherent is meaningless.
I think that at minimum, the attributes devices require needs to be
describe to the kernel, rather than being something we hope just
happened to match.
Yuck. Seriously? What happens when we have two devices which have
different required attributes for the CPU mapping? Should architecture
code have to parse the entire DT tree to work out what attributes each
device needs, and try to then work out how the CPU page tables should
be setup?
I really don't think that's a good idea.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
From: Mark Rutland <mark.rutland@arm.com> Date: 2016-06-07 12:55:28
On Tue, Jun 07, 2016 at 01:32:48PM +0100, Russell King - ARM Linux wrote:
On Tue, Jun 07, 2016 at 11:01:43AM +0100, Mark Rutland wrote:
quoted
So, if we codify the dma-coherent semantics as only matching the working
case today, then it becomes consistent and independent of kernel
configuration, and we can add properties to cater for the other cases,
independent of kernel configuration.
That's where our points of view differ. You claim that it becomes
independent of the kernel configuration. I'm saying that's total
rubbish, because it's dependent on the kernel setting the CPU page
tables up as it does today.
The key point is that *description* of the requirements for coherency
becomes independent of kernel configuration. Yes, whether or not a
kernel can support those depends on the configuration.
If we set them up differently, then it doesn't work so well. This
is evidenced by Marvell Armada uniprocessor platforms, where they
are DMA coherent provided that the S bit is set. However, because
they are uniprocessor platforms, the kernel sets the page tables up
with the S bit clear. That means that the kernel configures the
system in a way which results in it being non-coherent.
So here, we have an example of why your position is actually incorrect.
dma-coherent does *not* give a "consistent and independent of kernel
configuration" property - it's inherently tied to how the kernel has
setup the page tables.
Sorry, but that is not quite what I said.
I said that if you read dma-coherent as specifying *the requirements*
for coherency (i.e. "coherent iff Normal, Inner Shareable, Inner WB
Cacheable, Outer WB Cacheable"), rather than specifying that there is
coherency given some unspecified requirements, then it is possible to
use it in a manner which is consistent and independent of kernel
configuration. If the kernel uses memory attributes that don't meet
those requirements, it can know that the device cannot be used in a
coherent manner.
If we take that stance, then we can cater for other requirements (e.g.
Outer Shareable on Keystone) by having properties to specify those
requirements (e.g. dma-outer-coherent). The tricky part is how the
kernel decides how best to use that information, but that is a problem
regardless.
quoted
quoted
For example, if you clear the shared bit in the page tables on non-LPAE
SoCs, devices are no longer coherent.
Yes. This is a problem, but one that we already face. If we clarified
the semantics as above, we would know that the device is simply not
coherent.
How? We would need to introduce some flag which is passed from the
architecture code into the OF code to disable the effect of dma-coherent,
making of_dma_is_coherent() return false if the S bit is clear.
Yes, we would need to either alter the OF code, or some code which makes
use of this. Surely it's possible to have this logic in an arch
callback?
quoted
quoted
Whether devices are DMA coherent is a combination of two things:
* is the device connected to a coherent bus.
* is the system setup to allow coherency on that bus to work.
We capture the first through the dma-coherent property, which is clearly
a per-device property. We ignore the second because we assume everyone
is going to configure the CPU side correctly. That's untrue today, and
it's untrue not only because of Keystone II, but also because of other
SoCs as well which pre-date Keystone II. We currently miss out on
considering that, because if we ignore it, we get something that works
for most platforms.
I don't see that adding a dma-outer-coherent property helps this - it's
muddying the waters somewhat - and it's also forcing additional complexity
into places where we shouldn't have it. We would need to parse two
properties in the DMA API code, and then combine it with knowledge as
to how the system page tables have been setup. If they've been setup
as inner sharable, then dma-coherent identifies whether the device is
coherent. If they've been setup as outer sharable, then
dma-outer-coherent specifies that and dma-coherent is meaningless.
I think that at minimum, the attributes devices require needs to be
describe to the kernel, rather than being something we hope just
happened to match.
Yuck. Seriously? What happens when we have two devices which have
different required attributes for the CPU mapping? Should architecture
code have to parse the entire DT tree to work out what attributes each
device needs, and try to then work out how the CPU page tables should
be setup?
No, we do not necessarily have to try to dynamically handle every
possible case, especially as the vastly common case is the one I called
out above.
For those boards where we're going to have some code special-casing
those regardless, automatically deciding to have the kernel use the
preferred set of attributes is fine. However, to do this I don't think
we should provide board+kernel specific semantics to dma-coherent, and
should at least precisely specify the coherency requirements.
Thanks,
Mark.