• Vlastimil Babka's avatar
    mm/slab: Convert most struct page to struct slab by spatch · 7981e67e
    Vlastimil Babka authored
    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: default avatarVlastimil Babka <vbabka@suse.cz>
    Reviewed-by: default avatarRoman Gushchin <guro@fb.com>
    Tested-by: default avatarHyeonggon Yoo <42.hyeyoo@gmail.com>
    Cc: Julia Lawall <julia.lawall@inria.fr>
    Cc: Luis Chamberlain <mcgrof@kernel.org>
    7981e67e
slab.c 106 KB