From: Alex Ivanov <gnidorah@p0n4ik.tk>
To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Maling list - DRI developers <dri-devel@lists.freedesktop.org>
Subject: Re: drm/radeon: "ring test failed" on PA-RISC Linux
Date: Thu, 26 Sep 2013 12:39:03 +0400 [thread overview]
Message-ID: <316151380184743@web9m.yandex.ru> (raw)
In-Reply-To: <85011380135064@web26m.yandex.ru>
Let's go futher.
25.09.2013, 22:58, "Alex Ivanov" <gnidorah@p0n4ik.tk>:
> 25.09.2013, 21:28, "Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com>:
>> I took a look at the arch/parisc/kernel/pci-dma.c and I see that
>> is mostly a flat platform. That is bus addresses == physical addresses.
>> Unless it is an pclx or pclx2 CPU type (huh?) - if its it that
>> then any calls to dma_alloc_coherent will map memory out of a pool.
>> In essence it will look like a SWIOTLB bounce buffer.
> arch/parisc/kernel/pci-dma.c:
> ** PARISC 1.1 Dynamic DMA mapping support.
> ** This implementation is for PA-RISC platforms that do not support
> ** I/O TLBs (aka DMA address translation hardware).
>
> That's very old. PA-RISC 2.0 came into the game circa 1996.
> PA-RISC 1.1 is 32-bit only and i even not sure whether these machines
> had PCI bus.
>
> Only old boxes (PA7200 CPU and lower) cannot use dma_alloc_coherent()
> (and forced to do syncs iirc). That's not our case.
> And PA-RISC configs have 'Discontiguous Memory' choosen.
>> But interestingly enough there is a lot of 'flush_kernel_dcache_range'
>> call for every DMA operation.
>> And I think the you need to do
>> dma_sync_for_cpu call in the radeon_test_writeback for it to
>> use the flush_kernel_dcache_range.
I was correct regarding syncs.
In our case (SBA IOMMU) dma_sync* calls are no-ops:
sba_iommu.c:
static struct hppa_dma_ops sba_ops = {
...
.dma_sync_single_for_cpu = NULL,
.dma_sync_single_for_device = NULL,
.dma_sync_sg_for_cpu = NULL,
.dma_sync_sg_for_device = NULL,
}
dma-mapping.h:
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
if(hppa_dma_ops->dma_sync_single_for_cpu)
flush_kernel_dcache_range((unsigned long)vaddr, size);
}
So i'll skip doing the flush_kernel_dcache_range().
>> I don't know what the
>> flush_kernel_dcache_range does thought so I could be wrong.
> D-cache is a CPU cache (if they meant it).
> Seems to be L1-level. There is an I-cache at same level.
>> You are missing a translation here (you were comparing the virtual address
>> to the bus address). I was thinking something along this:
> Yes, this confused me. I've translated your suggestion literally :\
>> unsigned int pfn = page_to_pfn(ttm->pages[i]);
>> dma_addr_t bus = gtt->ttm.dma_address[i];
>> void *va_bus, *va, *va_pfn;
>>
>> if ((pfn << PAGE_SHIFT) != bus)
>> printk("Bus 0x%lx != PFN 0x%lx, bus, pfn << PAGE_SHIFT); /* OK, that means
>> bus addresses are different */
>>
>> va_bus = bus_to_virt(gtt->ttm.dma_address[i]);
>> va_pfn = __va(pfn << PAGE_SHIFT);
>>
>> if (!virt_addr_valid(va_bus))
>> printk("va_bus (0x%lx) not good!\n", va_bus);
>> if (!virt_addr_valid(va_pfn))
>> printk("va_pfn (0x%lx) not good!\n", va_pfn);
>>
>> /* We got VA for both bus -> va, and pfn -> va. Should be the
>> same if bus and physical addresses are on the same namespace. */
>> if (va_bus != va_pfn)
>> printk("va bus:%lx != va pfn: %lx\n", va_bus, va_pfn);
>>
>> /* Now that we have bus -> pa -> va (va_bus) try to go va_bus -> bus address.
>> The bus address should be the same */
>> if (gtt->tmm.dma_address[i] != virt_to_bus(va_bus))
>> printk("bus->pa->va:%lx != bus->pa->va->ba: %lx\n", gtt->tmm.dma_address[i],virt_to_bus(va_bus));
Ok, slightly modified:
struct page *page = ttm->pages[i];
unsigned long pfn = page_to_pfn(page);
dma_addr_t bus = gtt->ttm.dma_address[i];
void *va_bus, *va, *va_pfn;
BUG_ON(!pfn_valid(pfn));
//BUG_ON(!page_mapping(page)); // Leads to a kernel BUG
/* Avoid floodage */
if (i % 100 == 0) {
if ((pfn << PAGE_SHIFT) != bus)
printk("Bus 0x%lx != PFN 0x%lx\n", bus, pfn << PAGE_SHIFT); /*
OK, that means bus addresses are different */
va_bus = bus_to_virt(bus);
va_pfn = __va(pfn << PAGE_SHIFT);
if (!virt_addr_valid(va_bus))
printk("va_bus (0x%lx) not good!\n", va_bus);
if (!virt_addr_valid(va_pfn))
printk("va_pfn (0x%lx) not good!\n", va_pfn);
/* We got VA for both bus -> va, and pfn -> va. Should be the
same if bus and physical addresses are on the same namespace. */
if (va_bus != va_pfn)
printk("va bus: %lx != va pfn: %lx\n", va_bus, va_pfn);
/* Now that we have bus -> pa -> va (va_bus) try to go va_bus -> bus address.
The bus address should be the same */
if (bus != virt_to_bus(va_bus))
printk("bus->pa->va: %lx != bus->pa->va->ba: %lx\n", bus,virt_to_bus(va_bus));
}
Output:
Bus 0x40280000 != PFN 0x3e92d000
va_bus (0x80280000) not good!
va bus: 80280000 != va pfn: 7e92d000
Bus 0x40281000 != PFN 0x3e930000
va_bus (0x80281000) not good!
va bus: 80281000 != va pfn: 7e930000
...
va_bus is invalid. That's the reason i was getting a KF trying to read data behind it.
>>> DRM_INFO("MISMATCH: %p != %p\n", va, (void *) virt_to_bus(va));
>>> /*DRM_INFO("CONTENTS: %x\n", *((uint32_t *)va));*/ // Leads to a Kernel Fault
>> That is odd. I would have thought it would be usuable.
>>> ...
>>> }
>>>
>>> I'm getting the output:
>>>
>>> [drm] MISMATCH: 0000000080280000 != 0000000040280000
>> In theory that means the bus address that is programmed in (gtt->dma_address[i])
>> is 0000000040280000 (which is what virt_to_bus(va) should have resolved itself to).
> Should resolved properly. I had a sane check of virt_to_bus(va) == gtt->ttm.dma_address[i]
>> Tha you can't get access to 'va' (0000000080280000) is odd. One way to try to
>> access it is to do:
>>
>> va = __va(page_to_pfn(ttm->pages[i]) << PAGE_SHIFT);
>> DRM_INFO("CONTENTS: %x\n", *((uint32_t)va));
>>
>> As that would get it via the page -> va.
This way i get CONTENTS: 0
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2013-09-26 8:39 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <995101375614033@web11d.yandex.ru>
2013-09-09 16:44 ` drm/radeon: "ring test failed" on PA-RISC Linux Alex Ivanov
2013-09-09 17:43 ` Alex Deucher
2013-09-10 9:20 ` Alex Ivanov
2013-09-10 12:37 ` Alex Deucher
2013-09-10 13:03 ` Hans Verkuil
2013-09-10 13:25 ` Konrad Rzeszutek Wilk
2013-09-17 9:23 ` Alex Ivanov
2013-09-17 14:24 ` Alex Deucher
2013-09-17 19:33 ` Alex Ivanov
2013-09-20 6:52 ` Alex Ivanov
2013-09-20 21:27 ` Alex Deucher
2013-09-21 3:39 ` Alex Ivanov
2013-09-23 20:11 ` Konrad Rzeszutek Wilk
2013-09-25 16:29 ` Alex Ivanov
2013-09-25 17:28 ` Konrad Rzeszutek Wilk
2013-09-25 18:17 ` Alex Deucher
2013-09-25 18:51 ` Alex Ivanov
2013-09-26 8:39 ` Alex Ivanov [this message]
2013-09-10 15:45 ` Michel Dänzer
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=316151380184743@web9m.yandex.ru \
--to=gnidorah@p0n4ik.tk \
--cc=dri-devel@lists.freedesktop.org \
--cc=konrad.wilk@oracle.com \
/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