From: Linus Torvalds <torvalds@linux-foundation.org>
To: Johannes Weiner <hannes@saeurebad.de>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
clameter@sgi.com, penberg@cs.helsinki.fi
Subject: Re: Why is the kfree() argument const?
Date: Wed, 16 Jan 2008 15:16:45 -0800 (PST) [thread overview]
Message-ID: <alpine.LFD.1.00.0801161454010.2806@woody.linux-foundation.org> (raw)
In-Reply-To: <87odblct19.fsf@saeurebad.de>
On Wed, 16 Jan 2008, Johannes Weiner wrote:
>
> Okay, I understood that now. A const qualifier just forbids modifying
> the underlying memory _through this particular pointer_, right?
Yes, exactly.
> In the case of slub's kfree(), which takes a const pointer, you pass it
> on to slab_free() which actually _DOES_ modification of the underlying
> memory when linking the object to the freelist (as far as I understood
> the code).
First off, the whole concept of "underlying memory" is all about the fact
that pointers point not to separate objects with its own existence, but
point to a shared resource ("memory") that can be accessed many different
ways.
So immediately when you talk about "underlying memory", you need to
realize that now you're not talking about "that pointer" any more, but you
are talking about the stuff that *other* pointers can access.
And the whole (and *only*) point of a memory allocator is turning that
amorphous notion of "infinitely aliasable underlying memory" model into
more of a "C pointer to separate objects" model.
That *is* what a memory allocator does.
> So if I got it right and you actually modify the memory you only got a
> const pointer to
No. YOU DO NOT.
You *invalidate* the pointer. Then, the memory allocator releases that
portion of the "infinitely aliasable underlying memory", but that means
that THAT POINTER NO LONGER EXISTS ON A C LEVEL.
So no, you don't "modify the memory you only got a const pointer to".
What you do is that the memory allocator
- keeps track of the NON-const memory that it always had
- it sees the const pointer you gave it, and uses that pointer to look up
ITS OWN DATA STRUCTURES.
- it then accesses those memory locations using its own pointers.
The "const pointer" you passed to kfree() simply no longer exists. The
object it pointed to has gone away. That particular pointer simply isn't
valid any more.
But the memory management code, which maintains its own structures for
what it has allocated and not allocated, can (and will) generally use the
knowledge *it* has about its own pointers to modify its own data
structures.
The fact that they (obviously) alias in memory is irrelevant. It has no
meaning for the "const void *" you passed in. That pointer is not usable
for the caller any more.
And no, this is not just a semantic argument. It's a real issue. The
pointer you pass in to kfree() is obviously used to *find* the data
structures that the memory allocator maintains, and there is almost
inevitably a rather direct mapping between the passed-in pointers and the
data structures that a memory manager maintains itself, but they really
are different.
So to take a kfree() a pointer, the memory manager will use the "binary
value" of that pointer to find its own data structures, and sometimes the
values are so closely related that it ends up being a direct cast
(possibly with an offset), but the end result of that direct cast really
is now the memory management internal data, not the original pointer.
A real example of this is the actual kfree() implementation in the kernel
(let's take the one from SLAB):
struct kmem_cache *c;
..
c = virt_to_cache(objp);
which then actually ends up doing a
struct page *page = virt_to_head_page(obj);
return page_get_cache(page);
which literally does math on the binary representation of the pointer to
look up the backing store values (because the memory manager by definition
is the thing that knows how the low-level representation of pointers
actually works).
So now the kernel has turned that user-supplied pointer into ITS OWN data
structures, that contain the NON-CONST aliases for the data.
(It will actually use the const pointer to further get offsets into those
things, of course, so it's several levels of indirection off that pointer)
And yes, then it will write to those non-const aliases, but that's really
no different from the same old thing: the pointer *you* passed kmalloc()
may be "const", but the memory manager itself has its own data structures
to keep track of *its* aliases to the same memory, and those are the ones
that are actually used to re-use the memory for others (and poison it
etc).
So the particular pointer you passed in is "const". But that never *ever*
guarantees that there aren't other non-const pointers around to be used
that can modify the memory. And the memory manegement definitely has all
those aliased pointers around - it's the whole *point* of memory
management.
Linus
next prev parent reply other threads:[~2008-01-16 23:22 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-16 16:32 Johannes Weiner
2008-01-16 16:48 ` Christoph Lameter
2008-01-16 17:34 ` Bernd Petrovitsch
2008-01-16 17:45 ` Pekka J Enberg
2008-01-16 18:39 ` Linus Torvalds
2008-01-16 22:19 ` Johannes Weiner
2008-01-16 22:20 ` Christoph Lameter
2008-01-16 22:37 ` Johannes Weiner
2008-01-16 23:13 ` Johannes Weiner
2008-01-16 23:18 ` Linus Torvalds
2008-01-16 23:16 ` Linus Torvalds [this message]
2008-01-16 22:33 ` Steven Rostedt
[not found] <MDEHLPKNGKAHNMBLJOLKIEGIJJAC.davids@webmaster.com>
2008-01-17 21:25 ` Linus Torvalds
2008-01-17 22:28 ` David Schwartz
2008-01-17 23:10 ` Linus Torvalds
2008-01-18 0:56 ` David Schwartz
2008-01-18 1:15 ` Linus Torvalds
2008-01-18 5:02 ` David Schwartz
2008-01-18 15:38 ` Chris Friesen
2008-01-18 16:10 ` Linus Torvalds
2008-01-18 20:55 ` David Schwartz
2008-01-18 17:37 ` Olivier Galibert
2008-01-18 18:06 ` DM
2008-01-18 7:51 ` Giacomo Catenazzi
2008-01-18 8:20 ` Giacomo Catenazzi
2008-01-18 13:53 ` Andy Lutomirski
2008-01-18 17:24 ` Olivier Galibert
2008-01-18 22:29 ` J.A. Magallón
2008-01-18 23:44 ` Krzysztof Halasa
2008-01-18 13:54 ` Andy Lutomirski
2008-01-18 19:14 ` Vadim Lobanov
2008-01-18 19:31 ` Zan Lynx
2008-01-18 19:55 ` Vadim Lobanov
2008-01-18 8:30 ` Vadim Lobanov
2008-01-18 9:48 ` Jakob Oestergaard
2008-01-18 11:47 ` Giacomo A. Catenazzi
2008-01-18 14:39 ` Jakob Oestergaard
2008-01-18 19:06 ` Vadim Lobanov
2008-01-18 13:31 ` Björn Steinbrink
2008-01-18 14:53 ` Jakob Oestergaard
2008-01-18 12:45 ecolbus
2008-01-18 15:20 ` Giacomo A. Catenazzi
2008-01-18 16:45 ecolbus
2008-01-18 18:20 ` Olivier Galibert
2008-01-18 19:10 ecolbus
[not found] <fa.cHMztHfqJXv7vw5O0nQ8SdTrma0@ifi.uio.no>
[not found] ` <fa.V9M+5l8C/um5KEiBtZOjbJDQmu4@ifi.uio.no>
2013-01-12 19:18 ` antoine.trux
2013-01-13 8:10 ` Chen Gang F T
2013-01-13 17:41 ` Guenter Roeck
2013-01-14 1:45 ` Chen Gang F T
2013-01-13 20:54 ` Cong Ding
2013-01-14 1:18 ` Chen Gang F T
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=alpine.LFD.1.00.0801161454010.2806@woody.linux-foundation.org \
--to=torvalds@linux-foundation.org \
--cc=clameter@sgi.com \
--cc=hannes@saeurebad.de \
--cc=linux-kernel@vger.kernel.org \
--cc=penberg@cs.helsinki.fi \
/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
all inboxes | Powered by JetHome®