KernelNewbies:

About Me

I'm a researcher at Inria, in Paris France. I develop the tool [http://coccinelle.lip6.fr 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.

Coccinelle challenge problem 1

The following semantic patch introduces the use of the managed version of kzalloc in some very constrained cases:

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

@other_things depends on platform@
@@

( iio_device_alloc(...)
| iio_trigger_alloc(...)
| iio_device_register(...)
| request_region(...)
| request_mem_region(...)
| request_irq(...)
| dma_alloc_coherent(...)
| dma_alloc_noncoherent(...)
| dma_declare_coherent_memory(...)
| dma_pool_create(...)
| pci_enable_device(...)
| pci_pin_device(...)
| ioport_map(...)
| ioremap(...)
| ioremap_nocache(...)
| pcim_iomap(...)
| pcim_iomap_table(...)
| pcim_iomap_regions(...)
| regulator_get(...)
| regulator_bulk_get(...)
| regulator_register(...)
| clk_get(...)
| pinctrl_get(...)
| pwm_get(...)
| usb_get_phy(...)
| acpi_dma_controller_register(...)
| spi_register_master(...)
| gpio_request(...)
| gpio_request_one(...)
)

@prb depends on !other_things@
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);
  ...>
}

Do the following:

  1. Read about the use of devm functions in Documentation/driver-model/devres.txt. Any recent version is fine.
  2. Download and install Coccinelle. If you are using Linux, it should be available in your package manager. Any recent version is fine.
  3. Download staging-next
  4. Save the above semantic patch in a file kzalloc.cocci
  5. Run Coccinelle on kzalloc.cocci and staging-next, ie spatch --sp-file kzalloc.cocci --no-includes --dir {your staging-next path} > kzalloc.out. This may take some time. Don't worry if there are some error messages.

  6. Study the results in kzalloc.out carefully and submit a patch based on one case where you think that the transformation was done properly.

This semantic patch is not very robust, in that there is no guarantee that the kfree that is removed in the remove function is freeing the data that was kzalloced in the probe function. Some things to watch out for are as follows:

  1. Does the file already use devm functions? If so, any kzalloc and kfree that this semantic patch finds are probably still there for a reason.
  2. Does the file contain calls to kfree that are not in the probe and remove functions. If so, could they affect the kzalloced data? If so, more thought may be required as to whether the kfrees are needed, and if they should be transformed to devm_kfree for early release of the devm allocated data.
  3. Does the transformation affect both a probe function and a remove function, or only a probe function? If there is no transformation to a remove function, is the kfree somewhere else? Is there a reason why the allocated data should not be freed? Again, more thought may be needed.

Coccinelle challenge problem 2

One of the checkpatch errors is "do not use assignment in if condition". And example of this is the following code, from drivers/staging/cxt1e1/sbeproc.c:

        if (!(bip = OS_kmalloc(sizeof(struct sbe_brd_info))))
                return -ENOMEM;

Write a semantic patch to find and fix such cases, eg producing the following patch for the above example:

-       if (!(bip = OS_kmalloc(sizeof(struct sbe_brd_info))))
+       bip = OS_kmalloc(sizeof(struct sbe_brd_info));
+       if (!bip)
                return -ENOMEM;

Apply your semantic patch to the Linux staging directory and submit patches based on your results. Take case that your result is as you would like it to look if you were making the transformation by hand. If it is not, consider whether you should extend your semantic patch in some way to improve the result. Include a concise version of the semantic patch that you have used in your commit message.

Coccinelle challenge problem 2

If a variable has value 0, then there is no point in combining it with other things with |, as for any x, 0 | x is just x. The following semantic patch finds this problem.

@@
expression x,e,e1;
statement S;
@@

if (x == 0) {
  ... when != x = e1
      when != while(...) S
      when != for(...;...;...) S
(
*  x |= e
|
*  x | e
)
  ... when any
}
  1. Apply the semantic patch to the Linux kernel and make some corresponding changes by hand. Note that the result of a semantic patch that uses * puts a - at the beginning of any line that contains a match of the starred pattern.
  2. Consider how you could extend the semantic patch to fix the code rather than just finding possible occurrences of the problem. Hint: it may work best to change the first "..." to <... and to change the "... when any" to just ...>.

Contact info

Email: MailTo(Julia.Lawall AT lip6 DOT fr)

My IRC handle is jlawall.

Questions about using Coccinelle should go to the Coccinelle mailing list: MailTo(cocci AT systeme DOT lip6 DOT fr)


CategoryHomepage

KernelNewbies: JuliaLawall (last edited 2014-03-01 21:00:52 by JuliaLawall)