On Sat, Jul 27, 2024 at 09:38:54AM GMT, Jens Axboe wrote: > On 7/27/24 9:30 AM, Jens Axboe wrote: > > On 7/26/24 4:48 PM, Linus Torvalds wrote: > >> I didn't even look at what the issue was with the > >> bio_for_each_segment() expansion, in the hope that Jens will make that > >> one look better. > > > > I did take a quick look, pretty obviously bvec_iter_bvec() which makes > > it horrible, which came from Kent's immutable work quite a while ago. > > Not sure yet what to do about it, will spend some time on this next > > week. > > Maybe something like this, totally untested... > > diff --git a/include/linux/bvec.h b/include/linux/bvec.h > index f41c7f0ef91e..9ccccddadde2 100644 > --- a/include/linux/bvec.h > +++ b/include/linux/bvec.h > @@ -130,12 +130,15 @@ struct bvec_iter_all { > (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 struct bio_vec bvec_iter_bvec(struct bio_vec *bv, > + struct bvec_iter iter) > +{ > + return (struct bio_vec) { > + .bv_page = bvec_iter_page(bv, iter), > + .bv_len = bvec_iter_len(bv, iter), > + .bv_offset = bvec_iter_offset(bv, iter) > + }; > +} > > static inline bool bvec_iter_advance(const struct bio_vec *bv, > struct bvec_iter *iter, unsigned bytes) > > -- > Jens Axboe > I tried this patch, doesn't seem to make a huge difference, going from 3,958,564 bytes with longest line of 82 kB to 3,943,824 bytes with a longest line of 77kB. It seems that the .bv_len = ... expansion is what's doing it, so I tried patching mp_bvec_iter_len() as well to do a silly ?: thing (sorry), which takes us down to 3,880,309 with longest line of 20kB. This is starting to feel like whack-a-mole isn't it? I looked at the next longest line, which originates from include/linux/pid_namespace.h believe it or not where some compiler cleverness + a loop is resulting in _another_ combinatorial explosion. Whacking that gets us down to 3,860,780 with longest line of 16kB and (credit to Willy for telling me about the make <file basename>.i thing): awk '{print length}' mm/compaction.i | sort -n Tells me we have... 18 lines >10k remaining in that file. Obviously dropping from 82 kB to 16 kB max size is handy but I think all this points to the need for a fundamental fix for this (I vote for fundamental simplification of core min()/max() macros, keep something complicated around for true const cases, e.g. MIN()/MAX()). Patch attached including Jens's change + mine. ----8<----