Wednesday, October 17, 2012

%.*s - Weird printk or Format of the format string

See this patch: https://lkml.org/lkml/2012/8/21/46

The author suggests:

- p9_debug(P9_DEBUG_VFS, "%s -> %s (%s)\n",
- dentry->d_name.name, st->extension, buffer);
+ p9_debug(P9_DEBUG_VFS, "%s -> %s (%.*s)\n",
+ dentry->d_name.name, st->extension, buflen, buffer);

But what the heck does %.*s? And why buflen variable was added as parameter to p9_debug? What would be the output of the C program above:

#include <stdio.h>

void main () {
        int i;
        char *ab ="abcdefghi";

        for (i = 0; i < 10; i++)
                printf ("%.*s\n", i, ab);
}

[peter@ace tmp]$ gcc test.c;./a.out

a
ab
abc
abcd
abcde
abcdef
abcdefg
abcdefgh
abcdefghi

Cool huh?

Sunday, October 14, 2012

Almost in the top ten

Thanks to my internship, on the raking of the number of patches accepted, only 10 people had sent more patches than me for the Kernel 3.7:

The ranking: http://www.remword.com/kps_result/3.7_petop.html

\o/

Not bad for a newbie.

Thursday, October 11, 2012

More than 100 (2) \o/


[peter@ace linux-next]$ git log |grep Author |grep peter.senna@gmail.com |wc -l
106

More than 100 patches accepted in the Linux Kernel. I'm happy with it but...

Those are really simple patches and I need to work on finding more complex things to do. But I think I'm on the way...

Friday, October 5, 2012

It is not enough to fix a bug and describe it correctly...

I'm sending a lot of patches. Many are just being accepted. But there is one very interesting rejection. I have not received nack, and the patch was not directed to /dev/null. The maintainers are happy with the code, but they "really" want me to do a very specific commit message.

Monday, October 1, 2012

How to write commit messages?


From: Linus Torvalds <torvalds@linux-foundation.org>
Newsgroups: fa.linux.kernel
Subject: Re: [PATCH] Bugfix to commit
Date: Tue, 23 Oct 2007 15:53:41 UTC
Message-ID: <fa.kLlZ0+PrvWCrpZjNV34+zBLE2ro@ifi.uio.no>

On Tue, 23 Oct 2007, Olaf Hering wrote:
>
> On Mon, Oct 22, Grant Likely wrote:
>
> > Olaf, do I have the correct solution here?
>
> Sure.

Side note: I already applied that patch, but take a look at the commit
message.

That's right: I had to edit the message provided to make it readable. So
I'll just take this opportunity to ask people that when they send
bug-fixes, please try to make the subject line and message make sense for
a *reader*, not for yourself (or even to me, although if it's readable to
some generic person, it's hopefully readable to me too!).

So a subject line of "Bugfix to commit <commit-sha-goes-here>" is
obviously not a very nice one, if you're looking at the kernel commit
history in gitk or some other visualizer that shows the first line as the
subject for the whole commit. It just doesn't make any sense to the
reader!

Related to that, another thing that also happens is that people write
subject lines (and the description) as if everybody realized that
something is particular to that architecture or driver. It may be true
that that particular developer (or development list) is only about ppc,
and then people write subject lines like "Fix execve() argument handling",
but again, when a *generic* person reads that, it now reads totally wrong,
since it wasn't execve() in general, it was a particular architecture that
it went wrong for.

So the rule should be:

 - if it's not fairly generic, specify the area (architecture, subsystem,
   driver) that the fix is for in the subject line. Even if you end up
   initially sending the fix out to just a list that handles that
   particular subsystem anyway.

 - don't use commit names in the subject line - and while it's great to
   use them in the body of the explanation, even there you don't want to
   assume that people read it from within git. People see patches and
   commit changelogs on the web or the commit mailing lists, so when
   specifying an exact version, also specify the human-readable name of
   that version.

 - write the commit message for an outsider, and use whitespace. The
   third-most common fixup I end up doing (after the above two) is to
   split things up into shorter paragraphs, after somebody wrote a good
   changelog entry, but made it one large unreadable blob of text. The
   more involved and technical some description is (and that's what long
   changelog entries should be - we don't want a fluffy novella here!),
   the more "breather space" and individually understandable small
   snippets of text readers need. Making things too dense is bad.

Anyway, this was in no way meant to be a specific problem for Grant or
Olaf - I end up editing just about half of all the commit messages of
stuff I get in email (except for Andrew's stuff, since Andrew largely does
the same kinds of cleanups anyway, so I only need to edit up a small
percentage of the patches he forwards). I'd like it to be *much* less than
that, so I thought I should speak up since I had an example of this.

Linus

Source: http://yarchive.net/comp/linux/commit_messages.html

Monday, September 17, 2012

More than 100! \o/

It is time to celebrate!



I've submitted more than 100 patches to the Linux Kernel! Yeah! Yeah!

See: http://www.kernelhub.org/?p=7&dev=10021&mbox_type=2

Want to learn about git?

Git is great! It really is. But you need to learn some secrets in order to use the full power. Two great resources:

1 - Pro git: Easy to read book that will make you very familiar with pro features of git.
2 - AlBlue’s Blog: Great articles explaining standard and advanced features of git.

Thursday, September 6, 2012

Patch versioning

When you send a second version of the same patch, you may add a "v2" on the subject so it will look like:
[PATCH v2]

There is an option for git format-patch that does it: --subject-prefix="PATCH v2"

More at: http://wireless.kernel.org/en/developers/Documentation/git-guide

Wednesday, July 11, 2012

Printing SPARSE errors during Linux Kernel Compilation

"Sparse, the semantic parser, provides a compiler frontend capable of parsing most of ANSI C as well as many GCC extensions, and a collection of sample compiler backends, including a static analyzer also called "sparse". Sparse provides a set of annotations designed to convey semantic information about types, such as what address space pointers point to, or what locks a function acquires or releases."

There is more about SPARSE here.

To check files that will be compiled with SPARSE:

$ make C=1

To check all files with SPARSE, even the ones that will not be compiled:

$ make C=2

Compiler warning messages for Linux Kernel

To enable compiler warning messages to be printed during compilation, add W=1 on the make command line like:


$ make W=1 drivers/media/dvb/frontends/stv090x.o


See this for description of warning level options.

Thursday, June 7, 2012

Installing Debug Kernel on Fedora 17

Installs Kernel package with debug options enabled, and debuginfo that will allow advanced Kernel tracing / profiling for oprofile and perf. For Kernel package: "kernel", not "kernel-debug".

$ sudo yum install --enablerepo=fedora-debuginfo --enablerepo=updates-debuginfo kernel-debuginfo

Monday, March 19, 2012

Emdebian!

Emdebian is a project that focus on thinner root filesystem than standard Debian. It is easy to spend 3.5 times less storage still being Debian. I've tested the Grip flavor of the project, more here.

Sunday, February 19, 2012

Tuesday, January 31, 2012

C code optimization benchmark

Can you believe that the code above can be optimized to run 14 times faster on Intel Core i7 CPU and to run 40 times faster on AMD Athlon X2?


#define X_SIZE 60
#define Y_SIZE 30
int matrix[X_SIZE][Y_SIZE];
void initmatrix(void)
{
int x,y;
for (x = 0; x < X_SIZE; ++x){
for (y = 0; y < Y_SIZE; ++y){
matrix[x][y] = -1;
}
}
}
void main()
{
initmatrix();
}

Wednesday, January 25, 2012

Writing device drivers in Linux: A brief tutorial - Compiling Errors and Warnings

The article:

Writing device drivers in Linux: A brief tutorial

Is a great starting point for Linux Kernel Development but it needs some simple updates. The first error you will find when compiling is:


/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:3:26: fatal error: linux/config.h: No such file or directory compilation terminated.


To fix, remove the line from the source code:
#include <linux/config.h>
Then some warnings:
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:28:3: warning: initialization from incompatible pointer type [enabled by default]
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:28:3: warning: (near initialization for ‘memory_fops.write’) [enabled by default]
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c: In function ‘memory_write’:
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:110:17: warning: ignoring return value of ‘copy_from_user’, declared with attribute warn_unused_result [-Wunused-result]
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c: In function ‘memory_read’:
/home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:94:15: warning: ignoring return value of ‘copy_to_user’, declared with attribute warn_unused_result [-Wunused-result]

To fix the warning with the "memory_write function" change the line from:
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
To:
ssize_t memory_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
And change the line from:
ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) {
To:
ssize_t memory_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) {
To fix the warnings about ignoring return value of "copy_from_user" and "copy_to_user", create a long inside both memory_read() and memory_write() to store the return value of copy_to/from_user.
ssize_t memory_read(struct ... )
{
        long ret;
        ret = copy_to_user(...);
        ...
}
ssize_t memory_write(struct ...)
{
        long ret;
        ...
        ret = copy_from_user(...);
        ...
}

Trying to compile again, other warning will be shown:
 /home/peter/devel/kdpeter/2012/bricks/original-post/memory.c:112:6: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
The error is on the line:
        tmp=buf+count-1;
buf is defined as "const char *buf" while tmp is defined as "char *tmp". Assigning const char * to char * can be considered an error. To fix it, make tmp also const char *. From:
   char *tmp;
To:
        const char *tmp;
The updated version of the source code is available here

Creating Linux Kernel Module made easy

Can you believe that a two line C source code can become a Linux module?

$ cat simplest_module.c
#include <linux/module.h>
MODULE_LICENSE("GPL");

$ cat Makefile
obj-m := simplest_module.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


Just "make".
$ make

To install your brand new bogus module:
$ sudo insmod simplest_module.ko

The lsmod command show that your module has been loaded:
$ lsmod |grep simplest_module
simplest_module          689  0
To remove the module:
$ sudo rmmod simplest_module
It is very simple to create a Linux Kernel Module. If you want more than a do nothing module, follow the links:

Source: Writing device drivers in Linux: A brief tutorial
Recommended: Writing a Simple USB Driver