Background: Quite a few servers on the market today include an IOMMU to try to patch up bus to memory accessibility issues. However, a fair number come with the caveat that actually using the IOMMU is expensive. Some IOMMUs come with a "bypass" mode, where the IOMMU won't try to translate the physical address coming from the device but will instead place it directly on the memory bus. For some machines (ia-64, and possibly x86_64) any address not programmed into the IOMMU for translation is viewed as a bypass. For others (parisc SBA) you have to assert specific address bus bits to get the bypass. All IOMMUs supporting the bypass mode will allow it to be used selectively, so a DMA transfer may include SG both bypass and mapped segments. The Problem: At the moment, the block layer assumes segments may be virtually mergeable (i.e. two phsically discondiguous pages may be treated as a single SG entity for DMA because the IOMMU will patch up the discontinuity) if an IOMMU is present in the system. This effectively stymies using bypass mode, because segments may not be virtually merged in a bypass operation. The Solution: Is to teach the block layer not to virtually merge segments if either segment may be bypassed. To that end, the block layer has to know what the physical dma mask is (not the bounce limit, which is different) and it must also know the address bits that must be asserted in bypass mode. To that end, I've introduced a new #define for asm/io.h BIO_VMERGE_BYPASS_MASK Which is set either to the physical bits that have to be asserted, or simply to an address (like 0x1) that will always pass the device's dma_mask. I've also introduced a new block layer callback blk_queue_dma_mask(q, dma_mask) Who's job is to set the physical dma_mask of the queue (it defaults to 0xffffffff) You can see how this works in the attached patch (block layer only; the DMA engines of platforms wishing to take advantage of bypassing would also have to be altered). Comments? James