aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2021-11-27 00:05:50 +0100
committerIngo Molnar <mingo@kernel.org>2022-03-15 12:57:33 +0100
commit1512a98e77bfdbc3864cba6e1a4603f13beba3bd (patch)
treec16c042535972aef5d584effd58673759b1c7082
parent2507f4736e74dbced5c46c38ee547fcb1f0218a8 (diff)
downloadtip-1512a98e77bfdbc3864cba6e1a4603f13beba3bd.tar.gz
headers/deps: kernel: Split <linux/bvec.h> into <linux/bvec_types.h> and <linux/bvec_api.h>
<linux/bvec.h> is a large header (10 KLOC), included in over 9,000 other headers: _______________________ | stripped lines of code | _____________________________ | | headers included recursively | | _______________________________ | | | usage in a distro kernel build ____________ | | | _________________________________________ | header name | | | | million lines of comment-stripped C code | | | | | #include <linux/bvec.h> | LOC: 13,501 | headers: 327 | 9,033 | MLOC: 121.9 In order to reduce this impact, we are splitting it into three parts: - <linux/bvec_types.h>: lightweight header with only type definitions and initializers. - <linux/bvec_api.h>: API declarations and inline functions. This header is inevitably more heavyweight. - <linux/bvec.h>: Simple default header that right now includes both the types and the API headers, but will only use the types header once all affected code is converted. No change in functionality in this first step. Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/linux/bvec.h200
-rw-r--r--include/linux/bvec_api.h62
-rw-r--r--include/linux/bvec_types.h161
3 files changed, 224 insertions, 199 deletions
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index 463854341da3ca..6d15a505fd26f0 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -7,203 +7,7 @@
#ifndef __LINUX_BVEC_H
#define __LINUX_BVEC_H
-#include <linux/highmem.h>
-#include <linux/bug.h>
-
-struct page;
-
-/**
- * struct bio_vec - a contiguous range of physical memory addresses
- * @bv_page: First page associated with the address range.
- * @bv_len: Number of bytes in the address range.
- * @bv_offset: Start of the address range relative to the start of @bv_page.
- *
- * The following holds for a bvec if n * PAGE_SIZE < bv_offset + bv_len:
- *
- * nth_page(@bv_page, n) == @bv_page + n
- *
- * This holds because page_is_mergeable() checks the above property.
- */
-struct bio_vec {
- struct page *bv_page;
- unsigned int bv_len;
- unsigned int bv_offset;
-};
-
-struct bvec_iter {
- sector_t bi_sector; /* device address in 512 byte
- sectors */
- unsigned int bi_size; /* residual I/O count */
-
- unsigned int bi_idx; /* current index into bvl_vec */
-
- unsigned int bi_bvec_done; /* number of bytes completed in
- current bvec */
-} __packed;
-
-struct bvec_iter_all {
- struct bio_vec bv;
- int idx;
- unsigned done;
-};
-
-/*
- * various member access, note that bio_data should of course not be used
- * on highmem page vectors
- */
-#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
-
-/* multi-page (mp_bvec) helpers */
-#define mp_bvec_iter_page(bvec, iter) \
- (__bvec_iter_bvec((bvec), (iter))->bv_page)
-
-#define mp_bvec_iter_len(bvec, iter) \
- min((iter).bi_size, \
- __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
-
-#define mp_bvec_iter_offset(bvec, iter) \
- (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
-
-#define mp_bvec_iter_page_idx(bvec, iter) \
- (mp_bvec_iter_offset((bvec), (iter)) / PAGE_SIZE)
-
-#define mp_bvec_iter_bvec(bvec, iter) \
-((struct bio_vec) { \
- .bv_page = mp_bvec_iter_page((bvec), (iter)), \
- .bv_len = mp_bvec_iter_len((bvec), (iter)), \
- .bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
-})
-
-/* For building single-page bvec in flight */
- #define bvec_iter_offset(bvec, iter) \
- (mp_bvec_iter_offset((bvec), (iter)) % PAGE_SIZE)
-
-#define bvec_iter_len(bvec, iter) \
- min_t(unsigned, mp_bvec_iter_len((bvec), (iter)), \
- PAGE_SIZE - bvec_iter_offset((bvec), (iter)))
-
-#define bvec_iter_page(bvec, iter) \
- (mp_bvec_iter_page((bvec), (iter)) + \
- mp_bvec_iter_page_idx((bvec), (iter)))
-
-#define bvec_iter_bvec(bvec, iter) \
-((struct bio_vec) { \
- .bv_page = bvec_iter_page((bvec), (iter)), \
- .bv_len = bvec_iter_len((bvec), (iter)), \
- .bv_offset = bvec_iter_offset((bvec), (iter)), \
-})
-
-static inline bool bvec_iter_advance(const struct bio_vec *bv,
- struct bvec_iter *iter, unsigned bytes)
-{
- unsigned int idx = iter->bi_idx;
-
- if (WARN_ONCE(bytes > iter->bi_size,
- "Attempted to advance past end of bvec iter\n")) {
- iter->bi_size = 0;
- return false;
- }
-
- iter->bi_size -= bytes;
- bytes += iter->bi_bvec_done;
-
- while (bytes && bytes >= bv[idx].bv_len) {
- bytes -= bv[idx].bv_len;
- idx++;
- }
-
- iter->bi_idx = idx;
- iter->bi_bvec_done = bytes;
- return true;
-}
-
-/*
- * A simpler version of bvec_iter_advance(), @bytes should not span
- * across multiple bvec entries, i.e. bytes <= bv[i->bi_idx].bv_len
- */
-static inline void bvec_iter_advance_single(const struct bio_vec *bv,
- struct bvec_iter *iter, unsigned int bytes)
-{
- unsigned int done = iter->bi_bvec_done + bytes;
-
- if (done == bv[iter->bi_idx].bv_len) {
- done = 0;
- iter->bi_idx++;
- }
- iter->bi_bvec_done = done;
- iter->bi_size -= bytes;
-}
-
-#define for_each_bvec(bvl, bio_vec, iter, start) \
- for (iter = (start); \
- (iter).bi_size && \
- ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
- bvec_iter_advance_single((bio_vec), &(iter), (bvl).bv_len))
-
-/* for iterating one bio from start to end */
-#define BVEC_ITER_ALL_INIT (struct bvec_iter) \
-{ \
- .bi_sector = 0, \
- .bi_size = UINT_MAX, \
- .bi_idx = 0, \
- .bi_bvec_done = 0, \
-}
-
-static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
-{
- iter_all->done = 0;
- iter_all->idx = 0;
-
- return &iter_all->bv;
-}
-
-extern void bvec_advance(const struct bio_vec *bvec, struct bvec_iter_all *iter_all);
-
-/**
- * bvec_kmap_local - map a bvec into the kernel virtual address space
- * @bvec: bvec to map
- *
- * Must be called on single-page bvecs only. Call kunmap_local on the returned
- * address to unmap.
- */
-static inline void *bvec_kmap_local(struct bio_vec *bvec)
-{
- return kmap_local_page(bvec->bv_page) + bvec->bv_offset;
-}
-
-/**
- * memcpy_from_bvec - copy data from a bvec
- * @bvec: bvec to copy from
- *
- * Must be called on single-page bvecs only.
- */
-static inline void memcpy_from_bvec(char *to, struct bio_vec *bvec)
-{
- memcpy_from_page(to, bvec->bv_page, bvec->bv_offset, bvec->bv_len);
-}
-
-/**
- * memcpy_to_bvec - copy data to a bvec
- * @bvec: bvec to copy to
- *
- * Must be called on single-page bvecs only.
- */
-static inline void memcpy_to_bvec(struct bio_vec *bvec, const char *from)
-{
- memcpy_to_page(bvec->bv_page, bvec->bv_offset, from, bvec->bv_len);
-}
-
-/**
- * memzero_bvec - zero all data in a bvec
- * @bvec: bvec to zero
- *
- * Must be called on single-page bvecs only.
- */
-static inline void memzero_bvec(struct bio_vec *bvec)
-{
- memzero_page(bvec->bv_page, bvec->bv_offset, bvec->bv_len);
-}
-
-extern void *bvec_virt(struct bio_vec *bvec);
+#include <linux/bvec_types.h>
+#include <linux/bvec_api.h>
#endif /* __LINUX_BVEC_H */
diff --git a/include/linux/bvec_api.h b/include/linux/bvec_api.h
index deedf96829d613..91bc70df0fd354 100644
--- a/include/linux/bvec_api.h
+++ b/include/linux/bvec_api.h
@@ -1 +1,61 @@
-#include <linux/bvec.h>
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * bvec iterator
+ *
+ * Copyright (C) 2001 Ming Lei <ming.lei@canonical.com>
+ */
+#ifndef __LINUX_BVEC_API_H
+#define __LINUX_BVEC_API_H
+
+#include <linux/bvec_types.h>
+
+#include <linux/highmem.h>
+
+/**
+ * bvec_kmap_local - map a bvec into the kernel virtual address space
+ * @bvec: bvec to map
+ *
+ * Must be called on single-page bvecs only. Call kunmap_local on the returned
+ * address to unmap.
+ */
+static inline void *bvec_kmap_local(struct bio_vec *bvec)
+{
+ return kmap_local_page(bvec->bv_page) + bvec->bv_offset;
+}
+
+/**
+ * memcpy_from_bvec - copy data from a bvec
+ * @bvec: bvec to copy from
+ *
+ * Must be called on single-page bvecs only.
+ */
+static inline void memcpy_from_bvec(char *to, struct bio_vec *bvec)
+{
+ memcpy_from_page(to, bvec->bv_page, bvec->bv_offset, bvec->bv_len);
+}
+
+/**
+ * memcpy_to_bvec - copy data to a bvec
+ * @bvec: bvec to copy to
+ *
+ * Must be called on single-page bvecs only.
+ */
+static inline void memcpy_to_bvec(struct bio_vec *bvec, const char *from)
+{
+ memcpy_to_page(bvec->bv_page, bvec->bv_offset, from, bvec->bv_len);
+}
+
+/**
+ * memzero_bvec - zero all data in a bvec
+ * @bvec: bvec to zero
+ *
+ * Must be called on single-page bvecs only.
+ */
+static inline void memzero_bvec(struct bio_vec *bvec)
+{
+ memzero_page(bvec->bv_page, bvec->bv_offset, bvec->bv_len);
+}
+
+extern void *bvec_virt(struct bio_vec *bvec);
+
+#endif /* __LINUX_BVEC_API_H */
diff --git a/include/linux/bvec_types.h b/include/linux/bvec_types.h
new file mode 100644
index 00000000000000..5270734676deaa
--- /dev/null
+++ b/include/linux/bvec_types.h
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * bvec iterator
+ *
+ * Copyright (C) 2001 Ming Lei <ming.lei@canonical.com>
+ */
+#ifndef __LINUX_BVEC_TYPES_H
+#define __LINUX_BVEC_TYPES_H
+
+#include <linux/bug.h>
+
+struct page;
+
+/**
+ * struct bio_vec - a contiguous range of physical memory addresses
+ * @bv_page: First page associated with the address range.
+ * @bv_len: Number of bytes in the address range.
+ * @bv_offset: Start of the address range relative to the start of @bv_page.
+ *
+ * The following holds for a bvec if n * PAGE_SIZE < bv_offset + bv_len:
+ *
+ * nth_page(@bv_page, n) == @bv_page + n
+ *
+ * This holds because page_is_mergeable() checks the above property.
+ */
+struct bio_vec {
+ struct page *bv_page;
+ unsigned int bv_len;
+ unsigned int bv_offset;
+};
+
+struct bvec_iter {
+ sector_t bi_sector; /* device address in 512 byte
+ sectors */
+ unsigned int bi_size; /* residual I/O count */
+
+ unsigned int bi_idx; /* current index into bvl_vec */
+
+ unsigned int bi_bvec_done; /* number of bytes completed in
+ current bvec */
+} __packed;
+
+struct bvec_iter_all {
+ struct bio_vec bv;
+ int idx;
+ unsigned done;
+};
+
+/*
+ * various member access, note that bio_data should of course not be used
+ * on highmem page vectors
+ */
+#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
+
+/* multi-page (mp_bvec) helpers */
+#define mp_bvec_iter_page(bvec, iter) \
+ (__bvec_iter_bvec((bvec), (iter))->bv_page)
+
+#define mp_bvec_iter_len(bvec, iter) \
+ min((iter).bi_size, \
+ __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
+
+#define mp_bvec_iter_offset(bvec, iter) \
+ (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
+
+#define mp_bvec_iter_page_idx(bvec, iter) \
+ (mp_bvec_iter_offset((bvec), (iter)) / PAGE_SIZE)
+
+#define mp_bvec_iter_bvec(bvec, iter) \
+((struct bio_vec) { \
+ .bv_page = mp_bvec_iter_page((bvec), (iter)), \
+ .bv_len = mp_bvec_iter_len((bvec), (iter)), \
+ .bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
+})
+
+/* For building single-page bvec in flight */
+ #define bvec_iter_offset(bvec, iter) \
+ (mp_bvec_iter_offset((bvec), (iter)) % PAGE_SIZE)
+
+#define bvec_iter_len(bvec, iter) \
+ min_t(unsigned, mp_bvec_iter_len((bvec), (iter)), \
+ PAGE_SIZE - bvec_iter_offset((bvec), (iter)))
+
+#define bvec_iter_page(bvec, iter) \
+ (mp_bvec_iter_page((bvec), (iter)) + \
+ mp_bvec_iter_page_idx((bvec), (iter)))
+
+#define bvec_iter_bvec(bvec, iter) \
+((struct bio_vec) { \
+ .bv_page = bvec_iter_page((bvec), (iter)), \
+ .bv_len = bvec_iter_len((bvec), (iter)), \
+ .bv_offset = bvec_iter_offset((bvec), (iter)), \
+})
+
+static inline bool bvec_iter_advance(const struct bio_vec *bv,
+ struct bvec_iter *iter, unsigned bytes)
+{
+ unsigned int idx = iter->bi_idx;
+
+ if (WARN_ONCE(bytes > iter->bi_size,
+ "Attempted to advance past end of bvec iter\n")) {
+ iter->bi_size = 0;
+ return false;
+ }
+
+ iter->bi_size -= bytes;
+ bytes += iter->bi_bvec_done;
+
+ while (bytes && bytes >= bv[idx].bv_len) {
+ bytes -= bv[idx].bv_len;
+ idx++;
+ }
+
+ iter->bi_idx = idx;
+ iter->bi_bvec_done = bytes;
+ return true;
+}
+
+/*
+ * A simpler version of bvec_iter_advance(), @bytes should not span
+ * across multiple bvec entries, i.e. bytes <= bv[i->bi_idx].bv_len
+ */
+static inline void bvec_iter_advance_single(const struct bio_vec *bv,
+ struct bvec_iter *iter, unsigned int bytes)
+{
+ unsigned int done = iter->bi_bvec_done + bytes;
+
+ if (done == bv[iter->bi_idx].bv_len) {
+ done = 0;
+ iter->bi_idx++;
+ }
+ iter->bi_bvec_done = done;
+ iter->bi_size -= bytes;
+}
+
+#define for_each_bvec(bvl, bio_vec, iter, start) \
+ for (iter = (start); \
+ (iter).bi_size && \
+ ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
+ bvec_iter_advance_single((bio_vec), &(iter), (bvl).bv_len))
+
+/* for iterating one bio from start to end */
+#define BVEC_ITER_ALL_INIT (struct bvec_iter) \
+{ \
+ .bi_sector = 0, \
+ .bi_size = UINT_MAX, \
+ .bi_idx = 0, \
+ .bi_bvec_done = 0, \
+}
+
+static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all)
+{
+ iter_all->done = 0;
+ iter_all->idx = 0;
+
+ return &iter_all->bv;
+}
+
+extern void bvec_advance(const struct bio_vec *bvec, struct bvec_iter_all *iter_all);
+
+#endif /* __LINUX_BVEC_TYPES_H */