diff mbox series

[RESEND,1/5] loop: remove 'rw' parameter from lo_rw_aio()

Message ID 20250308162312.1640828-2-ming.lei@redhat.com (mailing list archive)
State New
Headers show
Series loop: improve loop aio perf by IOCB_NOWAIT | expand

Commit Message

Ming Lei March 8, 2025, 4:23 p.m. UTC
lo_rw_aio() is only called for READ/WRITE operation, which can be
figured out from request directly, so remove 'rw' parameter from
lo_rw_aio(), meantime rename the local variable as 'dir' which matches
the actual use more.

Meantime merge lo_read_simple() and lo_write_simple() into
lo_rw_simple().

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/block/loop.c | 48 ++++++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 29 deletions(-)

Comments

kernel test robot March 9, 2025, 7:30 a.m. UTC | #1
Hi Ming,

kernel test robot noticed the following build warnings:

[auto build test WARNING on axboe-block/for-next]
[also build test WARNING on linus/master v6.14-rc5 next-20250307]
[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/Ming-Lei/loop-remove-rw-parameter-from-lo_rw_aio/20250309-002548
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
patch link:    https://lore.kernel.org/r/20250308162312.1640828-2-ming.lei%40redhat.com
patch subject: [RESEND PATCH 1/5] loop: remove 'rw' parameter from lo_rw_aio()
config: arm-randconfig-001-20250309 (https://download.01.org/0day-ci/archive/20250309/202503091516.7U64QwvF-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project e15545cad8297ec7555f26e5ae74a9f0511203e7)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250309/202503091516.7U64QwvF-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/202503091516.7U64QwvF-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/block/loop.c:250:3: warning: variable 'ret' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
     250 |                 rq_for_each_segment(bvec, rq, iter) {
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/blk-mq.h:1043:2: note: expanded from macro 'rq_for_each_segment'
    1043 |         __rq_for_each_bio(_iter.bio, _rq)                       \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/blk-mq.h:1039:6: note: expanded from macro '__rq_for_each_bio'
    1039 |         if ((rq->bio))                  \
         |             ^~~~~~~~~
   drivers/block/loop.c:256:10: note: uninitialized use occurs here
     256 |                 return ret;
         |                        ^~~
   drivers/block/loop.c:250:3: note: remove the 'if' if its condition is always true
     250 |                 rq_for_each_segment(bvec, rq, iter) {
         |                 ^
   include/linux/blk-mq.h:1043:2: note: expanded from macro 'rq_for_each_segment'
    1043 |         __rq_for_each_bio(_iter.bio, _rq)                       \
         |         ^
   include/linux/blk-mq.h:1039:2: note: expanded from macro '__rq_for_each_bio'
    1039 |         if ((rq->bio))                  \
         |         ^
   drivers/block/loop.c:248:10: note: initialize the variable 'ret' to silence this warning
     248 |                 int ret;
         |                        ^
         |                         = 0
   1 warning generated.


vim +250 drivers/block/loop.c

^1da177e4c3f41 Linus Torvalds    2005-04-16  239  
e1d39dbf4716cd Ming Lei          2025-03-09  240  static int lo_rw_simple(struct loop_device *lo, struct request *rq, loff_t pos)
^1da177e4c3f41 Linus Torvalds    2005-04-16  241  {
aa4d86163e4e91 Christoph Hellwig 2015-04-07  242  	struct bio_vec bvec;
aa4d86163e4e91 Christoph Hellwig 2015-04-07  243  	struct req_iterator iter;
e1d39dbf4716cd Ming Lei          2025-03-09  244  	struct iov_iter i;
e1d39dbf4716cd Ming Lei          2025-03-09  245  	ssize_t len;
e1d39dbf4716cd Ming Lei          2025-03-09  246  
e1d39dbf4716cd Ming Lei          2025-03-09  247  	if (req_op(rq) == REQ_OP_WRITE) {
e1d39dbf4716cd Ming Lei          2025-03-09  248  		int ret;
aa4d86163e4e91 Christoph Hellwig 2015-04-07  249  
aa4d86163e4e91 Christoph Hellwig 2015-04-07 @250  		rq_for_each_segment(bvec, rq, iter) {
aa4d86163e4e91 Christoph Hellwig 2015-04-07  251  			ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
aa4d86163e4e91 Christoph Hellwig 2015-04-07  252  			if (ret < 0)
aa4d86163e4e91 Christoph Hellwig 2015-04-07  253  				break;
^1da177e4c3f41 Linus Torvalds    2005-04-16  254  			cond_resched();
^1da177e4c3f41 Linus Torvalds    2005-04-16  255  		}
aa4d86163e4e91 Christoph Hellwig 2015-04-07  256  		return ret;
aa4d86163e4e91 Christoph Hellwig 2015-04-07  257  	}
aa4d86163e4e91 Christoph Hellwig 2015-04-07  258  
aa4d86163e4e91 Christoph Hellwig 2015-04-07  259  	rq_for_each_segment(bvec, rq, iter) {
de4eda9de2d957 Al Viro           2022-09-15  260  		iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len);
18e9710ee59ce3 Christoph Hellwig 2017-05-27  261  		len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);
aa4d86163e4e91 Christoph Hellwig 2015-04-07  262  		if (len < 0)
aa4d86163e4e91 Christoph Hellwig 2015-04-07  263  			return len;
aa4d86163e4e91 Christoph Hellwig 2015-04-07  264  
aa4d86163e4e91 Christoph Hellwig 2015-04-07  265  		flush_dcache_page(bvec.bv_page);
^1da177e4c3f41 Linus Torvalds    2005-04-16  266  
aa4d86163e4e91 Christoph Hellwig 2015-04-07  267  		if (len != bvec.bv_len) {
aa4d86163e4e91 Christoph Hellwig 2015-04-07  268  			struct bio *bio;
fd5821404e6823 Jens Axboe        2007-06-12  269  
aa4d86163e4e91 Christoph Hellwig 2015-04-07  270  			__rq_for_each_bio(bio, rq)
aa4d86163e4e91 Christoph Hellwig 2015-04-07  271  				zero_fill_bio(bio);
aa4d86163e4e91 Christoph Hellwig 2015-04-07  272  			break;
aa4d86163e4e91 Christoph Hellwig 2015-04-07  273  		}
aa4d86163e4e91 Christoph Hellwig 2015-04-07  274  		cond_resched();
^1da177e4c3f41 Linus Torvalds    2005-04-16  275  	}
^1da177e4c3f41 Linus Torvalds    2005-04-16  276  
aa4d86163e4e91 Christoph Hellwig 2015-04-07  277  	return 0;
fd5821404e6823 Jens Axboe        2007-06-12  278  }
fd5821404e6823 Jens Axboe        2007-06-12  279
Christoph Hellwig March 10, 2025, 10:46 a.m. UTC | #2
On Sun, Mar 09, 2025 at 12:23:05AM +0800, Ming Lei wrote:
> lo_rw_aio() is only called for READ/WRITE operation, which can be
> figured out from request directly, so remove 'rw' parameter from
> lo_rw_aio(), meantime rename the local variable as 'dir' which matches
> the actual use more.
> 
> Meantime merge lo_read_simple() and lo_write_simple() into
> lo_rw_simple().

That's two entirely separate things, please split them into separate
patches.

static int lo_rw_simple(struct loop_device *lo, struct request *rq, loff_t pos)
>  {
>  	struct bio_vec bvec;
>  	struct req_iterator iter;
>  	struct iov_iter i;
>  	ssize_t len;
>  
> +	if (req_op(rq) == REQ_OP_WRITE) {
> +		int ret;
> +
> +		rq_for_each_segment(bvec, rq, iter) {
> +			ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
> +			if (ret < 0)
> +				break;
> +			cond_resched();
> +		}
> +		return ret;
> +	}
> +
>  	rq_for_each_segment(bvec, rq, iter) {

.. and nothing is really merged here.  So unless you actually merge
some code later this part doesn't seem particularly useful.

>  	struct request *rq = blk_mq_rq_from_pdu(cmd);
> +	int dir = (req_op(rq) == REQ_OP_READ) ? ITER_DEST : ITER_SOURCE;
>  	struct bio *bio = rq->bio;
>  	struct file *file = lo->lo_backing_file;
>  	struct bio_vec tmp;
> @@ -448,7 +442,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
>  	}
>  	atomic_set(&cmd->ref, 2);
>  
> -	iov_iter_bvec(&iter, rw, bvec, nr_bvec, blk_rq_bytes(rq));
> +	iov_iter_bvec(&iter, dir, bvec, nr_bvec, blk_rq_bytes(rq));
>  	iter.iov_offset = offset;
>  
>  	cmd->iocb.ki_pos = pos;
> @@ -457,7 +451,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
>  	cmd->iocb.ki_flags = IOCB_DIRECT;
>  	cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
>  
> -	if (rw == ITER_SOURCE)
> +	if (dir == ITER_SOURCE)


i'd just use the request direction check here, and then open code
the iter source/dest in the iov_iter_bvec call.

>  	case REQ_OP_READ:
>  		if (cmd->use_aio)
> -			return lo_rw_aio(lo, cmd, pos, ITER_DEST);
> +			return lo_rw_aio(lo, cmd, pos);
>  		else
> -			return lo_read_simple(lo, rq, pos);
> +			return lo_rw_simple(lo, rq, pos);

Not entirely new here, but there is no reason to use an else after a
return.
diff mbox series

Patch

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 657bf53decf3..6bbbaa4aaf2c 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -239,31 +239,25 @@  static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
 	return bw;
 }
 
-static int lo_write_simple(struct loop_device *lo, struct request *rq,
-		loff_t pos)
-{
-	struct bio_vec bvec;
-	struct req_iterator iter;
-	int ret = 0;
-
-	rq_for_each_segment(bvec, rq, iter) {
-		ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
-		if (ret < 0)
-			break;
-		cond_resched();
-	}
-
-	return ret;
-}
-
-static int lo_read_simple(struct loop_device *lo, struct request *rq,
-		loff_t pos)
+static int lo_rw_simple(struct loop_device *lo, struct request *rq, loff_t pos)
 {
 	struct bio_vec bvec;
 	struct req_iterator iter;
 	struct iov_iter i;
 	ssize_t len;
 
+	if (req_op(rq) == REQ_OP_WRITE) {
+		int ret;
+
+		rq_for_each_segment(bvec, rq, iter) {
+			ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
+			if (ret < 0)
+				break;
+			cond_resched();
+		}
+		return ret;
+	}
+
 	rq_for_each_segment(bvec, rq, iter) {
 		iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len);
 		len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);
@@ -400,13 +394,13 @@  static void lo_rw_aio_complete(struct kiocb *iocb, long ret)
 	lo_rw_aio_do_completion(cmd);
 }
 
-static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
-		     loff_t pos, int rw)
+static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, loff_t pos)
 {
 	struct iov_iter iter;
 	struct req_iterator rq_iter;
 	struct bio_vec *bvec;
 	struct request *rq = blk_mq_rq_from_pdu(cmd);
+	int dir = (req_op(rq) == REQ_OP_READ) ? ITER_DEST : ITER_SOURCE;
 	struct bio *bio = rq->bio;
 	struct file *file = lo->lo_backing_file;
 	struct bio_vec tmp;
@@ -448,7 +442,7 @@  static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
 	}
 	atomic_set(&cmd->ref, 2);
 
-	iov_iter_bvec(&iter, rw, bvec, nr_bvec, blk_rq_bytes(rq));
+	iov_iter_bvec(&iter, dir, bvec, nr_bvec, blk_rq_bytes(rq));
 	iter.iov_offset = offset;
 
 	cmd->iocb.ki_pos = pos;
@@ -457,7 +451,7 @@  static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
 	cmd->iocb.ki_flags = IOCB_DIRECT;
 	cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
 
-	if (rw == ITER_SOURCE)
+	if (dir == ITER_SOURCE)
 		ret = file->f_op->write_iter(&cmd->iocb, &iter);
 	else
 		ret = file->f_op->read_iter(&cmd->iocb, &iter);
@@ -498,15 +492,11 @@  static int do_req_filebacked(struct loop_device *lo, struct request *rq)
 	case REQ_OP_DISCARD:
 		return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE);
 	case REQ_OP_WRITE:
-		if (cmd->use_aio)
-			return lo_rw_aio(lo, cmd, pos, ITER_SOURCE);
-		else
-			return lo_write_simple(lo, rq, pos);
 	case REQ_OP_READ:
 		if (cmd->use_aio)
-			return lo_rw_aio(lo, cmd, pos, ITER_DEST);
+			return lo_rw_aio(lo, cmd, pos);
 		else
-			return lo_read_simple(lo, rq, pos);
+			return lo_rw_simple(lo, rq, pos);
 	default:
 		WARN_ON_ONCE(1);
 		return -EIO;