[Part I] Macros module init/exit, Boilerplate code and Linux Kernel

Hii

Lets talk about boiler plate code today. I worked on cases of boiler plate code in Linux kernel during last few days. I am going to divide this particular topic in 2 blog posts. In this post, I will talk about boiler plate code, cases of them and how can we find them in the kernel using Coccinelle. In the second post, I will talk about how Coccinelle can help to handle such cases.

Boiler plate code:

Boilerplate code is any seemingly repetitive code that shows up again and again in order to get some result that seems like it ought to be much simpler. Basically boilerplate code or boilerplate is the sections of code that have to be included in many places with little or no alteration.

Bolier plate code and init/exit macros:

In kernel macro module_init can either be called during do_initcalls (if builtin) or at module insertion time (if a module). Macro module_exit is used to wrap the driver clean-up code with cleanup_module when used with rmmod and the driver is a module. If the driver is statically compiled into the kernel, module_exit has no effect. There can only be one module_init and one module_exit per module. In 70% of cases drivers don’t do anything special in module init/exit. So, such bolier plate code can be eliminated using some helper macros like module_platform_driver, module_pci_driver, module_pcmcia_driver etc. Here, is an example of such code form kernel:


static int __init snirm710_init(void)
{
return platform_driver_register(&snirm710_driver);
}
static void __exit snirm710_exit(void)
{
platform_driver_unregister(&snirm710_driver);
}
module_init(snirm710_init);
module_exit(snirm710_exit);

[From file drivers/scsi/sni_53c710.c]

Basically these helper macros are defined for drivers whose init and exit paths does only register and unregister. Sometimes we have unnecessary print statements and code in module init/exit too. In such cases we can use these helper macros too. Currently there are some such general macros and driver specific helper macros presented in the kernel. And many more such opportunities are there.

Macros module init/exit and Coccinelle

Generally we can use following Coccinelle semantic patch to match the module init/exit associated functions and statements.

@r@
declarer name module_init;
identifier f;
@@
module_init(f);

@s@
declarer name module_exit;
identifier f;
@@
module_exit(f);

@a@
identifier r.f;
statement S;
@@
f(…) { S }

@depends on a@
identifier s.f;
statement S;
@@
f(…) {
*S
}

@b@
identifier s.f;
statement S;
@@
f(…) { S }

@depends on b@
identifier r.f;
statement S;
@@
f(…) {
*S
}

So, after getting output of this semantic patch I analyzed all cases. And grouped them together accordingly. I grouped them in with categories like old macro and new macro means cases where we can use already defined helper macro and where we need to define new macros respectively. I am thinking to put that file on my github along with some coccinelle scripts so that others can use it. I am going to handle most of them. I have sent some patches and will sent for all those cases where old macro can be used. For the new macro cases, I will send patches introducing some of those macros which can handle maximum cases and such cases are already present there.

Note that above script can help with matching things only. For the transformation one need to be more specific in the script. I will talk about those scripts and some intersting stuff regarding the same in my next post.

Till then stay tuned!

Advertisements

2 thoughts on “[Part I] Macros module init/exit, Boilerplate code and Linux Kernel

  1. Question: a boilerplated code is a code that repeats like platform_driver_register(&snirm710_driver) in your example? Or its the code that this function call replaced (i.e. having boilerplated codes are bad)?

    Like

  2. Boiler plate code is these function definitions [ie. snirm710_init and snirm710_exit] and their calls in module_init/exit as they are doing nothing special except registering/unregistering module.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s