forked from mirrors/linux
		
	iov_iter: use bvec iterator to implement iterate_bvec()
bvec has one native/mature iterator for long time, so not necessary to use the reinvented wheel for iterating bvecs in lib/iov_iter.c. Two ITER_BVEC test cases are run: - xfstest(-g auto) on loop dio/aio, no regression found - swap file works well under extreme stress(stress-ng --all 64 -t 800 -v), and lots of OOMs are triggerd, and the whole system still survives Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@canonical.com> Tested-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
		
							parent
							
								
									80f162ff06
								
							
						
					
					
						commit
						1bdc76aea1
					
				
					 1 changed files with 15 additions and 30 deletions
				
			
		|  | @ -56,37 +56,24 @@ | |||
| 	n = wanted;					\ | ||||
| } | ||||
| 
 | ||||
| #define iterate_bvec(i, n, __v, __p, skip, STEP) {	\ | ||||
| 	size_t wanted = n;				\ | ||||
| 	__p = i->bvec;					\ | ||||
| 	__v.bv_len = min_t(size_t, n, __p->bv_len - skip);	\ | ||||
| 	if (likely(__v.bv_len)) {			\ | ||||
| 		__v.bv_page = __p->bv_page;		\ | ||||
| 		__v.bv_offset = __p->bv_offset + skip; 	\ | ||||
| 		(void)(STEP);				\ | ||||
| 		skip += __v.bv_len;			\ | ||||
| 		n -= __v.bv_len;			\ | ||||
| 	}						\ | ||||
| 	while (unlikely(n)) {				\ | ||||
| 		__p++;					\ | ||||
| 		__v.bv_len = min_t(size_t, n, __p->bv_len);	\ | ||||
| 		if (unlikely(!__v.bv_len))		\ | ||||
| #define iterate_bvec(i, n, __v, __bi, skip, STEP) {	\ | ||||
| 	struct bvec_iter __start;			\ | ||||
| 	__start.bi_size = n;				\ | ||||
| 	__start.bi_bvec_done = skip;			\ | ||||
| 	__start.bi_idx = 0;				\ | ||||
| 	for_each_bvec(__v, i->bvec, __bi, __start) {	\ | ||||
| 		if (!__v.bv_len)			\ | ||||
| 			continue;			\ | ||||
| 		__v.bv_page = __p->bv_page;		\ | ||||
| 		__v.bv_offset = __p->bv_offset;		\ | ||||
| 		(void)(STEP);				\ | ||||
| 		skip = __v.bv_len;			\ | ||||
| 		n -= __v.bv_len;			\ | ||||
| 	}						\ | ||||
| 	n = wanted;					\ | ||||
| } | ||||
| 
 | ||||
| #define iterate_all_kinds(i, n, v, I, B, K) {			\ | ||||
| 	size_t skip = i->iov_offset;				\ | ||||
| 	if (unlikely(i->type & ITER_BVEC)) {			\ | ||||
| 		const struct bio_vec *bvec;			\ | ||||
| 		struct bio_vec v;				\ | ||||
| 		iterate_bvec(i, n, v, bvec, skip, (B))		\ | ||||
| 		struct bvec_iter __bi;				\ | ||||
| 		iterate_bvec(i, n, v, __bi, skip, (B))		\ | ||||
| 	} else if (unlikely(i->type & ITER_KVEC)) {		\ | ||||
| 		const struct kvec *kvec;			\ | ||||
| 		struct kvec v;					\ | ||||
|  | @ -104,15 +91,13 @@ | |||
| 	if (i->count) {						\ | ||||
| 		size_t skip = i->iov_offset;			\ | ||||
| 		if (unlikely(i->type & ITER_BVEC)) {		\ | ||||
| 			const struct bio_vec *bvec;		\ | ||||
| 			const struct bio_vec *bvec = i->bvec;	\ | ||||
| 			struct bio_vec v;			\ | ||||
| 			iterate_bvec(i, n, v, bvec, skip, (B))	\ | ||||
| 			if (skip == bvec->bv_len) {		\ | ||||
| 				bvec++;				\ | ||||
| 				skip = 0;			\ | ||||
| 			}					\ | ||||
| 			i->nr_segs -= bvec - i->bvec;		\ | ||||
| 			i->bvec = bvec;				\ | ||||
| 			struct bvec_iter __bi;			\ | ||||
| 			iterate_bvec(i, n, v, __bi, skip, (B))	\ | ||||
| 			i->bvec = __bvec_iter_bvec(i->bvec, __bi);	\ | ||||
| 			i->nr_segs -= i->bvec - bvec;		\ | ||||
| 			skip = __bi.bi_bvec_done;		\ | ||||
| 		} else if (unlikely(i->type & ITER_KVEC)) {	\ | ||||
| 			const struct kvec *kvec;		\ | ||||
| 			struct kvec v;				\ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Ming Lei
						Ming Lei