Move resources allocated using unmanaged interface to managed devm interface

So today let’s talk about devm functions as that is what I have been upto the past couple of weeks. Yes, should have finished the task by now but due to some reasons was not active a couple of days :(.
Now what are devm functions. There are some common memory resources used by drivers which are allocated using functions and stored as a linked list of arbitrarily sized memory areas called devres. Some of this memory is allocated in the probe function. But all of this memory should be freed on a failure path or a driver detach. Else, the driver will be leaking resources and wasting precious main memory!
Detection of such memory leaks is difficult as they not clearly noticeable. So, managed interfaces have been created for common resources used by drivers. They have a name similar to the corresponding unmanaged function making it easy to identify e.g.:  dma_alloc_coherent() and dmam_alloc_coherent(), kzalloc() and devm_kzalloc(). If a managed function is used for memory allocation the resources are guaranteed to be freed both on initialization failure and driver detachment. Many of these managed functions are devm functions. eg: devm_kzalloc, devm_iio_device_alloc().
My task has been mainly to identify the cases where kzalloc() can be changed to devm_kzalloc() and the corresponding kfree()s can be done away with. Then the changes were applied and minor code changes like removal of labels , removing of brackets in single statement ifs were done. I have been using a Coccinelle semantic patch to do this task and have made tweaks to handle some specific cases. Here is a major part of the Coccinelle semantic patch making the change:

@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
.probe = probefn,
.remove = removefn,
};

@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, …) {
<+…
– e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)

?-kfree(e);
…+>
}

@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(…) {
<…
– kfree(e);
…>
}

There are many cases in which a lot of code goes away and the probe and remove functions appear really simple and easier to understand.
At the same time, there are issues such as cases to which the patch applies but does not benefit much as there are major resources that are still unmanaged. Also, some more advanced functions that can be managed like IRQs have not been handled at this stage.

Advertisements

Thanks to OPW.

Dreams do come true. This statement came true for me on the night of 21st March when I did a Ctrl+F for my name on the selection list of OPW and the result was 1 match! Yeah.. I was in. I would be learning this summers while contributing to the Linux Kernel. Yes, it is the same kernel that is the basis of the operating system used by most people at my university or by lakhs of Linux users worldwide. Yes it the free and open-source operating system that we hear about all the time. I have been given the opportunity to contribute to the kernel, to help make some changes that may make the operating system less buggy, more compatible to variety of softwares and hence improve the user experience for the Linux users worldwide. I will put my heart and soul into this project, learn for the sake of knowledge and work for the betterment of the software. I express my heartfelt thanks to the mentors for there faith in me and the help and guidance they have always given.

The main purpose of this blog will be to track my progress through my project Coccinelle. I will probably write about any issues or interesting technical subjects I encounter through the project, provided they are related to FOSS.

The content of this blog will be mostly technical. Hope you enjoy the read and find some cool stuff here!!