* Ingo Molnar <mingo@elte.hu> wrote:Houston, we've got a problem! :-/ randconfig testing found that this patchset broke sendfile on certain .config's - DMA started returning all 0xfffffffff data, corrupting files. (config attached) After some bisection fun it turns out that the conversions from struct page are wrong: +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + size_t offset, size_t size, + int direction) +{ + return dma_map_single(dev, page_address(page)+offset, size, direction); because page_address() is not defined for highmem pages in general. (and even if it's defined, it will corrupt data) changing it to page_to_phys() is not good because it goes via a 32-bit bottleneck that trims things on PAE: dma_addr_t (*map_single)(struct device *hwdev, void *ptr, the 'ptr' is 32-bit albeit it's a DMA target. what i came up is the prototype 32-bit fix below - this works on 32-bit but breaks 64-bit because we pass in physical addresses instead of virtual direct addresses. i'll fix the 64-bit side but that means materially touching all the dma_mapping_ops instantiations materially on the 64-bit side - not really something we wanted to do :-/ Ingo ----------------> Subject: x86: dma-ops on highmem fix From: Ingo Molnar <mingo@elte.hu> Signed-off-by: Ingo Molnar <mingo@elte.hu> --- arch/x86/kernel/pci-base_32.c | 4 ++-- include/asm-x86/dma-mapping.h | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) Index: linux-x86.q/arch/x86/kernel/pci-base_32.c =================================================================== --- linux-x86.q.orig/arch/x86/kernel/pci-base_32.c +++ linux-x86.q/arch/x86/kernel/pci-base_32.c @@ -4,12 +4,12 @@ #include <linux/dma-mapping.h> #include <asm/dma-mapping.h> -static dma_addr_t pci32_map_single(struct device *dev, void *ptr, +static dma_addr_t pci32_map_single(struct device *dev, u64 ptr, size_t size, int direction) { WARN_ON(size == 0); flush_write_buffers(); - return virt_to_phys(ptr); + return ptr; } static int pci32_dma_map_sg(struct device *dev, struct scatterlist *sglist, Index: linux-x86.q/include/asm-x86/dma-mapping.h =================================================================== --- linux-x86.q.orig/include/asm-x86/dma-mapping.h +++ linux-x86.q/include/asm-x86/dma-mapping.h @@ -16,10 +16,10 @@ struct dma_mapping_ops { dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); - dma_addr_t (*map_single)(struct device *hwdev, void *ptr, + dma_addr_t (*map_single)(struct device *hwdev, u64 ptr, size_t size, int direction); /* like map_single, but doesn't check the device mask */ - dma_addr_t (*map_simple)(struct device *hwdev, char *ptr, + dma_addr_t (*map_simple)(struct device *hwdev, u64 ptr, size_t size, int direction); void (*unmap_single)(struct device *dev, dma_addr_t addr, size_t size, int direction); @@ -73,7 +73,7 @@ dma_map_single(struct device *hwdev, voi int direction) { BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(hwdev, ptr, size, direction); + return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void @@ -174,7 +174,9 @@ static inline dma_addr_t dma_map_page(st size_t offset, size_t size, int direction) { - return dma_map_single(dev, page_address(page)+offset, size, direction); + BUG_ON(!valid_dma_direction(direction)); + return dma_ops->map_single(dev, page_to_phys(page)+offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| James Bottomley | Re: Announce: Linux-next (Or Andrew's dream :-)) |
| Andrew Morton | echo mem > /sys/power/state |
| Peter Zijlstra | [PATCH 00/23] per device dirty throttling -v8 |
git: | |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| David Miller | [GIT]: Networking |
| Gerrit Renker | [PATCH 18/37] dccp: Support for Mandatory options |
| Michael S. Tsirkin | Re: [RFC PATCH v2 03/19] vbus: add connection-client helper infrastructure |
| NeilBrown | [PATCH 00/18] Assorted md patches headed for 2.6.30 |
| Justin Piszcz | General question (scheduler) with SSDs? |
| Neil Brown | Re: Any hope for a 27 disk RAID6+1HS array with four disks reporting "No md superb... |
| Ryan Wagoner | High IO Wait with RAID 1 |
