[PATCH v3 3/9] block: prevent race condition on bi_status in __bio_chain_endio

zhangshida posted 9 patches 2 months, 1 week ago
There is a newer version of this series
[PATCH v3 3/9] block: prevent race condition on bi_status in __bio_chain_endio
Posted by zhangshida 2 months, 1 week ago
From: Shida Zhang <zhangshida@kylinos.cn>

Andreas point out that multiple completions can race setting
bi_status.

The check (parent->bi_status) and the subsequent write are not an
atomic operation. The value of parent->bi_status could have changed
between the time you read it for the if check and the time you write
to it. So we use cmpxchg to fix the race, as suggested by Christoph.

Suggested-by: Andreas Gruenbacher <agruenba@redhat.com>
Suggested-by: Christoph Hellwig <hch@infradead.org>
Suggested-by: Caleb Sander Mateos <csander@purestorage.com>
Signed-off-by: Shida Zhang <zhangshida@kylinos.cn>
---
 block/bio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 1b5e4577f4c..097c1cd2054 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -314,8 +314,9 @@ static struct bio *__bio_chain_endio(struct bio *bio)
 {
 	struct bio *parent = bio->bi_private;
 
-	if (bio->bi_status && !parent->bi_status)
-		parent->bi_status = bio->bi_status;
+	if (bio->bi_status)
+		cmpxchg(&parent->bi_status, 0, bio->bi_status);
+
 	bio_put(bio);
 	return parent;
 }
-- 
2.34.1
Re: [PATCH v3 3/9] block: prevent race condition on bi_status in __bio_chain_endio
Posted by kernel test robot 2 months ago
Hi zhangshida,

kernel test robot noticed the following build warnings:

[auto build test WARNING on axboe/for-next]
[also build test WARNING on xfs-linux/for-next nvdimm/libnvdimm-for-next linus/master brauner-vfs/vfs.all v6.18 next-20251205]
[cannot apply to nvdimm/dax-misc]
[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/zhangshida/md-bcache-fix-improper-use-of-bi_end_io/20251129-170348
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git for-next
patch link:    https://lore.kernel.org/r/20251129090122.2457896-4-zhangshida%40kylinos.cn
patch subject: [PATCH v3 3/9] block: prevent race condition on bi_status in __bio_chain_endio
config: loongarch-randconfig-r133-20251130 (https://download.01.org/0day-ci/archive/20251207/202512070122.my7vkR7A-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251207/202512070122.my7vkR7A-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/202512070122.my7vkR7A-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> block/bio.c:319:17: sparse: sparse: cast from restricted blk_status_t
>> block/bio.c:319:17: sparse: sparse: cast from restricted blk_status_t
>> block/bio.c:319:17: sparse: sparse: cast to restricted blk_status_t

vim +319 block/bio.c

   313	
   314	static struct bio *__bio_chain_endio(struct bio *bio)
   315	{
   316		struct bio *parent = bio->bi_private;
   317	
   318		if (bio->bi_status)
 > 319			cmpxchg(&parent->bi_status, 0, bio->bi_status);
   320	
   321		bio_put(bio);
   322		return parent;
   323	}
   324	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v3 3/9] block: prevent race condition on bi_status in __bio_chain_endio
Posted by Christoph Hellwig 2 months, 1 week ago
On Sat, Nov 29, 2025 at 05:01:16PM +0800, zhangshida wrote:
> From: Shida Zhang <zhangshida@kylinos.cn>
> 
> Andreas point out that multiple completions can race setting
> bi_status.
> 
> The check (parent->bi_status) and the subsequent write are not an
> atomic operation. The value of parent->bi_status could have changed
> between the time you read it for the if check and the time you write
> to it. So we use cmpxchg to fix the race, as suggested by Christoph.

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>