[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHp75VcVJBSnPQ6NfdF8FdEDfM+oQ=Sr+cH5VGX4SrAqrgpf-g@mail.gmail.com>
Date: Thu, 3 Sep 2020 13:57:39 +0300
From: Andy Shevchenko <andy.shevchenko@...il.com>
To: Nicolin Chen <nicoleotsuka@...il.com>
Cc: Christoph Hellwig <hch@....de>,
Stephen Rothwell <sfr@...b.auug.org.au>,
Michael Ellerman <mpe@...erman.id.au>,
Benjamin Herrenschmidt <benh@...nel.crashing.org>,
Paul Mackerras <paulus@...ba.org>,
"open list:LINUX FOR POWERPC PA SEMI PWRFICIENT"
<linuxppc-dev@...ts.ozlabs.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
rth@...ddle.net, ink@...assic.park.msu.ru,
Matt Turner <mattst88@...il.com>, linux-alpha@...r.kernel.org,
Tony Luck <tony.luck@...el.com>,
Fenghua Yu <fenghua.yu@...el.com>, linux-ia64@...r.kernel.org,
schnelle@...ux.ibm.com, gerald.schaefer@...ux.ibm.com,
hca@...ux.ibm.com, Vasily Gorbik <gor@...ux.ibm.com>,
Christian Borntraeger <borntraeger@...ibm.com>,
linux-s390@...r.kernel.org,
"David S. Miller" <davem@...emloft.net>,
sparclinux@...r.kernel.org, Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
"maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)" <x86@...nel.org>,
"H. Peter Anvin" <hpa@...or.com>,
James Bottomley <James.Bottomley@...senpartnership.com>,
Helge Deller <deller@....de>, linux-parisc@...r.kernel.org
Subject: Re: [PATCH 1/2] dma-mapping: introduce dma_get_seg_boundary_nr_pages()
On Wed, Sep 2, 2020 at 1:20 AM Nicolin Chen <nicoleotsuka@...il.com> 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
Powered by blists - more mailing lists