On Tue, 2019-06-11 at 20:52 -0500, Larry Finger wrote: > On 6/11/19 5:46 PM, Benjamin Herrenschmidt wrote: > > On Tue, 2019-06-11 at 17:20 -0500, Larry Finger wrote: > > > b43-pci-bridge 0001:11:00.0: dma_direct_supported: failed (mask = > > > 0x3fffffff, > > > min_mask = 0x5ffff000/0x5ffff000, dma bits = 0x1f > > > > Ugh ? A mask with holes in it ? That's very wrong... That min_mask is > > bogus. > > I agree, but that is not likely serious as most systems will have enough memory > that the max_pfn term will be much larger than the initial min_mask, and > min_mask will be unchanged by the min function. Well no... it's too much memory that is the problem. If min_mask is bogus though it will cause problem later too, so one should look into it. > In addition, min_mask is not > used beyond this routine, and then only to decide if direct dma is supported. > The following patch generates masks with no holes, but I cannot see that it is > needed. The right fix is to round up max_pfn to a power of 2, something like min_mask = min_t(u64, min_mask, (roundup_pow_of_two(max_pfn - 1)) << PAGE_SHIFT) > diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c > index 2c2772e9702a..e3edd4f29e80 100644 > --- a/kernel/dma/direct.c > +++ b/kernel/dma/direct.c > @@ -384,7 +384,8 @@ int dma_direct_supported(struct device *dev, u64 mask) > else > min_mask = DMA_BIT_MASK(32); > > - min_mask = min_t(u64, min_mask, (max_pfn - 1) << PAGE_SHIFT); > + min_mask = min_t(u64, min_mask, ((max_pfn - 1) << PAGE_SHIFT) | > + DMA_BIT_MASK(PAGE_SHIFT)); > > /* > * This check needs to be against the actual bit mask value, so > > > Larry