All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Joerg Roedel <joro@8bytes.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>,
	Ingo Molnar <mingo@elte.hu>,
	the arch/x86 maintainers <x86@kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Xen-devel <xen-devel@lists.xensource.com>,
	Alex Nixon <alex.nixon@citrix.com>,
	Ian Campbell <Ian.Campbell@eu.citrix.com>
Subject: Re: [PATCH 07/11] Xen/x86/PCI: Add support for the Xen PCI subsytem
Date: Mon, 11 May 2009 13:32:08 -0700	[thread overview]
Message-ID: <4A088B48.1080900@goop.org> (raw)
In-Reply-To: <20090511094025.GA30035@8bytes.org>

Joerg Roedel wrote:
>> +static inline int address_needs_mapping(struct device *hwdev,
>> +                                             dma_addr_t addr)
>> +{
>> +     dma_addr_t mask = 0xffffffff;
>>     
>
> You can use DMA_32BIT_MASK here.
>   

OK.  Well, DMA_BIT_MASK(32), since I think DMA_XXBIT_MASK are considered 
deprecated.

>> +     int ret;
>> +
>> +     /* If the device has a mask, use it, otherwise default to 32 bits */
>> +     if (hwdev && hwdev->dma_mask)
>> +             mask = *hwdev->dma_mask;
>>     
>
> I think the check for a valid hwdev->dma_mask is not necessary. Other
> IOMMU drivers also don't check for this.
>   

OK.

>> +
>> +static int range_straddles_page_boundary(phys_addr_t p, size_t size)
>> +{
>> +     unsigned long pfn = PFN_DOWN(p);
>> +     unsigned int offset = p & ~PAGE_MASK;
>> +
>> +     if (offset + size <= PAGE_SIZE)
>> +             return 0;
>>     
>
> You can use iommu_num_pages here from lib/iommu_helpers.c
>   

Ah, useful.  Hm, but iommu_num_pages() takes the addr as an unsigned 
long, which will fail on a 32-bit machine with a 64-bit phys addr.

>> +static int xen_map_sg(struct device *hwdev, struct scatterlist *sg,
>> +                     int nents, int direction)
>> +{
>> +     struct scatterlist *s;
>> +     struct page *page;
>> +     int i, rc;
>> +
>> +     BUG_ON(direction == DMA_NONE);
>> +     WARN_ON(nents == 0 || sg[0].length == 0);
>> +
>> +     for_each_sg(sg, s, nents, i) {
>> +             BUG_ON(!sg_page(s));
>> +             page = sg_page(s);
>> +             s->dma_address = xen_dma_map_page(page) + s->offset;
>> +             s->dma_length = s->length;
>> +             IOMMU_BUG_ON(range_straddles_page_boundary(
>> +                             page_to_phys(page), s->length));
>>     
>
> I have a question on this. How do you make sure that the memory to map
> does not cross page boundarys? I have a stats counter for x-page
> requests in amd iommu code and around 10% of the requests are actually
> x-page for me.
>   

I define a BIOVEC_PHYS_MERGEABLE() which prevents BIOs from being merged 
across non-contiguous pages.  Hm, wonder where that change has gone?  It 
should probably be part of this series...

>> +     }
>> +
>> +     rc = nents;
>> +
>> +     flush_write_buffers();
>> +     return rc;
>> +}
>> +
>> +static void xen_unmap_sg(struct device *hwdev, struct scatterlist *sg,
>> +                      int nents, int direction)
>> +{
>> +     struct scatterlist *s;
>> +     struct page *page;
>> +     int i;
>> +
>> +     for_each_sg(sg, s, nents, i) {
>> +             page = pfn_to_page(mfn_to_pfn(PFN_DOWN(s->dma_address)));
>> +             xen_dma_unmap_page(page);
>> +     }
>> +}
>> +
>> +static void *xen_alloc_coherent(struct device *dev, size_t size,
>> +                             dma_addr_t *dma_handle, gfp_t gfp)
>> +{
>> +     void *ret;
>> +     struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
>> +     unsigned int order = get_order(size);
>> +     unsigned long vstart;
>> +     u64 mask;
>> +
>> +     /* ignore region specifiers */
>> +     gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
>> +
>> +     if (mem) {
>> +             int page = bitmap_find_free_region(mem->bitmap, mem->size,
>> +                                                  order);
>>     
>
> Can you use iommu_area_alloc here?
>   

There's a later patch in this series ("xen/swiotlb: use 
dma_alloc_from_coherent to get device coherent memory") which converts 
it to use dma_alloc_from_coherent().   I think that's the right thing to 
use here, rather than iommu_area_alloc().

>> +static void xen_free_coherent(struct device *dev, size_t size,
>> +                      void *vaddr, dma_addr_t dma_addr)
>> +{
>> +     struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
>> +     int order = get_order(size);
>> +
>> +     if (mem && vaddr >= mem->virt_base &&
>> +         vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
>> +             int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
>> +             bitmap_release_region(mem->bitmap, page, order);
>>     
>
> iommu_area_free
>   

I use dma_release_from_coherent() in the later patch.

Thanks,
    J

WARNING: multiple messages have this Message-ID (diff)
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Joerg Roedel <joro@8bytes.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>,
	Xen-devel <xen-devel@lists.xensource.com>,
	the arch/x86 maintainers <x86@kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Ian Campbell <Ian.Campbell@eu.citrix.com>,
	Alex Nixon <alex.nixon@citrix.com>, Ingo Molnar <mingo@elte.hu>
Subject: Re: [PATCH 07/11] Xen/x86/PCI: Add support for the Xen PCI subsytem
Date: Mon, 11 May 2009 13:32:08 -0700	[thread overview]
Message-ID: <4A088B48.1080900@goop.org> (raw)
In-Reply-To: <20090511094025.GA30035@8bytes.org>

Joerg Roedel wrote:
>> +static inline int address_needs_mapping(struct device *hwdev,
>> +                                             dma_addr_t addr)
>> +{
>> +     dma_addr_t mask = 0xffffffff;
>>     
>
> You can use DMA_32BIT_MASK here.
>   

OK.  Well, DMA_BIT_MASK(32), since I think DMA_XXBIT_MASK are considered 
deprecated.

>> +     int ret;
>> +
>> +     /* If the device has a mask, use it, otherwise default to 32 bits */
>> +     if (hwdev && hwdev->dma_mask)
>> +             mask = *hwdev->dma_mask;
>>     
>
> I think the check for a valid hwdev->dma_mask is not necessary. Other
> IOMMU drivers also don't check for this.
>   

OK.

>> +
>> +static int range_straddles_page_boundary(phys_addr_t p, size_t size)
>> +{
>> +     unsigned long pfn = PFN_DOWN(p);
>> +     unsigned int offset = p & ~PAGE_MASK;
>> +
>> +     if (offset + size <= PAGE_SIZE)
>> +             return 0;
>>     
>
> You can use iommu_num_pages here from lib/iommu_helpers.c
>   

Ah, useful.  Hm, but iommu_num_pages() takes the addr as an unsigned 
long, which will fail on a 32-bit machine with a 64-bit phys addr.

>> +static int xen_map_sg(struct device *hwdev, struct scatterlist *sg,
>> +                     int nents, int direction)
>> +{
>> +     struct scatterlist *s;
>> +     struct page *page;
>> +     int i, rc;
>> +
>> +     BUG_ON(direction == DMA_NONE);
>> +     WARN_ON(nents == 0 || sg[0].length == 0);
>> +
>> +     for_each_sg(sg, s, nents, i) {
>> +             BUG_ON(!sg_page(s));
>> +             page = sg_page(s);
>> +             s->dma_address = xen_dma_map_page(page) + s->offset;
>> +             s->dma_length = s->length;
>> +             IOMMU_BUG_ON(range_straddles_page_boundary(
>> +                             page_to_phys(page), s->length));
>>     
>
> I have a question on this. How do you make sure that the memory to map
> does not cross page boundarys? I have a stats counter for x-page
> requests in amd iommu code and around 10% of the requests are actually
> x-page for me.
>   

I define a BIOVEC_PHYS_MERGEABLE() which prevents BIOs from being merged 
across non-contiguous pages.  Hm, wonder where that change has gone?  It 
should probably be part of this series...

>> +     }
>> +
>> +     rc = nents;
>> +
>> +     flush_write_buffers();
>> +     return rc;
>> +}
>> +
>> +static void xen_unmap_sg(struct device *hwdev, struct scatterlist *sg,
>> +                      int nents, int direction)
>> +{
>> +     struct scatterlist *s;
>> +     struct page *page;
>> +     int i;
>> +
>> +     for_each_sg(sg, s, nents, i) {
>> +             page = pfn_to_page(mfn_to_pfn(PFN_DOWN(s->dma_address)));
>> +             xen_dma_unmap_page(page);
>> +     }
>> +}
>> +
>> +static void *xen_alloc_coherent(struct device *dev, size_t size,
>> +                             dma_addr_t *dma_handle, gfp_t gfp)
>> +{
>> +     void *ret;
>> +     struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
>> +     unsigned int order = get_order(size);
>> +     unsigned long vstart;
>> +     u64 mask;
>> +
>> +     /* ignore region specifiers */
>> +     gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
>> +
>> +     if (mem) {
>> +             int page = bitmap_find_free_region(mem->bitmap, mem->size,
>> +                                                  order);
>>     
>
> Can you use iommu_area_alloc here?
>   

There's a later patch in this series ("xen/swiotlb: use 
dma_alloc_from_coherent to get device coherent memory") which converts 
it to use dma_alloc_from_coherent().   I think that's the right thing to 
use here, rather than iommu_area_alloc().

>> +static void xen_free_coherent(struct device *dev, size_t size,
>> +                      void *vaddr, dma_addr_t dma_addr)
>> +{
>> +     struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
>> +     int order = get_order(size);
>> +
>> +     if (mem && vaddr >= mem->virt_base &&
>> +         vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
>> +             int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
>> +             bitmap_release_region(mem->bitmap, page, order);
>>     
>
> iommu_area_free
>   

I use dma_release_from_coherent() in the later patch.

Thanks,
    J

  reply	other threads:[~2009-05-11 20:32 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-07 21:45 [GIT PULL] xen: dom0 support for PCI access Jeremy Fitzhardinge
2009-05-07 21:45 ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 01/11] xen: Don't disable the I/O space Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 02/11] xen: Allow unprivileged Xen domains to create iomap pages Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 03/11] Xen: Rename the balloon lock Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-08  2:01   ` [Xen-devel] " Isaku Yamahata
2009-05-08  2:01     ` Isaku Yamahata
2009-05-11 19:00     ` [Xen-devel] " Jeremy Fitzhardinge
2009-05-12  2:47       ` Isaku Yamahata
2009-05-12  2:47         ` Isaku Yamahata
2009-05-07 21:45 ` [PATCH 04/11] xen: Add xen_create_contiguous_region Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 05/11] x86/PCI: Clean up pci_cache_line_size Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 06/11] x86/PCI: Enable scanning of all pci functions Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 07/11] Xen/x86/PCI: Add support for the Xen PCI subsytem Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-11  9:40   ` Joerg Roedel
2009-05-11 20:32     ` Jeremy Fitzhardinge [this message]
2009-05-11 20:32       ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 08/11] xen/swiotlb: use dma_alloc_from_coherent to get device coherent memory Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 09/11] x86/pci: make sure _PAGE_IOMAP it set on pci mappings Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 10/11] xen/pci: clean up Kconfig a bit Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-07 21:45 ` [PATCH 11/11] xen: checkpatch cleanups Jeremy Fitzhardinge
2009-05-07 21:45   ` Jeremy Fitzhardinge
2009-05-08 11:10 ` [GIT PULL] xen: dom0 support for PCI access Ingo Molnar
2009-05-08 11:10   ` Ingo Molnar
2009-05-08 12:44   ` Matthew Wilcox
2009-05-08 19:46     ` Yinghai Lu
2009-05-08 21:05       ` Jeremy Fitzhardinge
2009-05-09 13:32       ` Matthew Wilcox
2009-05-09 15:43     ` Jeremy Fitzhardinge
2009-05-09 20:08       ` Matthew Wilcox
2009-05-11 12:49         ` Ingo Molnar

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=4A088B48.1080900@goop.org \
    --to=jeremy@goop.org \
    --cc=Ian.Campbell@eu.citrix.com \
    --cc=alex.nixon@citrix.com \
    --cc=joro@8bytes.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xensource.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 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.