• Immutable Page
  • Info
  • Attachments

JuliaLawall round10

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 OPW project.


These challenge problems are listed roughly in order of increasing difficulty. In particular, problems 1-3 go together, and problems 4-5 go together. It is not obligatory to do all of them. You may find other things that can be done with Coccinelle. Source 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 thing than if you use it do one thing over and over.


The Coccinelle project in this round involves removing use of deprecated functions, typically functions that were formerly widely used but have now been replaced by something else. The project will thus involve considering a series of such functions. For the timeline, please discuss what you would do in the case of one such function. That is, if you are to replace calls to foo by calls to bar what steps would be involved in doing this.

A list of functions that it could be interesting to work with is available here.


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/vt6656/rf.c:

int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
        int ret = true;
        u8 power = priv->cck_pwr;

        if (channel == 0)
                return -EINVAL;

        switch (rate) {
        case RATE_1M:
        case RATE_2M:
        case RATE_5M:
        case RATE_11M:

                if (channel < sizeof(priv->cck_pwr_tbl))
                        power = priv->cck_pwr_tbl[channel];
        case RATE_6M:
        case RATE_9M:
        case RATE_18M:
        case RATE_24M:
        case RATE_36M:
        case RATE_48M:
        case RATE_54M:
                if (channel > CB_MAX_CHANNEL_24G)
                        power = priv->ofdm_a_pwr_tbl[channel-15];
                        power = priv->ofdm_pwr_tbl[channel-1];

        ret = vnt_rf_set_txpower(priv, power, rate);

        return ret;

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

int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
        int ret = true;
        u8 power = priv->cck_pwr;

        if (channel == 0)
                return -EINVAL;

        switch (rate) {

        return vnt_rf_set_txpower(priv, power, rate);

The following semantic patch makes this change:

expression ret;
identifier f;

-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.0-rc21. This is available on the Coccinelle webpage (coccinelle.lip6.fr) and on github.

  1. Download staging-next

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

  3. Run Coccinelle on ret.cocci and staging-next, ie spatch --sp-file ret.cocci --no-includes --dir {your staging-next 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.

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 value = (FLASH_CMD_STATUS_REG_READ == 24); 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

In the following code, when x has any pointer type

 kfree((u8 *)x);

the cast to u8 *, or to any other pointer type is not needed. Write a semantic patch to remove such casts. Consider generalizing your semantic patch to functions other than kfree.

Coccinelle challenge problem 4

The function setup_timer combines the initialization of a timer with the initialization of the timer's function and data fields. This is illustrated by the following patch:

  -       init_timer(&hwif->timer);
  -       hwif->timer.function = &ide_timer_expiry;
  -       hwif->timer.data = (unsigned long)hwif;
  +       setup_timer(&hwif->timer, &ide_timer_expiry, (unsigned long)hwif);

Write a semantic patch to implement this transformation. Note that the call to init_and the initialization of the function and data fields do not necessarily occur in the order shown in the example, and they are not necessarily contiguous. Furthermore, the data field might not always be initialized.

Coccinelle challenge problem 5

The file include/linux/list.h contains some very useful functions for iterating over doubly linked lists. Some of these functions are list_for_each, list_for_each_entry, list_for_each_safe, and list_for_each_entry_safe. Some other functions related to doubly linked lists are list_empty and list_entry. Sometimes when list_empty is used in a loop, the code could be better rewritten using eg list_for_each, and sometimes when list_entry is used the code could be better written using eg list_for_each_entry.

Use Coccinelle to improve the code manipulating doubly linked lists, to remove when possible calls to list_empty and list_entry.

Note: This is a hard problem. You will need to study very carefully the definitions in include/linux/list.h and to study very carefully the code that uses these definitions, to be sure to be changing the code in the right way. Nevertheless, doubly linked lists are very widely used in the kernel, so it is useful to be familiar with how to manipulate them.

Coccinelle challenge problem 6

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.

Note that there is currently only one staging driver in which it makes sense to make these changes; if you get no results, it may be because someone else has fixed the problem before you.

Coccinelle challenge problem 7

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, !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 8

Lustre driver code uses the macro container_of0, which is a nonstandard version of the Linux macro container_of. Replace uses of container_of0 with uses of container_of. Note this is easy to do with Coccinelle. What is hard is to explain why it can be done. A patch should cange only one occurrence at a time, and should include a careful explanation of why the change can be made.

Coccinelle challenge problem 9

In general, static inline functions are preferred over macros, because static inline functions have types and return values. lustre/lustre/include/obd_class.h contains a number of macros that look like they could be static inline functions, such as class_export_rpc_inc. Consider whether these macros can be transformed into functions and if so make the change. This requires in particular checking the call sites, and finding the type of the argument in each case, to ensure that it is always the same.

The same file contains some other macros, such as OBD_CHECK_DEV, that use return. Return is more complicated, because you don't want to just return from the macro, but from the calling function. Consider how the code can be reorganized to eliminate these macros. If you decide to make an inline function, update the usage sites to use a lowercase version of the function name.

The file contains other macros that could be cleaned in various ways. For each case, explain carefully why your transformation is correct, and check that the resulting code actually compiles.

Other Coccinelle challenge problems

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

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-02-07 11:20:45 by JuliaLawall