[PATCH] ARM: DMA-mapping: mark all !DMA_TO_DEVICE pages in unmapping as clean

Ming Lei ming.lei at canonical.com
Tue May 14 22:59:00 EDT 2013


Hi,

On Wed, May 15, 2013 at 3:28 AM, Nicolas Pitre <nicolas.pitre at linaro.org> wrote:
> On Fri, 3 May 2013, Ming Lei wrote:
>
>> It is common for one sg to include many pages, so mark all these
>> pages as clean to avoid unnecessary flushing on them in
>> set_pte_at() or update_mmu_cache().
>
> [...]
>
>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
>> index e9db6b4..e63124a 100644
>> --- a/arch/arm/mm/dma-mapping.c
>> +++ b/arch/arm/mm/dma-mapping.c
>> @@ -879,10 +879,23 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
>>       dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
>>
>>       /*
>> -      * Mark the D-cache clean for this page to avoid extra flushing.
>> +      * Mark the D-cache clean for these pages to avoid extra flushing.
>>        */
>> -     if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
>> -             set_bit(PG_dcache_clean, &page->flags);
>> +     if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) {
>> +             unsigned long pfn;
>> +             size_t left = size;
>> +
>> +             pfn = page_to_pfn(page);
>
> Could the offset ever be greater than a page?  The code in
> dma_cache_maint_page() appears to be written with that possibility in
> mind.  So you should have:
>
>         pfn = page_to_pfn(page) + off / PAGE_SIZE;

Good catch, you are right.

>
>> +             if (off) {
>> +                     pfn++;
>> +                     left -= PAGE_SIZE - off % PAGE_SIZE;
>> +             }
>> +             while (left >= PAGE_SIZE) {
>> +                     page = pfn_to_page(pfn++);
>> +                     set_bit(PG_dcache_clean, &page->flags);
>> +                     left -= PAGE_SIZE;
>> +             }
>> +     }
>>  }
>
> Otherwise this looks fine to me.

I will send v1 with your ack, thanks for your review.

Thanks,
--
Ming Lei



More information about the linux-arm-kernel mailing list