#format wiki
#language en
== 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 ==
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:
channel--;
if (channel < sizeof(priv->cck_pwr_tbl))
power = priv->cck_pwr_tbl[channel];
break;
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];
else
power = priv->ofdm_pwr_tbl[channel-1];
break;
}
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
f(...);
-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
1. Save the above semantic patch in a file ret.cocci
1. Run Coccinelle on ret.cocci and staging-next, ie spatch --sp-file
ret.cocci --no-includes --dir {your staging-next path} > ret.out. This may
take some time.
Do you find the result satisfactory? If so, submit some patches. If not,
let us know!
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 ==
In the following function, from
drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c, the variable ret is not
very useful.
{{{
static int
rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
{
int ret = 0;
DBG_8723A("%s\n", __func__);
return ret;
}
}}}
The code would be simpler as:
{{{
static int
rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
{
DBG_8723A("%s\n", __func__);
return 0;
}
}}}
The following semantic patch makes this transformation:
{{{
@@
identifier ret;
@@
-int ret = 0;
... when != ret
when strict
-return ret;
+return 0;
}}}
The code ... when != ret
means that between the int ret = 0;
and the return at the end of the function, there should be no use of ret.
The code when strict
means that this should hold on every
execution path, including those that abort the function (return in the
middle of a function)
Test this semantic patch on the staging tree. Do you find any of the
results surprising? Are the results correct? Did Coccinelle complain
about anything or crash (if so, you may need to get a more recent
version). Submit some patches based on your results.
== Coccinelle challenge problem 3 ==
If you look back at the code in == Coccinelle challenge problem 1, you will
see that actually the only use of ret is the one at the end of the
function, and the semantic patch gets rid of it. This suggests that it
could be good to extend that semantic patch with another rule that would
look for cases where a variable is never used, and then remove the
declaration of the variable entirely. For this, the semantic patch rule
shown in == Coccinelle challenge problem 2 can serve as inspiration, but needs
to be somewhat modified.
Submit patches, including your semantic patch, based on your results. Does
your semantic patch do too much? Think about what information you would
need to get a better result.
== Coccinelle challenge problem 4 ==
The lustre file system in the staging tree defines the following macro:
{{{
#define GOTO(label, rc) \
do { \
if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \
libcfs_log_goto(&msgdata, #label, (long_ptr_t)(rc)); \
} else { \
(void)(rc); \
} \
goto label; \
} while (0)
}}}
In practice, the "then" branch of the if is debugging code, and it is only
the code in the else branch that is useful, as well as the goto that is
after the if. The GOTO macro is not standard in Linux, and it would be
nice to get rid of it. Write a semantic patch to make the required
transformation.
== Coccinelle challenge problem 5 ==
Continuing with the GOTO macro, you may find that in many cases the rc
argument can be dropped completely. In what case should it be kept? In
what case should it be dropped? Write a semantic patch that gives a
pleasant result. Hint: it may be useful to consider the
metavariable types identifier (a variable name like rc) and constant (a
number like 0).
Bigger hint: A number of patches making this transformation using
Coccinelle have been submitted already. If you are stuck, track them down
in the git logs and try to understand what they do.
== Coccinelle challenge problem 6 ==
The lustre file system in the staging tree uses a number of macros related
to locks. Find their definitions and use Coccinelle to replace them by the
corresponding standard Linux functions.
== Coccinelle challenge problem 7 ==
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 * is something like a patch with a - at the beginning of any line that contains a match of the starred pattern.
1. 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 ...>.
Note that there are very few occurrences of this problem in staging. If
someone else has done this problem, you may need to look elsewhere in the
kernel.
== Other Coccinelle challenge problems ==
You can also try the [http://kernelnewbies.org/JuliaLawall_round8 Old Coccinelle challenge problems] from round 8.
== 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