• Immutable Page
  • Info
  • Attachments

Diff for "JuliaLawall"

Differences between revisions 53 and 54

Deletions are marked like this. Additions are marked like this.
Line 173: Line 173:
This small task has no impact on the kernel code, so there is no need to claim it.

About Me

I'm a researcher at Inria, in Paris France. I develop the tool Coccinelle, which allows easy matching and transformation of C code. Coccinelle has been designed with the goal of contributing to Linux development, but it can also be used on other C code.

Please write to me directly if you would like to apply to the Coccinelle Outreachy project.


This page is organized into two parts. The first part is about learning to use Coccinelle. The second part has some small tasks that are relevant for the constification project. If you are interested in working on the Coccinelle project, you should do some work from both parts. The second part does not actually require knowing Coccinelle, so you can work on the two parts in any order, or in parallel.

For the Coccinelle part, it would be a good idea to start with the first challenge problem, to check that you know how to use the tool properly. The remaining challenge problems can be done in any order. It is not obligatory to do all of them. You may find other things that can be done with Coccinelle. Sources of inspiration may be the results of checkpatch and patches that have been applied to the kernel in the past. Any kind of problem that occurs over and over might be amenable to being solved with Coccinelle.

These challenge problems may apply to many files in the kernel. Pick a few files, and send patches for those. Once they have been accepted, consider moving on to another challenge problem. You will get a better understanding of Coccinelle if you use it for many different things than if you use it do one thing over and over.

There are many examples of uses of Coccinelle, in previous patches, in the kernel source tree in the scripts/coccinelle directory, and at coccinellery. If you use a script that is already in the Linux kernel, you don't need to include the script in your commit log, but rather something like Generated-by: scripts/coccinelle/misc/badty.cocci


A tutorial for Coccinelle is available here. These are slides that are intended to be presented, but they may be understandable independently of the presentation. Please note that the tutorial focuses on the source code of Linux 3.2, and so the patches created in doing the exercises of the tutorial are not suitable for submission to the opw-kernel mailing list. Doing the tutorial also does not count as a contribution to the project.

Coccinelle challenge problem 1

Consider the following function, from drivers/staging/most/hdm-dim2/dim2_sysfs.c

static ssize_t bus_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
                                   const char *buf, size_t count)
        ssize_t ret;
        struct medialb_bus *bus =
                container_of(kobj, struct medialb_bus, kobj_group);
        struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);

        if (!xattr->store)
                return -EIO;

        ret = xattr->store(bus, buf, count);
        return ret;

In this function, the last two lines could be compressed into one, as:

static ssize_t bus_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
                                   const char *buf, size_t count)
        ssize_t ret;
        struct medialb_bus *bus =
                container_of(kobj, struct medialb_bus, kobj_group);
        struct bus_attr *xattr = container_of(attr, struct bus_attr, attr);

        if (!xattr->store)
                return -EIO;

        return xattr->store(bus, buf, count);

The following semantic patch makes this change:

local idexpression ret;
expression e;

-ret =
-return ret;

Do the following:

  1. Download and install Coccinelle. If you are using Linux, it should be available in your package manager. Any recent version is fine to start

with, but you may need to get the most recent version, which is 1.0.4. This is available on the Coccinelle webpage (coccinelle.lip6.fr) and on github.

  1. Download staging-testing

  2. Save the above semantic patch in a file ret.cocci

  3. Run Coccinelle on ret.cocci and staging-testing, ie spatch --sp-file ret.cocci --no-includes --dir {your staging-testing path}/drivers/staging > ret.out. This may take some time.

Do you find the result satisfactory? If so, submit some patches. If not, let us know!

Your code may now declare some variables that are never used. Remove them before submitting your patch.

If you do submit a patch based on the use of Coccinelle, please mention Coccinelle in your patch, and the semantic patch that you used.

What happens in the above semantic patch if you replace local idexpression by identifier or expression? Try these extra variants and see if there are any differences in the results.

Coccinelle challenge problem 2

Parentheses are not needed around the right hand side of an assignment, like in value = (FLASH_CMD_STATUS_REG_READ << 24);. Write a semantic patch to remove these parentheses.

One could consider that parentheses might be useful in the case of eg rising = (dir == IIO_EV_DIR_RISING); because there could be a confusion between the different kinds of =. Extend your semantic patch using a disjunction so that it does not report on such cases.

Coccinelle challenge problem 3

Assignments in if conditions slightly complicate program analyses and are frowned upon by checkpatch.

        if ((rc = pci_enable_device(pdev))) {
                printk(KERN_WARNING "i2o: couldn't enable device %s\n",
                return rc;

Write a semantic patch to move such assignments out before the if. In the general case, it may be necessary to take into account the possibility of operators such as && and ||. Your semantic patch should not change the order in which expressions are evaluated. In the case of very complex conditions, the transformation may also not be desirable, if it requires duplicating code or introducing many layers of ifs.

Coccinelle challenge problem 4

Assignments in function call arguments are also undesirable. Write a semantic patch to pull such assignments out before the function call.

Note There are only a few occurrences of this issue in staging. Again, watch out for || and &&.

Coccinelle challenge problem 5

Some functions return NULL as a return value on failure. NULL can be tested for as !x, NULL == x, or x == NULL. When NULL represents failure, eg of an allocation, !x is commonly used. The following are some functions that commonly follow this strategy:


Write a semantic patch to clean up the tests on the results of one or more of these functions.

As a much harder problem, use Coccinelle to find other functions for which tests for NULL use !x at least 70% of the time.

Coccinelle challenge problem 6

Converting calls to eg pr_err to dev_err requires finding a valid, ie non-NULL, argument of type struct device *. Study some calls to pr_err etc and see if there are some contexts in which a valid value of type struct device * is known to exist. For example, the first argument of devm_kzalloc has type struct device *, and this value must not be NULL. Hence, there is no need to use pr_err once dev_kzalloc has been called.

Other Coccinelle challenge problems

You can also try the Coccinelle challenge problems from round 8, Coccinelle challenge problems from round 9, and Coccinelle challenge problems from round 10.

Small tasks

To be considered for the Coccinelle project in this round, you should complete one or more of the following small tasks. This is in addition to sending cleanup patches and learning to use Coccinelle, by either the above challenge problems or projects of your own choosing.

Small task 1

The following, from drivers/staging/vt6656/channel.c, is an example of a top-level structure declaration that is not currently const:

static struct ieee80211_supported_band vnt_supported_2ghz_band = {
        .channels = vnt_channels_2ghz,
        .n_channels = ARRAY_SIZE(vnt_channels_2ghz),
        .bitrates = vnt_rates_bg,
        .n_bitrates = ARRAY_SIZE(vnt_rates_bg),

Pick any 10 such structure declarations and add const when possible (and submit a patch) and explain why it cannot be const when adding const is not possible. For the latter, send me an email with your explanations. There are hundreds of these structure declarations in drivers/staging so it is not necessary to claim this task. You could, however, declare that you are working on some particular files.

To find opportunities using Coccinelle, you will need to disable the optional_qualifier isomorphism. Just put disable optional_qualifier in the middle of the first @@ in your structure declaration matching rule. Without this, it will match const ones also.

Small task 2

The program size gives some information about the layout of a .o file, in particular the size of the text segment and the data segment. When a structure is constified, we would like to be sure that some data has moved from the data segment (non-const data) to the text segment (code and const data), to be sure that the transformation has had an effect. Write a program, using the programming language of your choice, to take as input a patch and a path to the kernel source code. The program should extract the names of the files affected by the patch, compile those files, run size on each compiled file, apply the patch to the kernel source code, compile the affected files again, and run size on the result.

To produce the patch, you can just make changes to the code by hand, run git diff to obtain a patch, and then run git checkout to restore the kernel to the state before the patch has been applied.

This small task has no impact on the kernel code, so there is no need to claim it.

Contact info

Email: <Julia.Lawall AT lip6 DOT fr>

My IRC handle is jlawall.

Questions about using Coccinelle should go to the Coccinelle mailing list: <cocci AT systeme DOT lip6 DOT fr>


Tell others about this page:

last edited 2016-09-19 12:56:29 by JuliaLawall