Messages in this thread | | | Date | Mon, 8 Jun 2020 13:34:25 +0200 (CEST) | From | Julia Lawall <> | Subject | Re: [PATCH] kernel: power: swap: mark a function as __init to save some memory |
| |
On Mon, 8 Jun 2020, Dan Carpenter wrote:
> On Sun, May 31, 2020 at 03:11:27PM -0700, Joe Perches wrote: > > (adding Dan Carpenter) > > > > On Sun, 2020-05-31 at 23:00 +0200, Christophe JAILLET wrote: > > > 'swsusp_header_init()' is only called via 'core_initcall'. > > > It can be marked as __init to save a few bytes of memory. > > > > Hey Dan > > > > smatch has a full function calling tree right? > > > > Can smatch find unmarked functions called only by __init > > functions so those unmarked functions can be appropriately > > marked with __init like the below? > > > > It turns out it's complicated to do this in Smatch because Sparse > ignores the section attribute. :/
I wrote a script at one point for this for Coccinelle, and sent some patches. It requires some effort, because you want to run it over and over - once function Y becomes init, some other functions might become init as well. The iteration could be done automatically with Coccinelle, but I didn't take that option, because it semed safer to check the results along the way. A version of the script is attached.
julia// No iteration. Do it by hand.
@initialize:ocaml@ @@
let itbl = Hashtbl.create 101 let ltbl = Hashtbl.create 101 let thefile = ref ""
let hashadd t k = let cell = try Hashtbl.find t k with Not_found -> let cell = ref 0 in Hashtbl.add t k cell; cell in cell := !cell + 1
let hashget t k = try !(Hashtbl.find t k) with Not_found -> 0
let seen = ref []
@script:ocaml@ @@
(let file = List.hd (Coccilib.files()) in thefile := file; let file = try List.hd(List.tl (Str.split (Str.regexp "/linux-next/") file)) with _ -> file in let ofile = "/var/julia/linux-next/" ^ (Filename.chop_extension file) ^ ".o" in if not(Sys.file_exists ofile) then Coccilib.exit());
Hashtbl.clear itbl; Hashtbl.clear ltbl; seen := []
@r@ identifier f; @@
__init f(...) { ... }
@script:ocaml@ f << r.f; @@
Hashtbl.add itbl f ()
@s disable optional_attributes@ identifier f; @@
static f(...) { ... }
@script:ocaml@ f << s.f; @@
Hashtbl.add ltbl f ()
@t exists@ identifier f,g; position p; @@
__init f(...) { ... when any g@p(...) ... when any }
@script:ocaml@ g << t.g; _p << t.p; @@
if not (Hashtbl.mem ltbl g) || Hashtbl.mem itbl g then Coccilib.include_match false
@ok1 disable optional_attributes exists@ identifier f,t.g; @@
f(...) { ... when any g ... when any }
@ok2 disable optional_attributes exists@ identifier i,j,fld,t.g; @@
struct i j = { .fld = g, };
@ok3 disable optional_attributes exists@ identifier t.g; declarer d; @@
d(...,g,...);
@ok4 disable optional_attributes exists@ identifier t.g; expression e; @@
( e(...,g,...) | e(...,&g,...) | e = &g | e = g )
@script:ocaml depends on !ok1 && !ok2 && !ok3 && !ok4@ g << t.g; @@
let file = !thefile in let file = try List.hd(List.tl (Str.split (Str.regexp "/linux-next/") file)) with _ -> file in if not(List.mem (g,file) !seen) then begin seen := (g,file) :: !seen; let ofile = "/var/julia/linux-next/" ^ (Filename.chop_extension file) ^ ".o" in if Sys.file_exists ofile then let l = Common.cmd_to_list (Printf.sprintf "objdump -x %s | grep -w %s | grep -w F | grep .text.unlikely" ofile g) in match l with [] -> Coccilib.include_match false | _ -> Printf.printf "Info for %s %s\n" file g; List.iter (function l -> Printf.printf "%s\n" l) l; Printf.printf "\n"; flush stdout else Coccilib.include_match false end else Coccilib.include_match false
@depends on !ok1 && !ok2 && !ok3 && !ok4@ identifier t.g; @@
- g +__init g (...) { ... }
| |