| sarnold | welcome everyone to the third day of UMeet :) |
| sarnold | our first speaker today is gregkh, a long-time kernel hacker |
| sarnold | he has been maintaining the kernel's USB stack for .. 1.5 years? and has worked at IBM's linux |
| technology center for a little longer. If I recall correctly. |
| gregkh | long time? heh, I'm not _that_ old :) |
| sarnold | greg's talk is going to be about the coding style in the kernel, as it appears most people trying to |
| get drivers merged into the kernel screw it up somehow :) |
| sarnold | gregkh: you've got a kid. :) I think that makes you old. :) |
| sarnold | anyway, please welcome gregkh. :) |
| gregkh | heh, good point :) |
| gregkh | I'm here to talk about proper Linux kernel coding style. |
| gregkh | I'm going to go through a few reasons why we have a style guideline, |
| gregkh | then go over the currently documented style rules, and then cover |
| gregkh | some "undocumented" rules that everyone should also follow. |
| gregkh | feel free to ask questions whenever you want on #qc |
| gregkh | First off, why should we have a kernel coding style at all? |
| gregkh | After all, code formatting doesn't effect memory use, execution speed, |
| gregkh | or anything else a user of the kernel would notice. |
| gregkh | |
| gregkh | The main reason is that if a large body of code is written in a common |
| gregkh | style, it directly effects how easy it is to quickly understand the code, |
| gregkh | review it, and revise it. And since the Linux kernel source is meant for |
| gregkh | others to modify, we want this code to be as easy to change as possible. |
| gregkh | |
| gregkh | There have been a lot of research about this topic, and people can ask me |
| gregkh | offline if they want any citations. |
| gregkh | |
| gregkh | I'm kind of glossing over the reasons why we need rules, so are there any questions about this? |
| gregkh | good, no excuses for why anyone here isn't following them :) |
| gregkh | |
| gregkh | So what are the Linux kernel coding rules? |
| gregkh | First off, read the Documentation/CodingStyle file in the kernel tree. |
| gregkh | It lists a number of rules that should _always_ be followed. |
| gregkh | < zanshin> Are the rules because Linus wants them that way or are they based on something else? |
| gregkh | they are based on both because Linus wants them that way, and because of history. |
| gregkh | a combination of both. |
| gregkh | I'll summarize the CodingStyle rules here: |
| gregkh | - all tabs must be 8 characters, and the [TAB] character must be used instead of spaces. |
| gregkh | If your code is shifting off the side of the screen too much because |
| gregkh | of this, it's a good hint that you need to clean up the logic of your code. |
| gregkh | Be careful that your editor settings do not change tabs to spaces, I've seen that happen a lot. |
| gregkh | |
| gregkh | - braces must have the opening brace last on the line, and the closing brace first on the line. |
| gregkh | For example: |
| gregkh | if (x is true) { |
| gregkh | we do y |
| gregkh | } |
| gregkh | The only exception to this rule is functions, which have the opening |
| gregkh | brace at the beginning of the line like: |
| gregkh | int function(int x) |
| gregkh | { |
| gregkh | body of function |
| gregkh | } |
| gregkh | |
| gregkh | < jmgv> and class if you use c++ i suppose |
| gregkh | jmgv: there is no c++ in the kernel :) |
| gregkh | |
| gregkh | If you want to convert a file to this proper style, look at the |
| gregkh | scripts/Lindent script in the kernel tree. It is a good start at |
| gregkh | figuring out the indent(1) command line arguments to get the proper kernel style. |
| gregkh | |
| gregkh | any questions about indenting and tabs? |
| gregkh | there are lots of bad examples of this in the kernel, but I'm not going to go into those here. |
| gregkh | < gcc> the proper way to break a too long line |
| gregkh | There really isn't a "proper" way, just make it look sane. indent(1) can cause some horrible things to |
| happen with regards to that, so make sure you clean up after it by hand. |
| gregkh | < jmgv> how mandatory are these rules. |
| gregkh | very mandatory, your patch will be rejected. |
| gregkh | ok, moving on... |
| gregkh | |
| gregkh | - Your variables and functions should be declared descriptively and yet concisely. |
| gregkh | You should not use long flowery names like, CommandAllocationGroupSize or DAC960_V1_EnableMemoryMailboxI |
| nterface(), |
| gregkh | but instead, name them cmd_group_size, or enable_mem_mailbox(). |
| gregkh | Mixed case names are frowned upon and encoding the type of the |
| gregkh | variable or function in the name (like "Hungarian notation") is forbidden. |
| gregkh | < mulix> how about patches to clean up the coding style of old drivers? |
| gregkh | that's accepted by some people. |
| gregkh | but some maintainers are very stuborn about not changing their style. ignore them :) |
| gregkh | |
| gregkh | next item, |
| gregkh | - Functions should do only one thing, and do it well. |
| gregkh | They should be short, and hopefully contain only one or two screens of text. |
| gregkh | now this one is broken _all_ the time, but please, try to follow it. it will make |
| gregkh | maintaining your code easier over time. |
| gregkh | |
| gregkh | - Comments are very good to have, but they have to be good comments. |
| gregkh | Bad comments explain how the code works, who wrote a specific function on a |
| gregkh | specific date, or other such useless things. Good comments explain what |
| gregkh | the file or function does, and why it does it. |
| gregkh | If you are going to comment functions, use the kerneldoc format. |
| gregkh | This is explained in the Documentation/kernel-doc-nano-HOWTO.txt and |
| gregkh | scripts/kernel-doc files in the kernel tree. |
| gregkh | This allows documentation to be automatically generated from your code. |
| gregkh | |
| gregkh | and the final written rule, |
| gregkh | - reference count your data structures. |
| gregkh | This isn't so much a style guideline, as a proper coding guideline. |
| gregkh | If another thread can find your data structure, and you do not have a |
| gregkh | reference count on it, you almost certainly have a bug. |
| gregkh | Now the kernel has a kobject structure that can easily be used if you |
| gregkh | need to have a reference count within your structure. |
| gregkh | |
| gregkh | any questions on the documented rules? |
| gregkh | < snide> what about the unicity of the different function names all over the code ? |
| gregkh | what does "unicity" mean? |
| gregkh | do you mean "global namespace"? |
| gregkh | yes, pick your function names well, and don't make them global unless they have to be. |
| gregkh | |
| gregkh | Ok, moving on to the unwritten rules. |
| gregkh | - Use code that is already written. |
| gregkh | Use the list structures, the string functions, the kobject structure, |
| gregkh | the endian functions, and other, already written and debugged functions within your kernel |
| gregkh | code. |
| gregkh | Do NOT duplicate already written work just because you want to |
| gregkh | use the library functions, they are there for a reason. |
| gregkh | |
| gregkh | Moving on to my favorite rule: |
| gregkh | - typedef is EVIL! |
| gregkh | EVIL EVIL EVIL EVIL EVIL! |
| gregkh | NEVER USE typedef IN YOUR CODE!!! |
| gregkh | got it? :) |
| gregkh | even if you're ingo, he's slowly changing too :) |
| gregkh | Only in _very_ rare cases should you create a typedef. |
| gregkh | A function pointer is one of those instances. |
| gregkh | < gcc> why it so evil |
| gregkh | It hides information from the programmer, and enables them to do stupid things. |
| gregkh | like pass a whole structure on the stack as a paramater, and other such nonsense. |
| gregkh | again, typedefs for function pointers is ok. |
| gregkh | but that's it. |
| gregkh | If you only remember one "unwritten" rule, please remember that one. |
| gregkh | I'm going to pause for a few minutes to let the translators catch up, sorry for typing so fast |
| gregkh | < zanshin> what is bad about passing structures as parameters? |
| gregkh | pass a pointer to a structure, not the whole structure, or that will take up too much room on the |
| stack, and be very slow. |
| gregkh | ok, moving on, |
| gregkh | - do not place "magic numbers" within your code. |
| gregkh | If you are going to use a numeric value, document it, and make it a |
| gregkh | #define for others to understand what you are trying to do. |
| gregkh | If it's a number that a user might possibly want to be able to change, make it either a sysctl value, a |
| command line option, or a module paramater option. |
| gregkh | |
| gregkh | - do not put #ifdef within a .c file. |
| gregkh | They are allowd only within .h files. |
| gregkh | Use the preprocessor to compile away code that is not configured in, do not use |
| gregkh | #ifdef within the body of code to do this. |
| gregkh | |
| gregkh | any questions about this? |
| gregkh | < snide> but what about #ifdef CONFIG_SMP inside mm/slab.c for exemple |
| gregkh | yes, in some places it can't be helped, but for the majority of code, do not use it. |
| gregkh | |
| gregkh | Also remember all of these rules are just guidelines, you will find places that break everyone of them, |
| but try to follow them for 99% of your code. |
| gregkh | One last unwritten rule, use labeled identifiers for structures that you initialize at compile time. |
| gregkh | and by that I mean the following: |
| gregkh | struct foo bar = { |
| gregkh | .a = 24, |
| gregkh | .b = 42, |
| gregkh | }; |
| gregkh | use the C99 style initializers, and not the gnu style, as people are going through the whole kernel |
| gregkh | and converting them. |
| gregkh | |
| gregkh | So in conclusion: |
| gregkh | - read Documenatation/CodingStyle |
| gregkh | - follow it. |
| gregkh | - use scripts/Lindent. |
| gregkh | - Do not use typedef |
| gregkh | |
| gregkh | any further questions? |
| gregkh | < snide> how to avoid using #ifdef CONFIG_MYOPTION in a practical way then [ any exemple ? ] |
| gregkh | as an example, look at include/linux/hiddev.h and drivers/usb/input/hid_core.c for some functions |
| gregkh | that get compiled away if #ifdef CONFIG_USB_HIDDEV is not enabled. |
| gregkh | I also have a longer paper that was presented at ols2002 about this topic at: |
| http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_paper/codingstyle.ps |
| gregkh | and some slides at: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ |
| gregkh | < snide> so better split up the .c files ? |
| gregkh | No, split up the functions, and use static inline functions that do nothing if the config option is not |
| enabled, |
| gregkh | then in the .c file, always call them. gcc will compile them away to nothing if that option is not enabled. |
| gregkh | also look at include/security.h in the 2.5.51 kernel, it has lots of examples of this if CONFIG_SECURITY is not enabled. |
| gregkh | < snide> so using a function that the content will be wiped out with an #ifdef ? |
| gregkh | In a way, see the above examples for how it works. |
| gregkh | So that's it, any other questions? If anyone has any later, feel free to email me. |
| sarnold | gregkh: thanks :) |
| sarnold | thanks also to EMPEROR, who has been providing on-the-fly translation to spanish in #redes :) |
| fernand0 | plas plas plas plas plas plas plas plas pals plas plas |
| fernand0 | plas plas plas plas plas plas plas plas pals plas plas |
| fscked | nice talk, grek |
| fscked | greg |
| fernand0 | plas plas plas plas plas plas plas plas pals plas plas |
| fernand0 | plas plas plas plas plas plas plas plas pals plas plas |
| BorZung | good talk gregkh thanks you :) |
| Rawsock | while(1){ clap() ; } |
| gcc | gregkh: nice talk... thanks.. |
| tiri | clap clap clap clap |
| mulix | clap clap clap clap clap clap clap clap |
| mulix | clap clap clap clap clap clap clap clap |
| Rawsock | ow' somebody preempt me please :) |
| fscked | killall Rawsock |
| fscked | there |
| gregkh | thank you to everyone, and to the orginizers of this conference, I appreciate you letting me talk. |
| Rawsock | thx |
| VicMedina | clap clap |
| VicMedina | =) |
| JoelR | se vaaa se vaaa |
| EMPEROR | thanxs by your conference gregkh |
| JoelR | al loco, al loco al loco le queda poco |
| fernand0 | thank you very much to you |
| davej | oops, wrong window.. 8) |
| davej | thanks sarnold |
| MJ-usa | clap clap clap clap clap clap clap clap clap clap |
| MJ-usa | clap clap clap clap clap clap clap clap clap clap |
| MJ-usa | clap clap clap clap clap clap clap clap clap clap |
| MJ-usa | slow clap for avoid flooding |
| EMPEROR | thanxs by your conference gregkh |
| EMPEROR | very good :) |
| EMPEROR | greetings for you. |
| tiri | it was very good :) |
| MJesus_ | the soanish traslator are VicMedina Emperor, and tiri, and also have made an excelent work ! |
| MJesus_ | soanish /spanish |
| VicMedina | =) |
| JoelR | ai güant tu transleit tu |
| riel_ | well done gregkh |
| tiri | I'm going to study. Good bye! |
| twin | hola a todos |
| Ap | clap clap clap |
| MJesus_ | Ap, in #qc still there are discussion |