This is the best I've been able to come up with: /** * bio_for_each_folio_all - Iterate over each folio in a bio. * @fi: struct folio_iter which is updated for each folio. * @bio: struct bio to iterate over. */ #define bio_for_each_folio_all(fi, bio) \ for (bio_first_folio(&fi, bio, 0); fi.folio; bio_next_folio(&fi, bio)) which produces html which renders as: > bio_for_each_folio_all > > bio_for_each_folio_all (fi, bio) > > Iterate over each folio in a bio. > > Parameters > > fi > > struct folio_iter which is updated for each folio. > bio > > struct bio to iterate over. ... not too different from an actual function: > Parameters > > struct bio *bio > > bio to split > int sectors > > number of sectors to split from the front of bio but if anyone has a better suggestion, I'd love to hear it. I'll also update the doc-guide with the best practice for doing this. (obviously the best practice is just to use a function, but that doesn't work here. and some macros are deliberately untyped, eg offset_in_page) It'd be nice to improve the generated html here too to put the parameters in the name of the macro and not repeat the name of the macro with parameters on a second line. But right now, I'm more concerned with getting the kernel-doc comments right.