Re: [PATCH 1/2] dma-mapping: introduce dma_get_seg_boundary_nr_pages()
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
- To: Nicolin Chen <nicoleotsuka@xxxxxxxxx>
- Subject: Re: [PATCH 1/2] dma-mapping: introduce dma_get_seg_boundary_nr_pages()
- From: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
- Date: Thu, 3 Sep 2020 13:57:39 +0300
- Cc: Christoph Hellwig <hch@xxxxxx>, Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx>, Michael Ellerman <mpe@xxxxxxxxxxxxxx>, Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx>, Paul Mackerras <paulus@xxxxxxxxx>, "open list:LINUX FOR POWERPC PA SEMI PWRFICIENT" <linuxppc-dev@xxxxxxxxxxxxxxxx>, Linux Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>, rth@xxxxxxxxxxx, ink@xxxxxxxxxxxxxxxxxxxx, Matt Turner <mattst88@xxxxxxxxx>, linux-alpha@xxxxxxxxxxxxxxx, Tony Luck <tony.luck@xxxxxxxxx>, Fenghua Yu <fenghua.yu@xxxxxxxxx>, linux-ia64@xxxxxxxxxxxxxxx, schnelle@xxxxxxxxxxxxx, gerald.schaefer@xxxxxxxxxxxxx, hca@xxxxxxxxxxxxx, Vasily Gorbik <gor@xxxxxxxxxxxxx>, Christian Borntraeger <borntraeger@xxxxxxxxxx>, linux-s390@xxxxxxxxxxxxxxx, "David S. Miller" <davem@xxxxxxxxxxxxx>, sparclinux@xxxxxxxxxxxxxxx, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, Ingo Molnar <mingo@xxxxxxxxxx>, Borislav Petkov <bp@xxxxxxxxx>, "maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)" <x86@xxxxxxxxxx>, "H. Peter Anvin" <hpa@xxxxxxxxx>, James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>, Helge Deller <deller@xxxxxx>, linux-parisc@xxxxxxxxxxxxxxx
- In-reply-to: <20200901221646.26491-2-nicoleotsuka@gmail.com>
- References: <20200901221646.26491-1-nicoleotsuka@gmail.com> <20200901221646.26491-2-nicoleotsuka@gmail.com>
On Wed, Sep 2, 2020 at 1:20 AM Nicolin Chen <nicoleotsuka@xxxxxxxxx> wrote:
>
> We found that callers of dma_get_seg_boundary mostly do an ALIGN
> with page mask and then do a page shift to get number of pages:
> ALIGN(boundary + 1, 1 << shift) >> shift
>
> However, the boundary might be as large as ULONG_MAX, which means
> that a device has no specific boundary limit. So either "+ 1" or
> passing it to ALIGN() would potentially overflow.
>
> According to kernel defines:
> #define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
> #define ALIGN(x, a) ALIGN_MASK(x, (typeof(x))(a) - 1)
>
> We can simplify the logic here into a helper function doing:
> ALIGN(boundary + 1, 1 << shift) >> shift
> = ALIGN_MASK(b + 1, (1 << s) - 1) >> s
> = {[b + 1 + (1 << s) - 1] & ~[(1 << s) - 1]} >> s
> = [b + 1 + (1 << s) - 1] >> s
> = [b + (1 << s)] >> s
> = (b >> s) + 1
>
> This patch introduces and applies dma_get_seg_boundary_nr_pages()
> as an overflow-free helper for the dma_get_seg_boundary() callers
> to get numbers of pages. It also takes care of the NULL dev case
> for non-DMA API callers.
...
> +static inline unsigned long dma_get_seg_boundary_nr_pages(struct device *dev,
> + unsigned int page_shift)
> +{
> + if (!dev)
> + return (U32_MAX >> page_shift) + 1;
> + return (dma_get_seg_boundary(dev) >> page_shift) + 1;
Can it be better to do something like
unsigned long boundary = dev ? dma_get_seg_boundary(dev) : U32_MAX;
return (boundary >> page_shift) + 1;
?
> +}
--
With Best Regards,
Andy Shevchenko
[Index of Archives]
[Linux Kernel]
[Sparc Linux]
[DCCP]
[Linux ARM]
[Yosemite News]
[Linux SCSI]
[Linux x86_64]
[Linux for Ham Radio]