Skip to content

Commit 2263639

Browse files
axboebrauner
authored andcommitted
iov_iter: streamline iovec/bvec alignment iteration
Rewrite the alignment checking iterators for iovec and bvec to be easier to read, and also significantly more compact in terms of generated code. This saves 270 bytes of text on x86-64 for me (with clang-18) and 224 bytes on arm64 (with gcc-13). In profiles, also saves a bit of time as well for the same workload: 0.81% -0.18% [kernel.vmlinux] [k] iov_iter_aligned_bvec 0.48% -0.09% [kernel.vmlinux] [k] iov_iter_is_aligned which is a nice side benefit as well. Signed-off-by: Jens Axboe <axboe@kernel.dk> Link: https://lore.kernel.org/r/544b31f7-6d4b-42f5-a544-1420501f081f@kernel.dk Reviewed-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org> v2: do the other half of the iterators too, as suggested by Keith. This further saves some text.
1 parent 0000ff2 commit 2263639

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

lib/iov_iter.c

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -714,12 +714,11 @@ EXPORT_SYMBOL(iov_iter_discard);
714714
static bool iov_iter_aligned_iovec(const struct iov_iter *i, unsigned addr_mask,
715715
unsigned len_mask)
716716
{
717+
const struct iovec *iov = iter_iov(i);
717718
size_t size = i->count;
718719
size_t skip = i->iov_offset;
719-
unsigned k;
720720

721-
for (k = 0; k < i->nr_segs; k++, skip = 0) {
722-
const struct iovec *iov = iter_iov(i) + k;
721+
do {
723722
size_t len = iov->iov_len - skip;
724723

725724
if (len > size)
@@ -729,34 +728,36 @@ static bool iov_iter_aligned_iovec(const struct iov_iter *i, unsigned addr_mask,
729728
if ((unsigned long)(iov->iov_base + skip) & addr_mask)
730729
return false;
731730

731+
iov++;
732732
size -= len;
733-
if (!size)
734-
break;
735-
}
733+
skip = 0;
734+
} while (size);
735+
736736
return true;
737737
}
738738

739739
static bool iov_iter_aligned_bvec(const struct iov_iter *i, unsigned addr_mask,
740740
unsigned len_mask)
741741
{
742-
size_t size = i->count;
742+
const struct bio_vec *bvec = i->bvec;
743743
unsigned skip = i->iov_offset;
744-
unsigned k;
744+
size_t size = i->count;
745745

746-
for (k = 0; k < i->nr_segs; k++, skip = 0) {
747-
size_t len = i->bvec[k].bv_len - skip;
746+
do {
747+
size_t len = bvec->bv_len;
748748

749749
if (len > size)
750750
len = size;
751751
if (len & len_mask)
752752
return false;
753-
if ((unsigned long)(i->bvec[k].bv_offset + skip) & addr_mask)
753+
if ((unsigned long)(bvec->bv_offset + skip) & addr_mask)
754754
return false;
755755

756+
bvec++;
756757
size -= len;
757-
if (!size)
758-
break;
759-
}
758+
skip = 0;
759+
} while (size);
760+
760761
return true;
761762
}
762763

@@ -800,44 +801,44 @@ EXPORT_SYMBOL_GPL(iov_iter_is_aligned);
800801

801802
static unsigned long iov_iter_alignment_iovec(const struct iov_iter *i)
802803
{
804+
const struct iovec *iov = iter_iov(i);
803805
unsigned long res = 0;
804806
size_t size = i->count;
805807
size_t skip = i->iov_offset;
806-
unsigned k;
807808

808-
for (k = 0; k < i->nr_segs; k++, skip = 0) {
809-
const struct iovec *iov = iter_iov(i) + k;
809+
do {
810810
size_t len = iov->iov_len - skip;
811811
if (len) {
812812
res |= (unsigned long)iov->iov_base + skip;
813813
if (len > size)
814814
len = size;
815815
res |= len;
816816
size -= len;
817-
if (!size)
818-
break;
819817
}
820-
}
818+
iov++;
819+
skip = 0;
820+
} while (size);
821821
return res;
822822
}
823823

824824
static unsigned long iov_iter_alignment_bvec(const struct iov_iter *i)
825825
{
826+
const struct bio_vec *bvec = i->bvec;
826827
unsigned res = 0;
827828
size_t size = i->count;
828829
unsigned skip = i->iov_offset;
829-
unsigned k;
830830

831-
for (k = 0; k < i->nr_segs; k++, skip = 0) {
832-
size_t len = i->bvec[k].bv_len - skip;
833-
res |= (unsigned long)i->bvec[k].bv_offset + skip;
831+
do {
832+
size_t len = bvec->bv_len - skip;
833+
res |= (unsigned long)bvec->bv_offset + skip;
834834
if (len > size)
835835
len = size;
836836
res |= len;
837+
bvec++;
837838
size -= len;
838-
if (!size)
839-
break;
840-
}
839+
skip = 0;
840+
} while (size);
841+
841842
return res;
842843
}
843844

0 commit comments

Comments
 (0)