Message ID | 20231109210608.2252323-4-willy@infradead.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | More buffer_head cleanups | expand |
On Fri, Nov 10, 2023 at 6:06 AM Matthew Wilcox (Oracle) wrote: > > We must not shift by a negative number so work in terms of a byte > offset to avoid the awkward shift left-or-right-depending-on-sign > option. This means we need to use check_mul_overflow() to ensure > that a large block number does not result in a wrap. > > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> > --- > fs/buffer.c | 17 ++++++----------- > 1 file changed, 6 insertions(+), 11 deletions(-) > > diff --git a/fs/buffer.c b/fs/buffer.c > index 44e0c0b7f71f..9c3f49cf8d28 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -1085,26 +1085,21 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block, > static bool grow_buffers(struct block_device *bdev, sector_t block, > unsigned size, gfp_t gfp) > { > - pgoff_t index; > - int sizebits; > - > - sizebits = PAGE_SHIFT - __ffs(size); > - index = block >> sizebits; > + loff_t pos; > > /* > - * Check for a block which wants to lie outside our maximum possible > - * pagecache index. (this comparison is done using sector_t types). > + * Check for a block which lies outside our maximum possible > + * pagecache index. > */ > - if (unlikely(index != block >> sizebits)) { > - printk(KERN_ERR "%s: requested out-of-range block %llu for " > - "device %pg\n", > + if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) { > + printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n", > __func__, (unsigned long long)block, > bdev); > return false; > } > > /* Create a folio with the proper size buffers */ > - return grow_dev_folio(bdev, block, index, size, gfp); > + return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); "pos" has a loff_t type (= long long type). Was it okay to do C division directly on 32-bit architectures? Regards, Ryusuke Konishi > } > > static struct buffer_head * > -- > 2.42.0 > >
On Fri, Nov 10, 2023 at 3:37 PM Ryusuke Konishi wrote: > > On Fri, Nov 10, 2023 at 6:06 AM Matthew Wilcox (Oracle) wrote: > > > > We must not shift by a negative number so work in terms of a byte > > offset to avoid the awkward shift left-or-right-depending-on-sign > > option. This means we need to use check_mul_overflow() to ensure > > that a large block number does not result in a wrap. > > > > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> > > --- > > fs/buffer.c | 17 ++++++----------- > > 1 file changed, 6 insertions(+), 11 deletions(-) > > > > diff --git a/fs/buffer.c b/fs/buffer.c > > index 44e0c0b7f71f..9c3f49cf8d28 100644 > > --- a/fs/buffer.c > > +++ b/fs/buffer.c > > @@ -1085,26 +1085,21 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block, > > static bool grow_buffers(struct block_device *bdev, sector_t block, > > unsigned size, gfp_t gfp) > > { > > - pgoff_t index; > > - int sizebits; > > - > > - sizebits = PAGE_SHIFT - __ffs(size); > > - index = block >> sizebits; > > + loff_t pos; > > > > /* > > - * Check for a block which wants to lie outside our maximum possible > > - * pagecache index. (this comparison is done using sector_t types). > > + * Check for a block which lies outside our maximum possible > > + * pagecache index. > > */ > > - if (unlikely(index != block >> sizebits)) { > > - printk(KERN_ERR "%s: requested out-of-range block %llu for " > > - "device %pg\n", > > + if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) { > > + printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n", > > __func__, (unsigned long long)block, > > bdev); > > return false; > > } > > > > /* Create a folio with the proper size buffers */ > > - return grow_dev_folio(bdev, block, index, size, gfp); > > > + return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); > > "pos" has a loff_t type (= long long type). > Was it okay to do C division directly on 32-bit architectures? > > Regards, > Ryusuke Konishi Similar to the comment for patch 5/7, can we safely use the generally less expensive shift operation "pos >> PAGE_SHIFT" here ? Regards, Ryusuke Konishi
On Fri, Nov 10, 2023 at 08:29:41PM +0900, Ryusuke Konishi wrote: > On Fri, Nov 10, 2023 at 3:37 PM Ryusuke Konishi wrote: > > > + return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); > > > > "pos" has a loff_t type (= long long type). > > Was it okay to do C division directly on 32-bit architectures? > > Similar to the comment for patch 5/7, can we safely use the generally > less expensive shift operation "pos >> PAGE_SHIFT" here ? If your compiler sees x / 4096 and doesn't optimise it to x >> 12, you need a better compiler.
Hi Matthew, kernel test robot noticed the following build errors: [auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master next-20231110] [cannot apply to v6.6] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Return-bool-from-grow_dev_folio/20231110-051651 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20231109210608.2252323-4-willy%40infradead.org patch subject: [PATCH v2 3/7] buffer: Fix grow_buffers() for block size > PAGE_SIZE config: hexagon-comet_defconfig (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202311121240.AN8GbAbe-lkp@intel.com/ All errors (new ones prefixed by >>): >> ld.lld: error: undefined symbol: __muloti4 >>> referenced by buffer.c >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a >>> referenced by buffer.c >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a
On Sun, 12 Nov 2023 12:52:00 +0800 kernel test robot <lkp@intel.com> wrote: > Hi Matthew, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on akpm-mm/mm-everything] > [also build test ERROR on linus/master next-20231110] > [cannot apply to v6.6] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Return-bool-from-grow_dev_folio/20231110-051651 > base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything > patch link: https://lore.kernel.org/r/20231109210608.2252323-4-willy%40infradead.org > patch subject: [PATCH v2 3/7] buffer: Fix grow_buffers() for block size > PAGE_SIZE > config: hexagon-comet_defconfig (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/config) > compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202311121240.AN8GbAbe-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > >> ld.lld: error: undefined symbol: __muloti4 > >>> referenced by buffer.c > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > >>> referenced by buffer.c > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > What a peculiar compiler. I assume this fixes? --- a/fs/buffer.c~buffer-fix-grow_buffers-for-block-size-page_size-fix +++ a/fs/buffer.c @@ -1099,7 +1099,7 @@ static bool grow_buffers(struct block_de } /* Create a folio with the proper size buffers */ - return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); + return grow_dev_folio(bdev, block, pos >> PAGE_SHIFT, size, gfp); } static struct buffer_head *
On Mon, Nov 13, 2023 at 09:10:06AM -0800, Andrew Morton wrote: > On Sun, 12 Nov 2023 12:52:00 +0800 kernel test robot <lkp@intel.com> wrote: > > > Hi Matthew, > > > > kernel test robot noticed the following build errors: > > > > [auto build test ERROR on akpm-mm/mm-everything] > > [also build test ERROR on linus/master next-20231110] > > [cannot apply to v6.6] > > [If your patch is applied to the wrong git tree, kindly drop us a note. > > And when submitting patch, we suggest to use '--base' as documented in > > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > > > url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Return-bool-from-grow_dev_folio/20231110-051651 > > base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything > > patch link: https://lore.kernel.org/r/20231109210608.2252323-4-willy%40infradead.org > > patch subject: [PATCH v2 3/7] buffer: Fix grow_buffers() for block size > PAGE_SIZE > > config: hexagon-comet_defconfig (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/config) > > compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/reproduce) > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > the same patch/commit), kindly add following tags > > | Reported-by: kernel test robot <lkp@intel.com> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202311121240.AN8GbAbe-lkp@intel.com/ > > > > All errors (new ones prefixed by >>): > > > > >> ld.lld: error: undefined symbol: __muloti4 > > >>> referenced by buffer.c > > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > > >>> referenced by buffer.c > > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > > > > What a peculiar compiler. > > I assume this fixes? > > --- a/fs/buffer.c~buffer-fix-grow_buffers-for-block-size-page_size-fix > +++ a/fs/buffer.c > @@ -1099,7 +1099,7 @@ static bool grow_buffers(struct block_de > } > > /* Create a folio with the proper size buffers */ > - return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); > + return grow_dev_folio(bdev, block, pos >> PAGE_SHIFT, size, gfp); > } > > static struct buffer_head * > _ > > No, this is not a division libcall. This seems to be related to the types of the variables used in __builtin_mul_overflow() :/ for some odd reason, clang generates a libcall when passing in an 'unsigned long long' and 'unsigned int', which apparently has not been done before in the kernel? https://github.com/ClangBuiltLinux/linux/issues/1958 https://godbolt.org/z/csfGc6z6c A cast would work around this but that could have other implications I am not aware of (I've done little further investigation due to LPC): diff --git a/fs/buffer.c b/fs/buffer.c index 4eb44ccdc6be..d39934783743 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1091,7 +1091,7 @@ static bool grow_buffers(struct block_device *bdev, sector_t block, * Check for a block which lies outside our maximum possible * pagecache index. */ - if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) { + if (check_mul_overflow(block, (u64)size, &pos) || pos > MAX_LFS_FILESIZE) { printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n", __func__, (unsigned long long)block, bdev); Cheers, Nathan
Hi Nathan, On Mon, 13 Nov 2023 at 22:50, Nathan Chancellor <nathan@kernel.org> wrote: > > On Mon, Nov 13, 2023 at 09:10:06AM -0800, Andrew Morton wrote: > > On Sun, 12 Nov 2023 12:52:00 +0800 kernel test robot <lkp@intel.com> wrote: > > > > > Hi Matthew, > > > > > > kernel test robot noticed the following build errors: > > > > > > [auto build test ERROR on akpm-mm/mm-everything] > > > [also build test ERROR on linus/master next-20231110] > > > [cannot apply to v6.6] > > > [If your patch is applied to the wrong git tree, kindly drop us a note. > > > And when submitting patch, we suggest to use '--base' as documented in > > > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > > > > > url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/buffer-Return-bool-from-grow_dev_folio/20231110-051651 > > > base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything > > > patch link: https://lore.kernel.org/r/20231109210608.2252323-4-willy%40infradead.org > > > patch subject: [PATCH v2 3/7] buffer: Fix grow_buffers() for block size > PAGE_SIZE > > > config: hexagon-comet_defconfig (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/config) > > > compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) > > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231112/202311121240.AN8GbAbe-lkp@intel.com/reproduce) > > > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > > the same patch/commit), kindly add following tags > > > | Reported-by: kernel test robot <lkp@intel.com> > > > | Closes: https://lore.kernel.org/oe-kbuild-all/202311121240.AN8GbAbe-lkp@intel.com/ KFT CI also have been noticing this build problem on Linux next. Reported-by: Linux Kernel Functional Testing <lkft@linaro.org> > > > > > > All errors (new ones prefixed by >>): > > > > > > >> ld.lld: error: undefined symbol: __muloti4 > > > >>> referenced by buffer.c > > > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > > > >>> referenced by buffer.c > > > >>> fs/buffer.o:(bdev_getblk) in archive vmlinux.a > > > > > > > What a peculiar compiler. > > > > I assume this fixes? > > > > --- a/fs/buffer.c~buffer-fix-grow_buffers-for-block-size-page_size-fix > > +++ a/fs/buffer.c > > @@ -1099,7 +1099,7 @@ static bool grow_buffers(struct block_de > > } > > > > /* Create a folio with the proper size buffers */ > > - return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); > > + return grow_dev_folio(bdev, block, pos >> PAGE_SHIFT, size, gfp); > > } > > > > static struct buffer_head * > > _ > > > > > > No, this is not a division libcall. This seems to be related to the > types of the variables used in __builtin_mul_overflow() :/ for some odd > reason, clang generates a libcall when passing in an 'unsigned long > long' and 'unsigned int', which apparently has not been done before in > the kernel? > > https://github.com/ClangBuiltLinux/linux/issues/1958 > https://godbolt.org/z/csfGc6z6c > > A cast would work around this but that could have other implications I > am not aware of (I've done little further investigation due to LPC): Thanks for providing this fix patch. > diff --git a/fs/buffer.c b/fs/buffer.c > index 4eb44ccdc6be..d39934783743 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -1091,7 +1091,7 @@ static bool grow_buffers(struct block_device *bdev, sector_t block, > * Check for a block which lies outside our maximum possible > * pagecache index. > */ > - if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) { > + if (check_mul_overflow(block, (u64)size, &pos) || pos > MAX_LFS_FILESIZE) { > printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n", > __func__, (unsigned long long)block, > bdev); > > Cheers, > Nathan - Naresh
diff --git a/fs/buffer.c b/fs/buffer.c index 44e0c0b7f71f..9c3f49cf8d28 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1085,26 +1085,21 @@ static bool grow_dev_folio(struct block_device *bdev, sector_t block, static bool grow_buffers(struct block_device *bdev, sector_t block, unsigned size, gfp_t gfp) { - pgoff_t index; - int sizebits; - - sizebits = PAGE_SHIFT - __ffs(size); - index = block >> sizebits; + loff_t pos; /* - * Check for a block which wants to lie outside our maximum possible - * pagecache index. (this comparison is done using sector_t types). + * Check for a block which lies outside our maximum possible + * pagecache index. */ - if (unlikely(index != block >> sizebits)) { - printk(KERN_ERR "%s: requested out-of-range block %llu for " - "device %pg\n", + if (check_mul_overflow(block, size, &pos) || pos > MAX_LFS_FILESIZE) { + printk(KERN_ERR "%s: requested out-of-range block %llu for device %pg\n", __func__, (unsigned long long)block, bdev); return false; } /* Create a folio with the proper size buffers */ - return grow_dev_folio(bdev, block, index, size, gfp); + return grow_dev_folio(bdev, block, pos / PAGE_SIZE, size, gfp); } static struct buffer_head *
We must not shift by a negative number so work in terms of a byte offset to avoid the awkward shift left-or-right-depending-on-sign option. This means we need to use check_mul_overflow() to ensure that a large block number does not result in a wrap. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> --- fs/buffer.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)