On Tue, Jan 04, 2022 at 01:10:34AM +0100, Vlastimil Babka wrote: > The majority of conversion from struct page to struct slab in SLAB > internals can be delegated to a coccinelle semantic patch. This includes > renaming of variables with 'page' in name to 'slab', and similar. > > Big thanks to Julia Lawall and Luis Chamberlain for help with > coccinelle. > > // Options: --include-headers --no-includes --smpl-spacing mm/slab.c > // Note: needs coccinelle 1.1.1 to avoid breaking whitespace, and ocaml for the > // embedded script > > // build list of functions for applying the next rule > @initialize:ocaml@ > @@ > > let ok_function p = > not (List.mem (List.hd p).current_element ["kmem_getpages";"kmem_freepages"]) > > // convert the type in selected functions > @@ > position p : script:ocaml() { ok_function p }; > @@ > > - struct page@p > + struct slab > > @@ > @@ > > -PageSlabPfmemalloc(page) > +slab_test_pfmemalloc(slab) > > @@ > @@ > > -ClearPageSlabPfmemalloc(page) > +slab_clear_pfmemalloc(slab) > > @@ > @@ > > obj_to_index( > ..., > - page > + slab_page(slab) > ,...) > > // for all functions, change any "struct slab *page" parameter to "struct slab > // *slab" in the signature, and generally all occurences of "page" to "slab" in > // the body - with some special cases. > @@ > identifier fn; > expression E; > @@ > > fn(..., > - struct slab *page > + struct slab *slab > ,...) > { > <... > ( > - int page_node; > + int slab_node; > | > - page_node > + slab_node > | > - page_slab(page) > + slab > | > - page_address(page) > + slab_address(slab) > | > - page_size(page) > + slab_size(slab) > | > - page_to_nid(page) > + slab_nid(slab) > | > - virt_to_head_page(E) > + virt_to_slab(E) > | > - page > + slab > ) > ...> > } > > // rename a function parameter > @@ > identifier fn; > expression E; > @@ > > fn(..., > - int page_node > + int slab_node > ,...) > { > <... > - page_node > + slab_node > ...> > } > > // functions converted by previous rules that were temporarily called using > // slab_page(E) so we want to remove the wrapper now that they accept struct > // slab ptr directly > @@ > identifier fn =~ "index_to_obj"; > expression E; > @@ > > fn(..., > - slab_page(E) > + E > ,...) > > // functions that were returning struct page ptr and now will return struct > // slab ptr, including slab_page() wrapper removal > @@ > identifier fn =~ "cache_grow_begin|get_valid_first_slab|get_first_slab"; > expression E; > @@ > > fn(...) > { > <... > - slab_page(E) > + E > ...> > } > > // rename any former struct page * declarations > @@ > @@ > > struct slab * > -page > +slab > ; > > // all functions (with exceptions) with a local "struct slab *page" variable > // that will be renamed to "struct slab *slab" > @@ > identifier fn !~ "kmem_getpages|kmem_freepages"; > expression E; > @@ > > fn(...) > { > <... > ( > - page_slab(page) > + slab > | > - page_to_nid(page) > + slab_nid(slab) > | > - kasan_poison_slab(page) > + kasan_poison_slab(slab_page(slab)) > | > - page_address(page) > + slab_address(slab) > | > - page_size(page) > + slab_size(slab) > | > - page->pages > + slab->slabs > | > - page = virt_to_head_page(E) > + slab = virt_to_slab(E) > | > - virt_to_head_page(E) > + virt_to_slab(E) > | > - page > + slab > ) > ...> > } > > Signed-off-by: Vlastimil Babka <vbabka@xxxxxxx> > Tested-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> > Cc: Julia Lawall <julia.lawall@xxxxxxxx> > Cc: Luis Chamberlain <mcgrof@xxxxxxxxxx> Looks good to me! Reviewed-by: Roman Gushchin <guro@xxxxxx>