All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kyle Moffett <mrmacman_g4@mac.com>
To: Avi Kivity <avi@argo.co.il>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>, linux-kernel@vger.kernel.org
Subject: Re: Compiling C++ modules
Date: Tue, 25 Apr 2006 11:59:03 -0400	[thread overview]
Message-ID: <9E05E1FA-BEC8-4FA8-811E-93CBAE4D47D5@mac.com> (raw)
In-Reply-To: <444DCAD2.4050906@argo.co.il>

On Apr 25, 2006, at 03:08:02, Avi Kivity wrote:
> Kyle Moffett wrote:
>> The "advantages" of the former over the latter:
>>
>> (1)  Without exceptions (which are fragile in a kernel), the  
>> former can't return an error instead of initializing the Foo.
> Don't discount exceptions so fast. They're exactly what makes the  
> code clearer and more robust.

Except making exceptions work in the kernel is exceptionally  
nontrivial (sorry about the pun).

> A very large proportion of error handling consists of:
> - detect the error
> - undo local changes (freeing memory and unlocking spinlocks)
> - propagate the error/
>
> Exceptions make that fully automatic. The kernel uses a mix of  
> gotos and alternate returns which bloat the code and are incredibly  
> error prone. See the recent 2.6.16.x for examples.

You talk about code bloat here.  Which of the following fits better  
into a 4k stack?  Which of the following shows the flow of code better?

C version:
	int result;
	spin_lock(&lock);
	
	result = do_something();
	if (result)
		goto out;
	
	result = do_something_else();
	if (result)
		goto out;
	
	out:
	spin_unlock(&lock);
	return result;

C++ version:
	int result;
	TakeLock l(&lock);
	
	do_something();
	do_something_else();

First of all, that extra TakeLock object chews up stack, at least 4  
or 8 bytes of it, depending on your word size.  Secondly with  
standard integer error returns you have one or two easily-predictable  
assembly instructions at each step of the way, whereas with  
exceptions you trade the absence of error handling in the rest of the  
code for a lot of extra instructions at the exception throw and catch  
points.  Secondly, while the former is much longer it shows  
_explicitly_ exactly where the flow of code can go.  In an OS kernel,  
that is critical;  your debugability is directly dependent on how  
easy it is to see where the flow of code is going.

>> (2)  You can't control when you initialize the Foo.  For example  
>> in this code, the "Foo item;" declarations seem to be trivially  
>> relocatable, even if they're not.
>>     spin_lock(&foo_lock);
>>     Foo item1;
>>     Foo item2;
>>     spin_unlock(&foo_lock);
>
> They only seem relocatable with your C glasses on. Put on your C++  
> glasses (much thicker), and initialization no longer seems  
> trivially movable.

This is a really _really_ bad idea for a kernel.  Having simple  
declaration statements have big side effects (like the common  
TakeLock object example I gave above) is bound to lead to people  
screwing up and forgetting about the side effects.  In C it's  
impossible to miss the side effects of a statement; function calls  
are obvious, as is global memory modification.

> On the other hand, you can replace the C code
>
> {
>    Foo item1, item2;
>    int r;
>
>    spin_lock(&foo_lock);
>    if ((r = foo_init(&item1)) < 0) {
>        spin_unlock(&foo_lock);
>        return r;
>    }
>    if ((r = foo_init(&item2)) < 0) {
>        foo_destroy(&item1);
>        spin_unlock(&foo_lock);
>        return r;
>    }
>    foo_destroy(&item2);
>    foo_destroy(&item1);
>    spin_unlock(&foo_lock);
>    return 0;
> }
>
> with
>
> {
>    spinlock_t::guard foo_guard(foo_lock);
>    Foo item1;
>    Foo item2;
> }

Let me point out _again_ how unobvious and fragile the flow of code  
there is.  Not to mention the fact that the C++ compiler can easily  
notice that item1 and item2 are never used and optimize them out  
entirely.  You also totally missed the "int flags" argument you're  
supposed to pass to object specifying allocation parameters, not to  
mention the fact that you just allocated 2 objects of unknown size on  
the stack (which is limited to 4k).  AND there's the fact that the  
order of destruction of foo_guard, item1, and item2 is implementation- 
defined and can't easily be relied upon without adding massive  
amounts of excess braces:

{
	spinlock_t::guard foo_guard(&foo_lock);
	{
		Foo item1;
		{
			Foo item2;
		}
	}
}

Also, your spinlock_t::guard chews up stack space that otherwise  
wouldn't be used.  It would be much better to rewrite your above C  
function like this:

{
	struct foo *item1, *item2;
	int result;
	spin_lock(&foo_lock);
	
	item1 = kmalloc(sizeof(*item1), GFP_KERNEL);
	item2 = kmalloc(sizeof(*item2), GFP_KERNEL);
	if (!item1 || !item2)
		goto out;
	
	result = foo_init(item1, GFP_KERNEL);
	if (result)
		goto out;
	
	result = foo_init(item2, GFP_KERNEL);
	if (result)
		goto out;
	
out:
	/* If alloc and init went ok, register them */
	if (item1 && item2 && !result) {
		result = register_foo_pair(item1, item2);
	}
	
	/* If anything failed, free resources */
	if (!item1 || !item2 || result) {
		kfree(item1);
		kfree(item2);
	}
	
	spin_unlock(&foo_lock);
	return result;
}

> 14 lines vs 3, one variable eliminated. How many potential security  
> vulnerabilities? How much time freed to work on the algorithm/data  
> structure, not on error handling?

Yeah, sure, yours is 3 lines when you omit the following:
(1)  Handling allocation flags like GFP_KERNEL
(2)  Not allocating things on the stack
(3)  Proper cleanup ordering
(4)  Reference counting, garbage collection, or another way to  
selectively free the allocated objects based on success or failure of  
other code.

Those are all critical things that we want to force people to think  
about; in many cases the exact ordering of operations _is_ important  
and that needs to be specified _and_ commented on.  How often do you  
think people write comments talking about things that don't even  
appear in the source code?

Also, since when is error handling _not_ a critical part of the  
algorithm?  You can see in my more complicated example that you only  
want to free the items if the registration was unsuccessful.  How do  
you handle that without adding a refcount to everything (bloat) or  
implementing garbage collection (worse bloat).

>> Does that actually make it any easier to understand the code?  How  
>> does it make it more obvious to be able to write a "+" operator  
>> that allocates memory?
>
> Not all C++ features need to be used in the kernel. In fact, not  
> all C++ features need to be used, period. Ever tried to understand  
> code which uses overloaded operator,() (the comma operator)?

The very fact that the language provides such features mean that  
people would try to get code using them into the kernel.  Have you  
ever looked at all the ugly debugging macros that various people  
use?  The C preprocessor provides few features at all, and yet people  
still abuse those, I don't see why C++ would be any different.

Cheers,
Kyle Moffett



  parent reply	other threads:[~2006-04-25 15:59 UTC|newest]

Thread overview: 200+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-24 19:16 Compiling C++ modules Gary Poppitz
2006-04-24 19:27 ` Greg KH
2006-04-24 20:02   ` C++ pushback Gary Poppitz
2006-04-24 20:15     ` Christoph Hellwig
2006-04-24 20:16     ` Greg KH
2006-04-24 20:18     ` Martin Mares
2006-04-24 21:36       ` Jeff V. Merkey
2006-04-24 21:28         ` J.A. Magallon
2006-04-24 21:43           ` Harald Arnesen
2006-04-24 21:52         ` Alan Cox
2006-04-24 22:16           ` J.A. Magallon
2006-04-25  0:05             ` Harald Arnesen
2006-04-25  0:46               ` Diego Calleja
2006-04-25  9:12                 ` Harald Arnesen
2006-04-25  1:30             ` linux-os (Dick Johnson)
2006-04-25  2:58               ` marty fouts
2006-04-27 22:55               ` Bill Davidsen
2006-05-02 15:58                 ` Randy.Dunlap
2006-05-02 20:36                 ` David Schwartz
2006-04-25  8:15             ` Xavier Bestel
2006-04-25  8:42               ` Avi Kivity
2006-04-25  8:52                 ` Martin Mares
2006-04-25  9:00                   ` Avi Kivity
2006-04-25  9:05                     ` Martin Mares
2006-04-25  9:13                       ` Avi Kivity
2006-04-25  9:22                         ` Xavier Bestel
2006-04-25 20:20                           ` J.A. Magallon
2006-04-25 20:31                             ` Barry Kelly
2006-04-25  9:09             ` Nikita Danilov
2006-04-25 20:10               ` J.A. Magallon
2006-04-25 18:02             ` Geert Uytterhoeven
2006-04-27  9:09             ` Alexander E. Patrakov
2006-04-24 22:39           ` Willy Tarreau
2006-04-24 22:57           ` Jeff V. Merkey
2006-04-24 23:02       ` David Schwartz
2006-04-25  8:55         ` Martin Mares
2006-04-25  8:59           ` Jan Engelhardt
2006-04-25 14:37           ` David Schwartz
2006-04-25 19:50             ` Martin Mares
2006-04-26  2:33               ` David Schwartz
2006-04-26  3:42                 ` Matthew Frost
2006-04-26 19:25                   ` David Schwartz
2006-04-26 20:01                     ` Jan-Benedict Glaw
2006-04-26 20:09                       ` Linus Torvalds
2006-04-26 20:19                         ` Al Viro
2006-04-26 21:37                           ` Sam Ravnborg
2006-04-28  9:23                             ` Avi Kivity
2006-04-28 12:00                               ` linux-os (Dick Johnson)
2006-04-28 12:46                                 ` Jan-Benedict Glaw
2006-04-26 20:25                         ` Jan-Benedict Glaw
2006-04-26 20:43                         ` David Schwartz
2006-04-26 23:00                         ` Roman Kononov
2006-04-27  0:38                           ` Kyle Moffett
2006-04-27  2:05                             ` Roman Kononov
2006-04-27  3:37                               ` Kyle Moffett
2006-04-27  5:37                                 ` Roman Kononov
2006-04-27 13:58                                   ` Michael Buesch
2006-04-27 14:22                                     ` linux-os (Dick Johnson)
2006-04-27  8:07                                 ` Avi Kivity
2006-04-27 13:55                                   ` Denis Vlasenko
2006-04-27 14:27                                     ` Avi Kivity
2006-04-27 14:56                                       ` Denis Vlasenko
2006-04-27 15:54                                         ` Bob Copeland
2006-04-27 16:03                                         ` Avi Kivity
2006-04-27 15:00                                       ` Martin Mares
2006-04-27 15:31                                         ` Avi Kivity
2006-04-27 15:38                                           ` Martin Mares
2006-04-28  8:16                                             ` Avi Kivity
2006-04-28  8:30                                               ` Avi Kivity
2006-04-28 15:47                                               ` Jan Engelhardt
2006-04-28 15:51                                       ` Jan Engelhardt
2006-04-28 16:51                                         ` Avi Kivity
2006-04-27 14:50                                 ` Sam Ravnborg
2006-04-27  8:50                               ` Martin Mares
2006-04-27  3:57                           ` Willy Tarreau
2006-04-27  5:53                             ` Roman Kononov
2006-04-27  7:55                           ` Jan-Benedict Glaw
2006-04-27 17:20                           ` C++ pushback (when does this religious thread end?) Leonard Peterson
2006-04-30 17:48                           ` C++ pushback Jan Harkes
2006-04-30 20:55                             ` David Schwartz
2006-04-26 20:05                     ` linux-os (Dick Johnson)
2006-04-26 20:09                     ` Xavier Bestel
2006-04-26 20:44                       ` Randy.Dunlap
2006-05-02 20:09                         ` C++ pushback + sparse Randy.Dunlap
2006-04-27  7:49                       ` C++ pushback Jiri Kosina
2006-04-26 21:05                     ` Martin Mares
2006-04-25  7:33       ` Avi Kivity
2006-04-25  7:47         ` Nick Piggin
2006-05-13 16:21         ` Esben Nielsen
2006-04-24 20:36     ` Thiago Galesi
2006-04-24 21:38     ` Kurt Wall
2006-04-27 16:17     ` Roman Kononov
2006-04-27 21:59       ` Grant Coady
2006-04-27 22:09     ` Bill Davidsen
2006-04-27 23:19       ` Jan Knutar
2006-04-24 19:30 ` Compiling C++ modules Al Viro
2006-04-24 19:40 ` linux-os (Dick Johnson)
2006-04-24 20:54   ` Geert Uytterhoeven
2006-04-24 19:42 ` Alexey Dobriyan
2006-04-24 20:30 ` Daniel Barkalow
2006-04-24 20:35 ` C++ is in US [Re: Compiling C++ modules] Jiri Slaby
2006-04-24 20:45 ` Compiling C++ modules Alan Cox
2006-04-24 21:03   ` Avi Kivity
2006-04-24 21:23     ` Joshua Hudson
2006-04-24 21:29     ` Kyle Moffett
2006-04-24 21:50       ` marty fouts
2006-04-24 22:09         ` Martin Mares
2006-04-24 22:30           ` Willy Tarreau
2006-04-24 22:32           ` Joshua Hudson
2006-04-24 22:45           ` marty fouts
2006-04-25 15:32         ` Michael Buesch
2006-04-25  7:08       ` Avi Kivity
2006-04-25 10:23         ` James Courtier-Dutton
2006-04-25 15:59         ` Kyle Moffett [this message]
2006-04-25 16:46           ` Avi Kivity
2006-04-25 17:10             ` Dmitry Torokhov
2006-04-25 17:19               ` Avi Kivity
2006-04-25 17:28                 ` Dmitry Torokhov
2006-04-25 17:53                   ` Avi Kivity
2006-04-25 18:04                     ` Dmitry Torokhov
2006-04-25 18:08                     ` Valdis.Kletnieks
2006-04-25 18:26                       ` Avi Kivity
2006-04-25 18:38                         ` Avi Kivity
2006-04-25 18:52                           ` Michael Poole
2006-04-25 19:13                             ` Avi Kivity
2006-04-27 15:10                     ` Denis Vlasenko
2006-04-27 20:15                       ` Willy Tarreau
2006-04-27 21:08                         ` Davi Arnaut
2006-04-28  9:33                           ` Avi Kivity
2006-04-28 10:03                             ` Avi Kivity
2006-04-28 11:27                               ` Sergei Organov
2006-04-28 11:03                             ` Martin Mares
2006-04-28 11:30                               ` Avi Kivity
2006-04-28 15:56                                 ` Jan Engelhardt
2006-04-28 17:02                                   ` Avi Kivity
2006-04-28 17:38                                     ` linux-os (Dick Johnson)
2006-04-29  2:50                                       ` Christer Weinigel
2006-05-01 17:46                                       ` Dave Neuer
2006-05-01 20:21                                         ` Jan Engelhardt
2006-05-01 23:53                                         ` David Schwartz
2006-05-02  5:12                                           ` Willy Tarreau
2006-05-02 10:32                                             ` Avi Kivity
2006-05-02 11:15                                               ` Martin Mares
2006-05-02 11:26                                                 ` Avi Kivity
2006-05-02 11:40                                                   ` linux-os (Dick Johnson)
2006-05-02 12:42                                                   ` David Woodhouse
2006-05-02 16:27                                                     ` Christer Weinigel
2006-05-02 12:48                                                   ` Martin Mares
2006-05-02 13:52                                                     ` Avi Kivity
2006-05-02 14:13                                                       ` Al Viro
2006-05-02 14:54                                                         ` Avi Kivity
2006-05-02 16:16                                                   ` Brian Beattie
2006-05-02 16:21                                                     ` Avi Kivity
2006-05-02 13:21                                               ` Willy Tarreau
2006-05-02 14:41                                                 ` Avi Kivity
2006-05-02 22:25                                                   ` Diego Calleja
2006-05-02 13:34                                               ` Al Viro
2006-05-02 14:02                                                 ` Avi Kivity
2006-05-02 14:34                                                   ` Al Viro
2006-05-02 15:04                                                     ` Avi Kivity
2006-05-02 15:15                                                       ` Al Viro
2006-05-02 15:19                                                         ` Avi Kivity
2006-05-02 15:27                                                           ` Kyle Moffett
2006-05-02 15:30                                                             ` Avi Kivity
2006-05-02 15:28                                                           ` Al Viro
2006-05-02 15:51                                                             ` Avi Kivity
2006-05-02 15:24                                                         ` Kyle Moffett
2006-05-03 13:13                                           ` Mark Lord
2006-05-03 20:51                                             ` David Schwartz
2006-04-30 21:15                               ` Eric W. Biederman
2006-04-25 17:54                 ` linux-os (Dick Johnson)
2006-04-26  8:30                   ` Jan Engelhardt
2006-04-26 11:36                     ` linux-os (Dick Johnson)
2006-04-25 19:22             ` Kyle Moffett
2006-04-25 19:54               ` Michael Buesch
2006-04-25 20:24               ` Avi Kivity
2006-04-25 20:11             ` Bongani Hlope
2006-04-25 20:26               ` Avi Kivity
2006-04-25 21:02                 ` Valdis.Kletnieks
2006-04-25 21:15                   ` Avi Kivity
     [not found]                     ` <71a0d6ff0604251646g4fc90b3dr30a03b8606360e7f@mail.gmail.com>
2006-04-26  4:39                       ` Avi Kivity
2006-04-25 17:55           ` Geert Uytterhoeven
2006-04-24 21:58     ` Alan Cox
2006-04-25  7:20       ` Avi Kivity
2006-04-25  9:06         ` Matt Keenan
2006-04-25 20:29           ` Bongani Hlope
2006-04-25 20:37             ` Avi Kivity
2006-04-25 21:08               ` Bongani Hlope
2006-04-25  4:17     ` Martin J. Bligh
2006-04-25  5:30       ` Avi Kivity
2006-04-25  8:58         ` Sam Ravnborg
2006-04-25  7:56     ` Jakob Oestergaard
2006-04-25  9:03     ` Jan Engelhardt
2006-04-24 21:36   ` J.A. Magallon
     [not found] <65eLE-GJ-21@gated-at.bofh.it>
     [not found] ` <65zwH-61W-51@gated-at.bofh.it>
     [not found]   ` <65zZH-6Bw-23@gated-at.bofh.it>
     [not found]     ` <66grR-2DK-27@gated-at.bofh.it>
2006-04-28  0:03       ` Robert Hancock
2006-04-28  9:37 Khushil Dep
2006-05-02 18:21 Al Boldi
2006-05-02 20:28 ` J.A. Magallon
2006-05-02 23:55 ` Peter Williams
2006-05-03  8:09 ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9E05E1FA-BEC8-4FA8-811E-93CBAE4D47D5@mac.com \
    --to=mrmacman_g4@mac.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=avi@argo.co.il \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.