summaryrefslogtreecommitdiffstats
path: root/lib/iov_iter.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2016-05-30 09:34:32 -0400
committerJens Axboe <axboe@fb.com>2016-06-09 12:02:47 -0400
commit1bdc76aea1159a750846c2fc98e404403eb7d51c (patch)
treeeb61e4844ee2862fc43d396645224da2fa6fd177 /lib/iov_iter.c
parent80f162ff061c9e280589bb1a1890c7fc21c932cd (diff)
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>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r--lib/iov_iter.c45
1 files changed, 15 insertions, 30 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 0cd522753ff5..d67c8288d95d 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -56,37 +56,24 @@
56 n = wanted; \ 56 n = wanted; \
57} 57}
58 58
59#define iterate_bvec(i, n, __v, __p, skip, STEP) { \ 59#define iterate_bvec(i, n, __v, __bi, skip, STEP) { \
60 size_t wanted = n; \ 60 struct bvec_iter __start; \
61 __p = i->bvec; \ 61 __start.bi_size = n; \
62 __v.bv_len = min_t(size_t, n, __p->bv_len - skip); \ 62 __start.bi_bvec_done = skip; \
63 if (likely(__v.bv_len)) { \ 63 __start.bi_idx = 0; \
64 __v.bv_page = __p->bv_page; \ 64 for_each_bvec(__v, i->bvec, __bi, __start) { \
65 __v.bv_offset = __p->bv_offset + skip; \ 65 if (!__v.bv_len) \
66 (void)(STEP); \
67 skip += __v.bv_len; \
68 n -= __v.bv_len; \
69 } \
70 while (unlikely(n)) { \
71 __p++; \
72 __v.bv_len = min_t(size_t, n, __p->bv_len); \
73 if (unlikely(!__v.bv_len)) \
74 continue; \ 66 continue; \
75 __v.bv_page = __p->bv_page; \
76 __v.bv_offset = __p->bv_offset; \
77 (void)(STEP); \ 67 (void)(STEP); \
78 skip = __v.bv_len; \
79 n -= __v.bv_len; \
80 } \ 68 } \
81 n = wanted; \
82} 69}
83 70
84#define iterate_all_kinds(i, n, v, I, B, K) { \ 71#define iterate_all_kinds(i, n, v, I, B, K) { \
85 size_t skip = i->iov_offset; \ 72 size_t skip = i->iov_offset; \
86 if (unlikely(i->type & ITER_BVEC)) { \ 73 if (unlikely(i->type & ITER_BVEC)) { \
87 const struct bio_vec *bvec; \
88 struct bio_vec v; \ 74 struct bio_vec v; \
89 iterate_bvec(i, n, v, bvec, skip, (B)) \ 75 struct bvec_iter __bi; \
76 iterate_bvec(i, n, v, __bi, skip, (B)) \
90 } else if (unlikely(i->type & ITER_KVEC)) { \ 77 } else if (unlikely(i->type & ITER_KVEC)) { \
91 const struct kvec *kvec; \ 78 const struct kvec *kvec; \
92 struct kvec v; \ 79 struct kvec v; \
@@ -104,15 +91,13 @@
104 if (i->count) { \ 91 if (i->count) { \
105 size_t skip = i->iov_offset; \ 92 size_t skip = i->iov_offset; \
106 if (unlikely(i->type & ITER_BVEC)) { \ 93 if (unlikely(i->type & ITER_BVEC)) { \
107 const struct bio_vec *bvec; \ 94 const struct bio_vec *bvec = i->bvec; \
108 struct bio_vec v; \ 95 struct bio_vec v; \
109 iterate_bvec(i, n, v, bvec, skip, (B)) \ 96 struct bvec_iter __bi; \
110 if (skip == bvec->bv_len) { \ 97 iterate_bvec(i, n, v, __bi, skip, (B)) \
111 bvec++; \ 98 i->bvec = __bvec_iter_bvec(i->bvec, __bi); \
112 skip = 0; \ 99 i->nr_segs -= i->bvec - bvec; \
113 } \ 100 skip = __bi.bi_bvec_done; \
114 i->nr_segs -= bvec - i->bvec; \
115 i->bvec = bvec; \
116 } else if (unlikely(i->type & ITER_KVEC)) { \ 101 } else if (unlikely(i->type & ITER_KVEC)) { \
117 const struct kvec *kvec; \ 102 const struct kvec *kvec; \
118 struct kvec v; \ 103 struct kvec v; \