Error handling in the kernel

A general practice in the kernel is after calling the function, to check whether the function has succeeded or failed. Depending on the function there are ways of checking for failure of a function.

Sometimes kernel developers do not add error checks on a function. This is actually not good practice. Error handling is indeed a practice that should be employed everywhere.

There are two types of error checks mainly: IS_ERR check and a NULL check.

var = somefunction(…);

An IS_ERR check looks something like this:

if (IS_ERR(var))

return PTR_ERR(var);

Whereas a NULL check may look like this:

if (!var)

return -ENOMEM;

You can find out the correct type of error handling for each function by checking the definition of the function, lxr is the easiest way to find out. Check what the function is returning in case of error. If the function returns NULL, we need a NULL check and if the function is returning an ERR_PTR, we need a IS_ERR check.

So for the last 2-3 weeks, I worked on an additional script wherein I found out functions in the kernel which are using both NULL check and IS_ERR checks which is mostly wrong. One particular function should have only one type of error handling. I found around 53 results where error checks are ambiguous and now I am consistently checking each of these results and finding out the correct error check and modifying the cases where incorrect check has been used.

Coccinellery – Part 2

As a continuation to my last post, I will continuetalking about the interesting scripts in Coccinellery.

simplify_ioremap_resource.cocci is a script that detects case where there is error handling for a platform_get_resource call just before a call to devm_ioremap_resource. This error handling is not required and should be removed. Thisthis and this are example patches that have been added to the kernel already.

simple_kzalloc.cocci finds cases where kmalloc and memset 0 are used since they can be replaced by a direct call to kzalloc. After using this script Julia suggested finding more functions like these where memset and the function call can be replaced by a direct function call. For example: vmalloc/vzalloc is a similar case and a patch accepted for this case.

kmemdup.cocci is used to find cases where memory is allocated followed by a call to memcpy. These two calls can be replaced by a direct call to kmemdup. This is an example patch.

moduleparam.cocci is a script to find cases where both module.h and moduleparam.h are included. module.h contains a call to moduleparam.h making the call to it redundant and useless. These are some accepted patches for the same: one and two.

export_static.cocci finds cases where a static function is being exported which is not possible. Sadly could not find any cases to submit patches on.

 

Coccinellery – Part 1

This week I’m going to talk of some of the interesting scripts I’ve found in Coccinellery.

There are A LOT of scripts in coccinellery which you can see here.

One of the first few scripts that I submitted a patch for was using badcheck.cocci. This script checks the devm_ioremap_resource error detection code. Some functions in the kernel like devm_ioremap_resource use an IS_ERR test instead of a NULL test for error detection but in many places in the kernel developers have not updated the error detection code. Excitingly, this script, if all goes well, after some required updation I will be sending to the kernel 🙂

bugon.cocci is a script that replaces an if condition and a BUG() statement with a simple BUG_ON() statement. You can see an example patch that I submitted and has been applied here.

Some functions like kmem_cache_alloc, kmem_cache_zalloc, etc have a corresponding freeing function known as kmem_cache_free; but some developers have used kfree instead of kmem_cache_free. A script to solve this issue is given here.

countptr.cocci is a script that removes an exceptional ‘&’ in front of a function name. Interestingly this one gives a lot of results in the kernel and is a good semantic patch to submit and get patches accepted. It is very easy too 🙂

Typically, we use devm_kzalloc in probe function of a driver to allocate managed resources. But sometimes, both devm_kzalloc and kzalloc are used in the probe function. This is generally an incorrect practice and devm functions should be used consistently. These inconsistencies can be found with the help of this script.

Two scripts on devm functions are given here and here which find places where freeing functions like iounmap and kfree have been used for devm_ allocated data.

There are lots of interesting scripts on devm functions and a number of opportunities to submit patches on the same.

 

Interesting times ahead indeed!

Accepted as an Outreachy Intern!

I’ve been accepted as an Outreachy intern and will be working on Coccinelle under the guidance of Julia Lawall over the summer!

Julia has a lot of interesting tasks in mind for the internship, but for now I’m working on running and checking scripts from coccinellery and submitting patches based on them.

This is quite interesting because I get to understand common bugs and learn about different functions used in the kernel. For example, I was introduced to devres during the application period of Outreachy and now continue to understand how managed resources work, analyse coccinelle scripts finding devm function bugs and submit patches based on them.

What is devres?

Every driver has some memory resources which are allocated using functions and stored as a linked list of arbitrarily sized memory areas associated with a device. This is called devres.

The special thing about devres or managed resources is that the memory allocated is automatically freed when a driver detaches.

For example, devm_kzalloc() is the managed version of kzalloc(), a very common function in the kernel used to allocate memory. With devm_kzalloc() we do not need kfree() to free memory allocated by devm_kzalloc(), since it is automatically freed when the driver detaches.

There are several managed resource interfaces, a full list of which can be found here.

But many developers still add these freeing functions for devm allocated memory, here is where the awesomeness of Coccinelle steps in. Coccinellery has a couple of scripts to detect these devm bugs and a lot of opportunities to submit patches.

Another interesting devm_ function is devm_ioremap_resource. The usual null error check is actually incorrect for this function, instead it returns an ERR_PTR() encoded error on failure, but developers have not switched the error checks everywhere . Coccinellery contains a semantic patch for this and I’ve submitted several patches like this to rectify this which has already been applied in the kernel.

Julia also recommends this semantic patch to be added to the kernel so I will be understanding how to go about adding the patch to the kernel also!

Exciting internship indeed! 🙂