linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Arsen Arsenović" <arsen@aarsen.me>
To: David Howells <dhowells@redhat.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 00/45] C++: Convert the kernel to C++
Date: Fri, 12 Jan 2024 00:09:30 +0100	[thread overview]
Message-ID: <86r0inmpbm.fsf@aarsen.me> (raw)
In-Reply-To: <152261521484.30503.16131389653845029164.stgit@warthog.procyon.org.uk>

[-- Attachment #1: Type: text/plain, Size: 10762 bytes --]


David Howells <dhowells@redhat.com> writes:

> Here are a series of patches to start converting the kernel to C++.  It
> requires g++ v8.
>
> What rocks:
>
>  (1) Inline template functions, which makes implementation of things like
>      cmpxchg() and get_user() much cleaner.
>
>  (2) Inline overloaded functions, which makes implementation of things like
>      static_branch_likely() cleaner.
>
>  (3) Class inheritance.  For instance, all those inode wrappers that require
>      the base inode struct to be included and that has to be accessed with
>      something like:
>
> 	inode->vfs_inode.i_mtime
>
>      when you could instead do:
>
> 	inode->i_mtime
>
> What I would disallow:
>
>  (1) new and delete.  There's no way to pass GFP_* flags in.
>
>  (2) Constructors and destructors.  Nests of implicit code makes the code less
>      obvious, and the replacement of static initialisation with constructor
>      calls would make the code size larger.

This also disallows the primary benefit of C++ (RAII), though.  A lot of
static initialization can be achieved using constexpr and consteval,
too.

It is incredibly useful to be able to express resource ownership in
terms of automatic storage duration.

>  (3) Exceptions and RTTI.  RTTI would bulk the kernel up too much and
>      exception handling is limited without it, and since destructors are not
>      allowed, you still have to manually clean up after an error.
>
>  (4) Operator overloading (except in special cases).
>
>  (5) Function overloading (except in special inline cases).

Generic code, another significant benefit of C++, requires function
overloading, though.

>  (6) STL (though some type trait bits are needed to replace __builtins that
>      don't exist in g++).

A lot of useful stuff that works fine in kernel contexts is in the STL,
though.  For instance, nearly everything from the iterators, ranges,
utility, memory, and algorithms library works fine.  Naturally,
concepts, type traits, and language support libraries are also fine.

>  (7) 'class', 'private', 'namespace'.

'class' does nothing that struct doesn't do, private and namespace serve
simply for encapsulation, so I don't see why banning these is useful.

>  (8) 'virtual'.  Don't want virtual base classes, though virtual function
>      tables might make operations tables more efficient.

Virtual base classes are seldom useful, but I see no reason to
blanket-ban them (and I suspect you'll never notice that they're not
banned).

> Issues:
>
>  (1) Need spaces inserting between strings and symbols.
>
>  (2) Direct assignment of pointers to/from void* isn't allowed by C++, though
>      g++ grudgingly permits it with -fpermissive.  I would imagine that a
>      compiler option could easily be added to hide the error entirely.

This should never be useful.

Have a lovely night!

>  (3) Need gcc v8+ to statically initialise an object of any struct that's not
>      really simple (e.g. if it's got an embedded union).
>
>  (4) Symbol length.  Really need to extern "C" everything to reduce the size
>      of the symbols stored in the kernel image.  This shouldn't be a problem
>      if out-of-line function overloading isn't permitted.
>
> So far, it gets as far as compiling init/main.c to a .o file.
>
> Seriously, though...
>
> Apart from the cleaner inline functions allowed by templating, I'm not sure
> there's a lot of the C++ language that we would want to use in the kernel
> unless we want to go for more advanced classes implementing interesting types.
>
> We could, for example, wrap things like userspace pointers, __be numbers,
> ioport addresses and control access to them that way, but I don't know that it
> gains a whole load that sparse doesn't give us.
>
> And finally, doing this did find a few minor things that can be fixed.
>
> David
> ---
> David Howells (45):
>       Use UINT_MAX, not -1, to represent an invalid UID, GID or project ID
>       Fix exception_enter() return value
>       Fix loop var in be32_to_cpu_array() and cpu_to_be32_array()
>       Fix use of ACPI_COMPANION_SET()
>       C++: Set compilation as C++ for .c files
>       C++: Do some basic C++ type definition
>       C++: Define a header with some C++ type traits for type checking
>       C++: Implement abs() as an inline template function
>       C++: x86: Fix the x86 syscall table production for C++
>       C++: x86: Turn xchg(), xadd() & co. into inline template functions
>       C++: x86: Turn cmpxchg() & co. into inline template functions
>       C++: x86: Turn cmpxchg_double() & co. into inline template functions
>       C++: x86: Turn cmpxchg64() & co. into inline template functions
>       C++: x86: Turn put_user(), get_user() & co. into inline template functions
>       C++: Need space between string and symbol
>       C++: Disable VERIFY_OCTAL_PERMISSIONS() for the moment
>       C++: Turn READ_ONCE(), WRITE_ONCE() & co. into inline template functions
>       C++: Turn RCU accessors into inline template functions
>       C++: Turn ktime_add/sub_ns() into inline template functions
>       C++: init/main: Constify pointers
>       C++: Set the type of atomic64_t to s64
>       C++: Define apic_intr_mode after the enum definition, not before
>       C++: Don't do "extern asmlinkage"
>       C++: Fix BUILD_BUG_ON_ZERO()
>       C++: Fix void variables
>       C++: Can't have variable/member names the same as typedef names
>       C++: Disable __same_type() for the moment
>       C++: Move ctx_state enum out of struct context_tracking
>       C++: Move the print_line_t enum before first use
>       C++: Include linux/hrtimer.h from linux/timer.h
>       C++: Avoid using 'compl' and 'and' as names
>       C++: __to_fd() needs to reduce the size of v for struct fd::flags
>       C++: Move irqchip_irq_state enum
>       C++: Fix up use of LIST_POISON*
>       C++: Fix static_branch_likely/unlikely()
>       C++: Fix kernfs_type() int->enum
>       C++: Fix page_zonenum() int->enum
>       C++: mutex_trylock_recursive_enum() int->enum
>       C++: Fix spinlock initialisation
>       C++: Fix sema_init()
>       C++: Cast in bitops
>       C++: Hide C++ keywords
>       C++: Don't need to declare struct pgd_t after typedef
>       C++: Can't declare unsized-array in struct cgroup
>       C++: Move initcall_level_names[] to __initdata section
>
>
>  Makefile                               |   13 -
>  arch/x86/Makefile                      |    2
>  arch/x86/entry/syscalls/Makefile       |    8
>  arch/x86/entry/syscalls/syscallhdr.pl  |   73 ++++
>  arch/x86/entry/syscalls/syscalltbl.pl  |   95 +++++
>  arch/x86/include/asm/alternative.h     |   10 -
>  arch/x86/include/asm/apic.h            |    2
>  arch/x86/include/asm/arch_hweight.h    |    4
>  arch/x86/include/asm/atomic.h          |    2
>  arch/x86/include/asm/atomic64_64.h     |   12 -
>  arch/x86/include/asm/cmpxchg.h         |  430 +++++++++++-----------
>  arch/x86/include/asm/cmpxchg_64.h      |   28 +
>  arch/x86/include/asm/hw_irq.h          |   38 +-
>  arch/x86/include/asm/percpu.h          |   94 ++---
>  arch/x86/include/asm/perf_event.h      |    2
>  arch/x86/include/asm/processor.h       |    2
>  arch/x86/include/asm/special_insns.h   |    2
>  arch/x86/include/asm/tlbflush.h        |    1
>  arch/x86/include/asm/uaccess.h         |  630 +++++++++++++++++---------------
>  arch/x86/include/asm/uaccess_64.h      |   66 +--
>  arch/x86/kernel/asm-offsets_32.c       |    1
>  arch/x86/kernel/asm-offsets_64.c       |    1
>  arch/x86/purgatory/Makefile            |    2
>  include/asm-generic/bitops/le.h        |   32 +-
>  include/asm-generic/sections.h         |    2
>  include/linux/acpi.h                   |    2
>  include/linux/backing-dev-defs.h       |    4
>  include/linux/blkdev.h                 |   86 ++--
>  include/linux/build_bug.h              |    5
>  include/linux/byteorder/generic.h      |    4
>  include/linux/cgroup-defs.h            |    2
>  include/linux/compat.h                 |    2
>  include/linux/compiler-c++.h           |   54 +++
>  include/linux/compiler-gcc.h           |    5
>  include/linux/compiler.h               |   93 +----
>  include/linux/compiler_types.h         |    2
>  include/linux/context_tracking.h       |    4
>  include/linux/context_tracking_state.h |   14 -
>  include/linux/cpumask.h                |    4
>  include/linux/crypto.h                 |    4
>  include/linux/elevator.h               |   82 ++--
>  include/linux/file.h                   |    2
>  include/linux/interrupt.h              |   10 -
>  include/linux/irq.h                    |    1
>  include/linux/irqflags.h               |   10 +
>  include/linux/jump_label.h             |   41 +-
>  include/linux/kernel.h                 |   35 --
>  include/linux/kernfs.h                 |    2
>  include/linux/ktime.h                  |   12 +
>  include/linux/list.h                   |    8
>  include/linux/list_bl.h                |    4
>  include/linux/list_nulls.h             |    2
>  include/linux/lockdep.h                |    2
>  include/linux/mm.h                     |    2
>  include/linux/mutex.h                  |    5
>  include/linux/page-flags.h             |    3
>  include/linux/poison.h                 |    6
>  include/linux/printk.h                 |    4
>  include/linux/projid.h                 |    2
>  include/linux/rculist.h                |    4
>  include/linux/rculist_bl.h             |    2
>  include/linux/rcupdate.h               |  124 ++++--
>  include/linux/sched/task.h             |    2
>  include/linux/semaphore.h              |    5
>  include/linux/spinlock.h               |    2
>  include/linux/spinlock_types.h         |    4
>  include/linux/start_kernel.h           |    2
>  include/linux/stddef.h                 |   12 -
>  include/linux/sysctl.h                 |    6
>  include/linux/timer.h                  |    1
>  include/linux/trace_events.h           |   16 -
>  include/linux/types.h                  |   16 +
>  include/linux/uidgid.h                 |    4
>  init/main.c                            |    4
>  scripts/checksyscalls.sh               |    2
>  tools/power/cpupower/Makefile          |    1
>  tools/virtio/Makefile                  |    2
>  77 files changed, 1269 insertions(+), 1010 deletions(-)
>  create mode 100644 arch/x86/entry/syscalls/syscallhdr.pl
>  create mode 100644 arch/x86/entry/syscalls/syscalltbl.pl
>  create mode 100644 include/linux/compiler-c++.h


--
Arsen Arsenović

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 381 bytes --]

  parent reply	other threads:[~2024-01-11 23:18 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-01 20:40 [PATCH 00/45] C++: Convert the kernel to C++ David Howells
2018-04-01 20:40 ` [PATCH 01/45] Use UINT_MAX, not -1, to represent an invalid UID, GID or project ID David Howells
2018-04-01 23:04   ` Randy Dunlap
2018-04-01 20:40 ` [PATCH 02/45] Fix exception_enter() return value David Howells
2018-04-05  1:34   ` Sasha Levin
2018-04-01 20:40 ` [PATCH 03/45] Fix loop var in be32_to_cpu_array() and cpu_to_be32_array() David Howells
2018-04-01 20:40 ` [PATCH 04/45] Fix use of ACPI_COMPANION_SET() David Howells
2018-04-01 20:40 ` [PATCH 05/45] C++: Set compilation as C++ for .c files David Howells
2018-04-02  6:10   ` kbuild test robot
2018-04-02  6:10   ` kbuild test robot
2018-04-03 13:16   ` David Howells
2018-04-03 13:27     ` Fengguang Wu
2018-04-10  8:44     ` David Howells
2018-04-10  9:45       ` Fengguang Wu
2018-04-11  1:13         ` Li, Philip
2018-04-01 20:40 ` [PATCH 06/45] C++: Do some basic C++ type definition David Howells
2018-04-02  4:37   ` kbuild test robot
2018-04-02  6:10   ` kbuild test robot
2018-04-01 20:40 ` [PATCH 07/45] C++: Define a header with some C++ type traits for type checking David Howells
2018-04-02  7:00   ` kbuild test robot
2018-04-01 20:41 ` [PATCH 08/45] C++: Implement abs() as an inline template function David Howells
2018-04-01 20:41 ` [PATCH 09/45] C++: x86: Fix the x86 syscall table production for C++ David Howells
2018-04-02  7:57   ` kbuild test robot
2018-04-01 20:41 ` [PATCH 10/45] C++: x86: Turn xchg(), xadd() & co. into inline template functions David Howells
2018-04-01 20:41 ` [PATCH 11/45] C++: x86: Turn cmpxchg() " David Howells
2018-04-01 20:41 ` [PATCH 12/45] C++: x86: Turn cmpxchg_double() " David Howells
2018-04-01 20:41 ` [PATCH 13/45] C++: x86: Turn cmpxchg64() " David Howells
2018-04-01 20:41 ` [PATCH 14/45] C++: x86: Turn put_user(), get_user() " David Howells
2018-04-01 20:41 ` [PATCH 15/45] C++: Need space between string and symbol David Howells
2018-04-01 20:41 ` [PATCH 16/45] C++: Disable VERIFY_OCTAL_PERMISSIONS() for the moment David Howells
2018-04-01 20:41 ` [PATCH 17/45] C++: Turn READ_ONCE(), WRITE_ONCE() & co. into inline template functions David Howells
2018-04-01 20:42 ` [PATCH 18/45] C++: Turn RCU accessors " David Howells
2018-04-01 20:42 ` [PATCH 19/45] C++: Turn ktime_add/sub_ns() " David Howells
2018-04-01 20:42 ` [PATCH 20/45] C++: init/main: Constify pointers David Howells
2018-04-01 20:42 ` [PATCH 21/45] C++: Set the type of atomic64_t to s64 David Howells
2018-04-01 20:42 ` [PATCH 22/45] C++: Define apic_intr_mode after the enum definition, not before David Howells
2018-04-01 20:42 ` [PATCH 23/45] C++: Don't do "extern asmlinkage" David Howells
2018-04-01 20:42 ` [PATCH 24/45] C++: Fix BUILD_BUG_ON_ZERO() David Howells
2018-04-01 20:42 ` [PATCH 25/45] C++: Fix void variables David Howells
2018-04-01 20:42 ` [PATCH 26/45] C++: Can't have variable/member names the same as typedef names David Howells
2018-04-01 20:42 ` [PATCH 27/45] C++: Disable __same_type() for the moment David Howells
2018-04-01 20:43 ` [PATCH 28/45] C++: Move ctx_state enum out of struct context_tracking David Howells
2018-04-01 20:43 ` [PATCH 29/45] C++: Move the print_line_t enum before first use David Howells
2018-04-01 20:43 ` [PATCH 30/45] C++: Include linux/hrtimer.h from linux/timer.h David Howells
2018-04-01 20:43 ` [PATCH 31/45] C++: Avoid using 'compl' and 'and' as names David Howells
2018-04-02  7:57   ` kbuild test robot
2018-04-01 20:43 ` [PATCH 32/45] C++: __to_fd() needs to reduce the size of v for struct fd::flags David Howells
2018-04-01 20:43 ` [PATCH 33/45] C++: Move irqchip_irq_state enum David Howells
2018-04-01 20:43 ` [PATCH 34/45] C++: Fix up use of LIST_POISON* David Howells
2018-04-01 20:43 ` [PATCH 35/45] C++: Fix static_branch_likely/unlikely() David Howells
2018-04-01 20:43 ` [PATCH 36/45] C++: Fix kernfs_type() int->enum David Howells
2018-04-01 20:43 ` [PATCH 37/45] C++: Fix page_zonenum() int->enum David Howells
2018-04-01 20:44 ` [PATCH 38/45] C++: mutex_trylock_recursive_enum() int->enum David Howells
2018-04-01 23:10   ` Randy Dunlap
2018-04-01 20:44 ` [PATCH 39/45] C++: Fix spinlock initialisation David Howells
2018-04-01 20:44 ` [PATCH 40/45] C++: Fix sema_init() David Howells
2018-04-01 20:44 ` [PATCH 41/45] C++: Cast in bitops David Howells
2018-04-02  6:10   ` kbuild test robot
2018-04-01 20:44 ` [PATCH 42/45] C++: Hide C++ keywords David Howells
2018-04-02  7:32   ` kbuild test robot
2018-04-01 20:44 ` [PATCH 43/45] C++: Don't need to declare struct pgd_t after typedef David Howells
2018-04-01 20:44 ` [PATCH 44/45] C++: Can't declare unsized-array in struct cgroup David Howells
2018-04-01 20:44 ` [PATCH 45/45] C++: Move initcall_level_names[] to __initdata section David Howells
2018-04-01 22:20 ` [PATCH 00/45] C++: Convert the kernel to C++ Randy Dunlap
2018-04-02  9:28 ` Vegard Nossum
2024-01-09 19:57 ` H. Peter Anvin
2024-01-09 23:29   ` Andrew Pinski
2024-01-11 21:01     ` Arsen Arsenović
2024-01-10  0:29   ` David Howells
2024-01-10  8:58   ` Jiri Slaby
2024-01-10 13:04     ` Neal Gompa
2024-01-10 15:52       ` Jason Gunthorpe
2024-01-10 16:05         ` H. Peter Anvin
2024-01-10 16:25         ` Neal Gompa
2024-01-10 17:57           ` Theodore Ts'o
2024-01-12  2:23             ` H. Peter Anvin
2024-01-12  2:52               ` Kent Overstreet
2024-01-11  8:06       ` Andreas Herrmann
2024-01-10 15:01   ` Michael de Lang
     [not found]     ` <69fe1c0c-b5ec-4031-b719-d9c14742929c@metux.net>
2024-01-12 21:58       ` Michael de Lang
2024-01-11  4:24   ` John Hubbard
2024-01-11  5:09     ` Dave Airlie
2024-01-11 15:24       ` Eric Curtin
2024-01-11 21:37       ` David Laight
2024-01-11 12:39   ` Chris Down
2024-01-11 19:40     ` David Laight
2024-01-24  6:53       ` Jiri Slaby
2024-01-12  2:54   ` H. Peter Anvin
2024-01-12  8:52   ` David Howells
2024-01-12 23:53     ` H. Peter Anvin
2024-01-09 23:40 ` David Howells
2024-01-10  7:13   ` Alexey Dobriyan
2024-01-12  2:25   ` H. Peter Anvin
2024-01-12  2:40   ` H. Peter Anvin
2024-01-11 23:09 ` Arsen Arsenović [this message]
2024-01-12  9:20 ` David Howells
2024-01-12 21:35   ` Arsen Arsenović
2024-01-12 23:41   ` David Howells
2018-04-01 21:32 Alexey Dobriyan
2024-01-11 10:56 Alexey Dobriyan
2024-01-11 10:58 ` Neal Gompa
2024-01-11 11:12   ` Alexey Dobriyan
2024-01-11 12:12   ` Andreas Herrmann

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=86r0inmpbm.fsf@aarsen.me \
    --to=arsen@aarsen.me \
    --cc=dhowells@redhat.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).